| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5753 人关注过本帖
标题:MFC对话框非客户区完美自绘
取消只看楼主 加入收藏
我菜119
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:938
专家分:1756
注 册:2009-10-17
结帖率:98.26%
收藏
已结贴  问题点数:100 回复次数:4 
MFC对话框非客户区完美自绘
声明:这篇帖子我在csdn上发表了,好久没来编程中国了,希望可以把更多的东西分享给大家,同时与大家交流学习!!!

下载地址:
http://download.

贴张效果图:
图片附件: 游客没有浏览图片的权限,请 登录注册


如果大家觉得效果一般的话,可是参看代码,自己进行改进

我们先从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上没有找到这两个消息,还好,最后在一篇帖子上找到了这样一段话:

原来是windows对绘制处理的一个操作(XP才增加的消息),猜测是一个只有微软内部才知道的BUG处理,其处理方式是通过向标题栏发送以下消息以解决余留问题,但我们重写后未曾予以适当的处理,故出现如题所述的现象


而我们大家所作的就是屏蔽掉这两个消息,不做任何的处理。


欢迎和大家一起交流学习,如果有什么问题,回复在该帖子里就行!
搜索更多相关主题的帖子: 下载地址 效果图 对话框 标题栏 
2013-11-01 16:16
我菜119
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:938
专家分:1756
注 册:2009-10-17
收藏
得分:0 
回复 14楼 蚕头燕尾
那就把C#好好学的吧

愿用余生致力编程
2013-11-03 00:36
我菜119
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:938
专家分:1756
注 册:2009-10-17
收藏
得分:0 
好东西支持的人...

愿用余生致力编程
2013-11-03 21:04
我菜119
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:938
专家分:1756
注 册:2009-10-17
收藏
得分:0 
回复 16楼 蚕头燕尾
没办法,人生就是这样!

愿用余生致力编程
2013-11-03 21:05
我菜119
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:938
专家分:1756
注 册:2009-10-17
收藏
得分:0 
回复 19楼 蚕头燕尾
我大学时学的是WIN SDK,学MFC时,直接就写代码,不懂的地方就去找百度,它很热情,什么都愿意告诉我!

[ 本帖最后由 我菜119 于 2013-11-3 22:19 编辑 ]

愿用余生致力编程
2013-11-03 22:18
快速回复:MFC对话框非客户区完美自绘
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020203 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved