自己继承的CMiniDockFrame,现在想在标题栏上添加自己的按钮,以实现自动伸缩bar的功能。我映射了WM_NCPAINT和WM_NCACITIVE消息,但是出现几个奇怪的现象,大家给点意见:1.在OnNcPaint里和OnNcActive里注释掉对父类的调用后,整个CMiniDockFrame确实没有重绘(这是应该的)2.注释调OnNcPaint,让它成为一个空函数,但是不修改OnNcActive,运行程序后,caption bar和四边框都没有重绘,这本该是正常的,但奇怪的是,当单击一次caption bar之后,caption bar就能正确重绘了。OnNcActive仅仅是发送一个WM_NCPAINT消息通知重绘NC而已,既然我已经注释掉了OnNcPaint里所有的代码,实在想不通为什么四个边框都没有被重绘,单单caption bar可以画出来。3.在OnNcPaint里设断点,F5运行后居然无法进入该函数。

解决方案 »

  1.   

    不明白的地方有三:
    其一,既然NcPaint是绘制NC,那么为什么注释掉该函数后,四个边框不能重绘,单单caption bar依然可以正确绘制,这是谁在绘制?
    其二,为什么在NcPaint中下断点,无法跟进?如果该函数根本没有被调用,那么注释掉它就应该是可以的,为何注释掉之后,四个边框又不能正确绘制了?
    其三,MiniFrame右上角的关闭按钮,到底是谁在绘制?
      

  2.   

    "在标题栏上添加自己的按钮"?这句是什么意思啊?
    注释掉OnNcPaint的动作之前,你已经在OnNcPaint里和OnNcActive里注释掉对父类的调用吗?
    你的主框架窗体创建时的参数如何?这里面有文章.注意窗口类是存在于C++类之外的类.窗口类的作用就像一个模板,可以由此创建其他窗口,并可共享某些特征,包括"类风格".选择不同的.有否关闭按钮,是可以由"类风格"决定的--按程序员的理解,实际就是那一堆参数!关闭按钮的绘制,自然是框架窗体的任务.
      

  3.   

    MFC的CMiniFrameWnd类在OnNcActive里头并没有调用父类的消息处理函数,它仅仅是发送了一次WM_NCPAINT消息。这是它的源代码:
    BOOL CMiniFrameWnd::OnNcActivate(BOOL bActive)
    {
    if((GetStyle() & MFS_SYNCACTIVE) == 0)
    {
    if (afxData.bSmCaption)
    return Default(); if (m_bActive != bActive) //×&acute;&Igrave;&not;&cedil;&Auml;±&auml;(&frac14;¤&raquo;&icirc;<=>&Icirc;&acute;&frac14;¤&raquo;&icirc;),&Iacute;¨&Ouml;&ordf;&Ouml;&Oslash;&raquo;&aelig;·&Ccedil;&iquest;&Iacute;&raquo;§&Ccedil;&oslash;
    {
    m_bActive = bActive;
    SendMessage(WM_NCPAINT);
    }
    }
    else if(m_nFlags & WF_KEEPMINIACTIVE)
    {
    return FALSE;
    }
    return TRUE;
    }
      

  4.   

    跟踪了一下,发现令我不解的是,原来OnNcPaint每次都调用Default(),而不往下进行画的动作,原因是afxData.bSmCaption为TRUE,MFC的解释是:afxData.bSmCaption:TRUE if WS_EX_SMCAPTION is supported。查了半天也没有关于这个风格的解释,不知道这是什么风格?
      

  5.   

    事实上,你只要保证窗体有WS_EX_PALETTEWINDOW风格就行了,因为WS_EX_PALETTEWINDOW实际上就是WS_EX_WINDOWEDGE, WS_EX_SMCAPTION, WS_EX_TOPMOST 这三种风格的组合.
      

  6.   

    我这边是这样定义的:
    #define WS_EX_PALETTEWINDOW    (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_TOPMOST)我把NcPaint里头画的动作全部注释掉,居然还能画:
    void CResizableMiniDockFrameWnd::OnNcPaint()
    {
    if(afxData.bSmCaption) //TRUE if WS_EX_SMCAPTION is supported
    {
    Default();
    return;
    }
    }
    没有一点异常。也就是说,MFC自己的源码里面,下面的那一大串绘画动作,都是无效的。
    现在我根本找不到这个关闭按钮是在哪个函数里头画的。
      

  7.   

    唔……找到症结了,MFC在Default里头包办了NcPaint的动作,给处的绘制代码都是骗人的……
      

  8.   

    应该说底下的那一堆绘画的动作是针对win3.1的,画出来都是平面的……
      

  9.   

    应该说底下的那一堆绘画的动作是针对win3.1的,画出来都是平面的……
      

  10.   

    关注
    ------------------------------------
    体验速度,体验CSDN新版论坛助手:http://community.csdn.net/Expert/TopicView.asp?id=3108679
      

  11.   

    下面是我自己的理解,不代表是正确的!
    caption被重画,一种可能是在WM_NCPAINT里做这个动作,另一种便是WM_NCLBUTTONDOWN里Windows自己直接绘制,意思是
    case WM_NCLBUTTONDOWN:
       // draw caption
    为什么要这样而不是统一由WM_NCPAINT来画呢,我猜想可能是考虑到实时性,比如有时窗口处于后台,这时用户直接点击caption,此时windows直接绘制的效果就是给用户的感觉没有延迟,否则点一下过一会才由灰色变成蓝色,会影响些视觉效果
    当然不止是caption是这样,combobox也是这样,比如hook了它的windowproc,自己处理WM_PAINT,发送CB_SETCURSEL,此时会发现没有调用WM_PAINT,因为combobox是直接在CB_SETCURSEL消息里绘制文本,即体现一种效率
      

  12.   

    “四个边框不能重绘”是因为WM_LBUTTONDOWN里不能处理太多,否则也会影响速度,因为视觉效果最直接的就是caption,所以是直接画,其他不重要的四个边框倒是统一由WM_NCPAINT来画的!