重绘标题栏

在重绘标题栏时,一般只要重载WN_NCPAINT消息即可,但是这并不完美,因为在程序第一次启动时微软的系统按钮还是会闪一下,基本是重绘标题栏的软肋,通过spyXX查看发现有这么一个消息:
<00026> 0004097E S message: 0x00AE [未知] wParam:00001001 lParam:00000000
<00027> 0004097E R message: 0x00AE [未知] lResult:00000000
该消息没有在winuser.h中定义,ps:这就是微软的技术壁垒~~~
查看了一下chrome的源码,确实是这个消息在作怪。下面是chrome代码里的说明:
    // These two messages aren't defined in winuser.h, but they are sent to windows
    // with captions. They appear to paint the window caption and frame.
    // Unfortunately if you override the standard non-client rendering as we do
    // with CustomFrameWindow, sometimes Windows (not deterministically
    // reproducibly but definitely frequently) will send these messages to the
    // window and paint the standard caption/title over the top of the custom one.
    // So we need to handle these messages in CustomFrameWindow to prevent this
    // from happening.
    const int WM_NCUAHDRAWCAPTION = 0xAE;
    const int WM_NCUAHDRAWFRAME = 0xAF;
我英文不是很好,大致的意思就是要重绘标题栏要对这两个消息响应。在看看chrome里是怎么响应的:
    LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param,
        LPARAM l_param)
    {
        // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for
        // an explanation about why we need to handle this message.
        SetMsgHandled(!non_client_view_->UseNativeFrame());
        return 0;
    }
有效语句就一句, SetMsgHandled(!non_client_view_->UseNativeFrame());意思是就是不用原生标题栏时,设置该消息已响应,不再继续传给默认消息处理函数。

无图无真相:
不响应2个消息的效果:
重绘标题栏 - JCK - 做最好的自己
 
响应2个消息的效果:
重绘标题栏 - JCK - 做最好的自己
效果不错。 接下来就是画图的问题了,开始大航海吧~~

呵呵,鄙人表达能力欠缺,要是没看懂就Q我,450885099
 
在MFC中,我们可以通过对窗口的WM_NCPAINT、WM_PAINT、WM_ERASEBKGND等消息进行处理来实现重绘标题栏和菜单栏。 首先,我们需要在类的声明中添加自定义消息。例如: #define WM_CUSTOM_TITLEBAR_REDRAW WM_USER+1 //自定义消息,重绘标题栏 #define WM_CUSTOM_MENUBAR_REDRAW WM_USER+2 //自定义消息,重绘菜单栏 然后在窗口创建时,通过对NC_PAINT和WM_PAINT消息的处理来实现标题栏和菜单栏的重绘。例如: void CMyFrameWnd::OnNcPaint() { //获取窗口的DC CDC* pDC = GetWindowDC(); //重绘标题栏 SendMessage(WM_CUSTOM_TITLEBAR_REDRAW, (WPARAM)pDC->m_hDC); //重绘菜单栏 SendMessage(WM_CUSTOM_MENUBAR_REDRAW, (WPARAM)pDC->m_hDC); //释放DC ReleaseDC(pDC); } void CMyFrameWnd::OnPaint() { CPaintDC dc(this); //绘制标题栏 SendMessage(WM_CUSTOM_TITLEBAR_REDRAW, (WPARAM)dc.m_hDC); //绘制菜单栏 SendMessage(WM_CUSTOM_MENUBAR_REDRAW, (WPARAM)dc.m_hDC); } 接下来,我们需要在窗口的消息映射中添加对自定义消息的处理。例如: BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_MESSAGE(WM_CUSTOM_TITLEBAR_REDRAW, OnCustomTitlebarRedraw) //重绘标题栏 ON_MESSAGE(WM_CUSTOM_MENUBAR_REDRAW, OnCustomMenubarRedraw) //重绘菜单栏 END_MESSAGE_MAP() LRESULT CMyFrameWnd::OnCustomTitlebarRedraw(WPARAM wParam, LPARAM lParam) { HDC hDC = (HDC)wParam; //在hDC上重绘标题栏 ... return 0; } LRESULT CMyFrameWnd::OnCustomMenubarRedraw(WPARAM wParam, LPARAM lParam) { HDC hDC = (HDC)wParam; //在hDC上重绘菜单栏 ... return 0; } 通过以上步骤,我们就可以实现对MFC窗口标题栏和菜单栏的重绘。当然,具体的重绘方式和效果可以根据实际需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值