转载请说明原出处,谢谢~~

上篇日志说明了怎么让自定义控件响应右键消息。之后我给主窗体的标题栏增加右键响应,观察原酷狗后可以发现,在整个标题栏都是可以响应右键并弹出菜单的。应该的效果如下:

本以为像上一片博客那样,处理标题栏的布局的右键消息就可以了。后来发现在duilib的标题栏中无法像在客户区那样自如响应UIEVENT_CONTEXTMENU消息的。所以还得用另外的方法。

在非客户区处理右击消息对应的是WM_NCRBUTTONUP,WM_NCRBUTTONUP是和WM_NCHITTEST相辅相成的。在WinImplBase.cpp文件中可以看到duilib处理WM_NCHITTEST的代码。在这里可以过滤指定的控件,被过滤的控件不会被duilib当作是非客户区的一部分,如果不过滤的话在标题栏的对应控件是无法响应用户的消息的,我为了适应仿酷狗程序,增加了被过滤的控件,源码如下:

LRESULT WindowImplBase::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
::ScreenToClient(*this, &pt); RECT rcClient;
::GetClientRect(*this, &rcClient); if( !::IsZoomed(*this) )
{
RECT rcSizeBox = m_PaintManager.GetSizeBox();
if( pt.y < rcClient.top + rcSizeBox.top )
{
if( pt.x < rcClient.left + rcSizeBox.left ) return HTTOPLEFT;
if( pt.x > rcClient.right - rcSizeBox.right ) return HTTOPRIGHT;
return HTTOP;
}
else if( pt.y > rcClient.bottom - rcSizeBox.bottom )
{
if( pt.x < rcClient.left + rcSizeBox.left ) return HTBOTTOMLEFT;
if( pt.x > rcClient.right - rcSizeBox.right ) return HTBOTTOMRIGHT;
return HTBOTTOM;
} if( pt.x < rcClient.left + rcSizeBox.left ) return HTLEFT;
if( pt.x > rcClient.right - rcSizeBox.right ) return HTRIGHT;
} RECT rcCaption = m_PaintManager.GetCaptionRect();
if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {
CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(pt));
if( pControl && _tcsicmp(pControl->GetClass(), _T("ButtonUI")) != 0 &&
_tcsicmp(pControl->GetClass(), _T("OptionUI")) != 0 &&
_tcsicmp(pControl->GetClass(), _T("TextUI")) != 0 &&
_tcsicmp(pControl->GetClass(), _T("SliderUI")) != 0 &&
_tcsicmp(pControl->GetClass(), _T("EditUI")) != 0)
return HTCAPTION;
} return HTCLIENT;
}

如果要在主窗体的标题栏里响应右击消息,应该让主窗体类继承WindowImplBase类,然后重写HandleMessage函数或者直接修改WindowImplBase类的HandleMessage函数。在函数里处理WM_NCRBUTTONUP消息,我选择的是第一个方法。当发现用户右击了标题栏,就让标题栏布局向主窗体发出menu消息,剩下的就是正常处理menu消息。代码如下:

LRESULT CFrameWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_NCRBUTTONUP )
{
POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); RECT rcClient;
::GetClientRect(*this, &rcClient); RECT rcCaption = m_PaintManager.GetCaptionRect();
if( pt.x >= rcClient.left && pt.x < rcClient.right && pt.y >= rcClient.top && pt.y < rcCaption.bottom )
m_PaintManager.SendNotify(m_pWndTitle, DUI_MSGTYPE_MENU, 0, 0);
} return __super::HandleMessage(uMsg, wParam, lParam);
}

原本我还在代码里过滤了控件,但是后来发现,在WM_NCHITTEST里面过滤了控件后就不用在WM_NCRBUTTONUP消息里另外过滤了!在WM_NCHITTEST里面过滤的控件,恰好在WM_NCRBUTTONUP消息就是不可以响应右键的,这正是我想要的。就这样可以模仿出酷狗的标题栏右键消息。

 
 Redrain  2014.8.27

仿酷狗音乐播放器开发日志二十六 duilib在标题栏弹出菜单的方法的更多相关文章

  1. 仿酷狗音乐播放器开发日志二十五 duilib右键事件的不足的bug修复

    转载请说明原出处,谢谢~~ 虽然仿酷狗的各个菜单早就写好了,但是一直没有附加到程序里.今天把菜单和播放列表控件关联时发现了问题. 和播放列表相关的菜单有三个,分别是每个音乐项目控件相关的菜单.分组的菜 ...

  2. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

  3. 仿酷狗音乐播放器开发日志二十七 用ole为窗体增加文件拖动功能(附源码)

    转载请说明原出处,谢谢~~ 中秋到了,出去玩了几天.今天把仿酷狗程序做了收尾,已经开发完成了,下一篇博客把完结的情况说一下.在这篇博客里说一下使用OLE为窗体增加文件拖拽的功能.使用播放器,我更喜欢直 ...

  4. 仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)

    转载请说明原出处,谢谢~~ 整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果 ...

  5. 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)

    转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...

  6. 仿酷狗音乐播放器开发日志十一——CTreeNodeUI的bug修复

    由于做播放列表控件,我的CMusicLength控件继承了CTreeVieWUI控件,在向分组控件中添加播放项目时,发现代码无法正常工作,调用CTreeNodeUI控件的Add方法后无反应,导致我的播 ...

  7. 仿酷狗音乐播放器开发日志三——修复CEditUI的bug2

    无意中发现了CEditUI控件的另一个bug,当我给播放器的搜索栏获取焦点时,这时再改变窗体大小,原本搜索栏应该对应着也改变大小,却发现CEditUI内嵌的edit控件没有跟着改变(如下图),跟着调试 ...

  8. Redrain仿酷狗音乐播放器开发完毕,发布测试程序

    转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...

  9. 项目源码--Android类似酷狗音乐播放器

    下载源码 知识技能概要: 1.音乐文件的扫描与管理 2.音频流的解码 3. UI控件的综合使用 4.播放列表方式管理 5.随机播放方式 6.源码带详细的中文注释 ...... 详细介绍 1. 音乐文件 ...

随机推荐

  1. C# Regex类用法

    使用Regex类需要引用命名空间:using System.Text.RegularExpressions; 利用Regex类实现全部匹配输出 string str = "test43232 ...

  2. 解决Eclipse10配置Pydev不成功的问题

    本人在线配置还在本地配置后 重启Eclipse,Windows-Preferences中并无Python选项,新建项目也无Python可选 这个尝试了好多种方法,重新安装Eclipse10,重新安装j ...

  3. windows下安装ubantu

        首先声明我是一个linux大菜鸟,之所以学这个,一个是好玩,另外做DL的一些软件如Caffe要在这个平台上运行,所以没事就鼓捣鼓捣.linux是一种内核,市场上支持这种内核的操作系统有uban ...

  4. Failed to allocate memory: 8

    Failed to allocate memory: 8This application has requested the Runtime to terminate it in an unusual ...

  5. 安卓开发44:解决 INSTALL_FAILED_UID_CHANGED 等问题

    apk无法卸载,一般可以下面的方法试一下: 1. 删除/data/app/(filename) 文件夹下的apk包 2. 删除/system/app/(filename) 文件夹下的apk包 3. 将 ...

  6. HTML常用标签及其全称

    <a href="#">a 超级链接(anchor)</a>     <abbr title="abbreviation的简写"& ...

  7. 设置UITableView section间距

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 0 ...

  8. LRU缓存算法

    http://blog.csdn.net/beiyeqingteng/article/details/7010411 http://blog.csdn.net/wzy_1988/article/det ...

  9. Android Studio上的几个插件

    转载:http://blog.csdn.net/maosidiaoxian/article/details/44992655 以下所有插件都可以在Idea的插件库中找到,如果你与我一样在Android ...

  10. 关于引用mshtml的问题

    今天看了个验证码识别的代码,其中引用到了mshtml.dll,找了半天原来就是microsoft.mshtml.dll.查这个dll的时候还发现了好几篇关于这个dll添加问题的文章.顺便看了下,原来这 ...