仿酷狗音乐播放器开发日志二十六 duilib在标题栏弹出菜单的方法
转载请说明原出处,谢谢~~
上篇日志说明了怎么让自定义控件响应右键消息。之后我给主窗体的标题栏增加右键响应,观察原酷狗后可以发现,在整个标题栏都是可以响应右键并弹出菜单的。应该的效果如下:
本以为像上一片博客那样,处理标题栏的布局的右键消息就可以了。后来发现在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在标题栏弹出菜单的方法的更多相关文章
- 仿酷狗音乐播放器开发日志二十五 duilib右键事件的不足的bug修复
转载请说明原出处,谢谢~~ 虽然仿酷狗的各个菜单早就写好了,但是一直没有附加到程序里.今天把菜单和播放列表控件关联时发现了问题. 和播放列表相关的菜单有三个,分别是每个音乐项目控件相关的菜单.分组的菜 ...
- 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)
转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...
- 仿酷狗音乐播放器开发日志二十七 用ole为窗体增加文件拖动功能(附源码)
转载请说明原出处,谢谢~~ 中秋到了,出去玩了几天.今天把仿酷狗程序做了收尾,已经开发完成了,下一篇博客把完结的情况说一下.在这篇博客里说一下使用OLE为窗体增加文件拖拽的功能.使用播放器,我更喜欢直 ...
- 仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)
转载请说明原出处,谢谢~~ 整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果 ...
- 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)
转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...
- 仿酷狗音乐播放器开发日志十一——CTreeNodeUI的bug修复
由于做播放列表控件,我的CMusicLength控件继承了CTreeVieWUI控件,在向分组控件中添加播放项目时,发现代码无法正常工作,调用CTreeNodeUI控件的Add方法后无反应,导致我的播 ...
- 仿酷狗音乐播放器开发日志三——修复CEditUI的bug2
无意中发现了CEditUI控件的另一个bug,当我给播放器的搜索栏获取焦点时,这时再改变窗体大小,原本搜索栏应该对应着也改变大小,却发现CEditUI内嵌的edit控件没有跟着改变(如下图),跟着调试 ...
- Redrain仿酷狗音乐播放器开发完毕,发布测试程序
转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...
- 项目源码--Android类似酷狗音乐播放器
下载源码 知识技能概要: 1.音乐文件的扫描与管理 2.音频流的解码 3. UI控件的综合使用 4.播放列表方式管理 5.随机播放方式 6.源码带详细的中文注释 ...... 详细介绍 1. 音乐文件 ...
随机推荐
- [topcoder]BoxesDiv2
https://community.topcoder.com/stat?c=problem_statement&pm=13192 #include <vector> #includ ...
- 自旋锁spin_lock和raw_spin_lock
自旋锁spin_lock和raw_spin_lock Linux内核spin_lock.spin_lock_irq 和 spin_lock_irqsave 分析 http://blog.csdn.ne ...
- Java API —— Random类
1.Random类概述 此类用于产生随机数 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列. 2.构造 ...
- apache缓存
http://www.t086.com/article/4256 http://www.360doc.com/content/09/0928/13/41237_6551659.shtml
- HDU4389:X mod f(x)(数位DP)
Problem Description Here is a function f(x): int f ( int x ) { if ( x == 0 ) return 0; return f ( x ...
- gcc编译代码报错及编译方式
一.error: 'for' loop initial declarations are only allowed in C99 mode 前段时间写了一个小C程序,放在linux下用gcc编译出错, ...
- hdu 1885 Key Task (三维bfs)
题目 之前比赛的一个题, 当时是崔老师做的,今天我自己做了一下.... 还要注意用bfs的时候 有时候并不是最先到达的就是答案,比如HDU 3442 这道题是要求最小的消耗血量伤害,但是并不是最先到 ...
- UVa 11889 (GCD) Benefit
好吧,被大白书上的入门题给卡了.=_=|| 已知LCM(A, B) = C,已知A和C,求最小的B 一开始我想当然地以为B = C / A,后来发现这时候的B不一定满足gcd(A, B) = 1 A要 ...
- UVa 524 Prime Ring Problem【回溯】
题意:给出n,把从1到n排成一个环,输出相邻两个数的和为素数的序列 照着紫书敲的, 大概就是这个地方需要注意下,初始化的时候a[0]=1,然后dfs(1),从第1个位置开始搜 #include< ...
- android TextView多行文本(超过3行)使用ellipsize属性无效问题的解决方法
这篇文章介绍了android TextView多行文本(超过3行)使用ellipsize属性无效问题的解决方法,有需要的朋友可以参考一下 布局文件中的TextView属性 复制代码代码如下: < ...