对话框非客户区完善自绘,供大家交流学习
对话框非客户区完美自绘,供大家交流学习
前段时间,hurryboylqs发布了自己写的非客户区自绘的例子(http://bbs.****.net/topics/390624967),效果不错。
但是无意之中发现有一个瑕疵,而且也在帖子里回复了,可是楼主没鸟我!
今天把我最近整理的关于对话框非客户区绘制的代码贴出来供大家参考学习一下,同时也稍微说一下绘制时应该注意的一些问题,如果有不对或是遗漏的地方,希望大家可以指正和补充,废话不多说,下载地址:
http://download.****.net/detail/jzycode/6484623
贴几张效果图:




如果大家觉得效果一般的话,可是参看代码,自己进行改进
我们先从ON_WM_NCHITTEST这个消息入手,其消息映射函数为OnNcHitTest(CPoint point),该消息的作用是:命中测试,即判断鼠标当前位于窗口的什么地方,比如:HTCAPTION(标题栏上),HTMINBUTTON(最小化按钮上)等等,并将测试的结果作为返回值,,在标题栏上的最小化、最大化和关闭“按钮”其实并非真正的按钮,而是我们绘制的位图,使其看起来好像是一个个按钮,于是乎,当我们产生一个WM_LBUTTONDOWN消息,如何知道是否按在了“按钮”呢,这些工作全靠OnNcHitTest函数的返回来进行判断,因此这个消息的处理对我们后续的工作起到至关重要的角色。
我们按照自己的想法,设定了最小化、最大化和关闭“按钮”的位置,程序中我设定它们的位置相对于窗口左上角(0, 0),所以在OnNcHitTest函数中,还需要将这些位置转换为相对于屏幕的坐标,具体的转换,参看BOOL PtInRect(CRect &rtWin, CRect &rtClientBtn, CPoint &pt)函数,
然后再说一下ON_WM_NCRBUTTONDOWN这个消息,其映射函数为OnNcRButtonDown(UINT nHitTest, CPoint point),这个消息将决定即将弹出的系统菜单,如果当前鼠标的位置位于最小化、最大化或是关闭“按钮”上,阻止即将弹出的系统菜单,这样就需要屏蔽掉HTCLOSE、HTMINBUTTON和HTMAXBUTTON情况,很多人看到人想到的是应该是处理ON_WM_NCRBUTTONUP消息,开始的时候我也是这样想的,可是实际上这是徒劳的,仍然会弹出系统菜单,没办法只有处理ON_WM_NCRBUTTONDOWN消息了,
一个对话框窗口有可能存在几种风格,可能只存在/不存在标题栏,也可能只存在关闭按钮,或是还包含一个最大化按钮,也可能还包含一个最小化按钮,程序中针对这一情况添加了处理函数,GetWindowStyle()用于获取当前窗口的风格,程序启动时在PreSubclassWindow()中调用一次,在OnNcPaint()处理中参考获取到的窗口风格进行绘制,同时,用户还可能在外部调用SetWindowLong()给窗口设置新的风格,针对这一情况,也添加了额外的消息处理:ON_WM_STYLECHANGED,WM_STYLECHANGED是当窗口风格发生改变时发送的消息,在该消息的处理函数中再次调用GetWindowStyle()函数获取到窗口新的风格。
最后说一下一个比较重要的问题,当我们做完上述的工作后,运行程序,会发现会出现默认的关闭/最小化/最大化按钮,这是我们不希望看到的,究其原因,是WM_NCUAHDRAWCAPTION和WM_NCUAHDRAWFRAME这两个该死的消息在作怪,我想把这两个消息详细的讲解一下,可是居然在msdn上没有找到这两个消息,还好,最后在一篇帖子上找到了这样一段话:
而我们大家所作的就是屏蔽掉这两个消息,不做任何的处理。
好了吧,实在不爱写了,大家感兴趣的,参考代码吧,欢迎和大家一起交流学习,如果有什么问题,回复在该帖子里就行!
------解决方案--------------------
支持分享!!!
------解决方案--------------------
居然还要两个积分......
------解决方案--------------------
你要积分反而赚积分的少,它是按下载量来算积分的,不是人家花多少积分你赚多少积分的
------解决方案--------------------
恩呢,好资源,为嘛链接下不到了。。
------解决方案--------------------
很多人积分很少的。直接零积分得了。下载的人还多
------解决方案--------------------
1个积分也可以啊,评价一下就回来了
------解决方案--------------------
资源的分也用到了"薄利多销"的策略.
你下载分多, 下载一次能赚的分多, 但是愿意下载的人就少.
如果载分小, 下载一次能赚的分少, 但是下载的人就多了.
------解决方案--------------------
你搜索的资源不存在,请返回下载频道首页
------解决方案--------------------
感谢分享~~
------解决方案--------------------
好人啊,谢谢
前段时间,hurryboylqs发布了自己写的非客户区自绘的例子(http://bbs.****.net/topics/390624967),效果不错。
但是无意之中发现有一个瑕疵,而且也在帖子里回复了,可是楼主没鸟我!
今天把我最近整理的关于对话框非客户区绘制的代码贴出来供大家参考学习一下,同时也稍微说一下绘制时应该注意的一些问题,如果有不对或是遗漏的地方,希望大家可以指正和补充,废话不多说,下载地址:
http://download.****.net/detail/jzycode/6484623
贴几张效果图:
如果大家觉得效果一般的话,可是参看代码,自己进行改进
我们先从ON_WM_NCHITTEST这个消息入手,其消息映射函数为OnNcHitTest(CPoint point),该消息的作用是:命中测试,即判断鼠标当前位于窗口的什么地方,比如:HTCAPTION(标题栏上),HTMINBUTTON(最小化按钮上)等等,并将测试的结果作为返回值,,在标题栏上的最小化、最大化和关闭“按钮”其实并非真正的按钮,而是我们绘制的位图,使其看起来好像是一个个按钮,于是乎,当我们产生一个WM_LBUTTONDOWN消息,如何知道是否按在了“按钮”呢,这些工作全靠OnNcHitTest函数的返回来进行判断,因此这个消息的处理对我们后续的工作起到至关重要的角色。
我们按照自己的想法,设定了最小化、最大化和关闭“按钮”的位置,程序中我设定它们的位置相对于窗口左上角(0, 0),所以在OnNcHitTest函数中,还需要将这些位置转换为相对于屏幕的坐标,具体的转换,参看BOOL PtInRect(CRect &rtWin, CRect &rtClientBtn, CPoint &pt)函数,
HRESULT CDrawDlg::OnNcHitTest(CPoint point)
{
CRect rtWin;
GetWindowRect(&rtWin);
if(PtInRect(rtWin, m_rtCloseBox, point))
{
return HTCLOSE;
}
if(PtInRect(rtWin, m_rtMaxBox, point))
{
return HTMAXBUTTON;
}
if(PtInRect(rtWin, m_rtMinBox, point))
{
return HTMINBUTTON;
}
return CDialog::OnNcHitTest(point);
}
然后再说一下ON_WM_NCRBUTTONDOWN这个消息,其映射函数为OnNcRButtonDown(UINT nHitTest, CPoint point),这个消息将决定即将弹出的系统菜单,如果当前鼠标的位置位于最小化、最大化或是关闭“按钮”上,阻止即将弹出的系统菜单,这样就需要屏蔽掉HTCLOSE、HTMINBUTTON和HTMAXBUTTON情况,很多人看到人想到的是应该是处理ON_WM_NCRBUTTONUP消息,开始的时候我也是这样想的,可是实际上这是徒劳的,仍然会弹出系统菜单,没办法只有处理ON_WM_NCRBUTTONDOWN消息了,
void CDrawDlg::OnNcRButtonDown(UINT nHitTest, CPoint point)
{
if(HTCLOSE == nHitTest || HTMAXBUTTON == nHitTest || HTMINBUTTON == nHitTest)
{
return;
}
CDialog::OnNcRButtonDown(nHitTest, point);
}
一个对话框窗口有可能存在几种风格,可能只存在/不存在标题栏,也可能只存在关闭按钮,或是还包含一个最大化按钮,也可能还包含一个最小化按钮,程序中针对这一情况添加了处理函数,GetWindowStyle()用于获取当前窗口的风格,程序启动时在PreSubclassWindow()中调用一次,在OnNcPaint()处理中参考获取到的窗口风格进行绘制,同时,用户还可能在外部调用SetWindowLong()给窗口设置新的风格,针对这一情况,也添加了额外的消息处理:ON_WM_STYLECHANGED,WM_STYLECHANGED是当窗口风格发生改变时发送的消息,在该消息的处理函数中再次调用GetWindowStyle()函数获取到窗口新的风格。
最后说一下一个比较重要的问题,当我们做完上述的工作后,运行程序,会发现会出现默认的关闭/最小化/最大化按钮,这是我们不希望看到的,究其原因,是WM_NCUAHDRAWCAPTION和WM_NCUAHDRAWFRAME这两个该死的消息在作怪,我想把这两个消息详细的讲解一下,可是居然在msdn上没有找到这两个消息,还好,最后在一篇帖子上找到了这样一段话:
而我们大家所作的就是屏蔽掉这两个消息,不做任何的处理。
好了吧,实在不爱写了,大家感兴趣的,参考代码吧,欢迎和大家一起交流学习,如果有什么问题,回复在该帖子里就行!
------解决方案--------------------
支持分享!!!
------解决方案--------------------
居然还要两个积分......
------解决方案--------------------
你要积分反而赚积分的少,它是按下载量来算积分的,不是人家花多少积分你赚多少积分的
------解决方案--------------------
恩呢,好资源,为嘛链接下不到了。。
------解决方案--------------------
因为楼上的大哥觉得两个下载积分有点多,所以改为了一个下载积分,这是新的地址连接:
http://download.****.net/detail/jzycode/6485517
很多人积分很少的。直接零积分得了。下载的人还多
------解决方案--------------------
恩呢,好资源,为嘛链接下不到了。。
使用新的连接地址进行下载
------解决方案--------------------
资源的分也用到了"薄利多销"的策略.
你下载分多, 下载一次能赚的分多, 但是愿意下载的人就少.
如果载分小, 下载一次能赚的分少, 但是下载的人就多了.
------解决方案--------------------
你搜索的资源不存在,请返回下载频道首页
------解决方案--------------------
感谢分享~~
------解决方案--------------------
好人啊,谢谢