问题是这样的:当我在标题上点下左键时(也就是要移动窗口时),
    窗口上的最小化,最大化,关闭按扭就显示出来了,除了这三个按扭显示有误之外(按理说应该不显示出来的,因为被屏蔽显示了)
     其它区域都正常,且只有在我要移动窗口时才会显示出来那三个按扭,隔一会就消失了,被红色遮住了又正常了,     问题就是为什么我按下鼠标左键的时候,它会显示出来,虽然我用了DefWindowProc处理 WM_NCLBUTTONDOWN,但时我后面又
     调用了重绘函数,就算是DefWindowProc把那三个按扭画出来了,也应该被我的重绘函数给遮住才对啊     如果不响应WM_NCLBUTTONDOWN,窗口又不能被移动了,真是郁闷;    我的目的就是重绘标题栏,但是不破坏原有的窗口任何东西(所以就不要给我说,把最大化最小化这些按扭删除了等等
    那样是避开问题,不是真的解决问题。LRESULT CALLBACK GameMain::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing,
                          void* pUserContext )
{ GameMain* pGM = GMain; switch( uMsg )
{
                        //挡截所有画非客户区消息
case WM_NCPAINT:
case WM_NCACTIVATE:
case WM_NCMOUSEMOVE:
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCRBUTTONUP:
case WM_NCLBUTTONUP:
case WM_INITMENU:
{
if( uMsg == WM_NCLBUTTONDOWN )//为了可以让窗口可移动,就让默认回调函数处理
{
::DefWindowProc( hWnd, uMsg, wParam, lParam ); } pGM->OnNCPaint( hWnd );//重绘非客户区函数
*pbNoFurtherProcessing = true; //这值为直,就不会调用默认的DefWindowProc
return 0;
}
break;
default:
break;
}
 return 0;//返回 交给默认的defwindowproc处理
}//重绘函数,这里就是把所有非客户区画成红色的void GameMain::OnNCPaint( HWND hWnd )
{
if( !hWnd || !IsWindow(hWnd) || !IsWindowVisible(hWnd)){ return; }
HDC dc = GetWindowDC(hWnd);
HBRUSH hbr = ::CreateSolidBrush( RGB(0xff,0,0) );
RECT rect;
::GetWindowRect( hWnd, &rect );
rect.top    = GetSystemMetrics( SM_CYFRAME );
rect.left    = GetSystemMetrics( SM_CXFRAME );
rect.right   = rect.right - (rect.left +GetSystemMetrics( SM_CYFRAME ));
rect.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION); FillRect( dc, &rect, hbr );


HDC hdc; hdc = GetWindowDC(hWnd); // Paint into this DC 
RECT rcWin;
GetWindowRect(hWnd, &rcWin);

OffsetRect( &rcWin, -rcWin.left, -rcWin.top );
for(int i=0; i<4; i++) 

FrameRect(hdc, &rcWin, hbr); 
InflateRect(&rcWin, -1, -1); 
}
ReleaseDC(hWnd, hdc); DeleteObject(hbr);
ReleaseDC( hWnd, dc );
}

解决方案 »

  1.   

    我现在也在做自绘captionbar,我觉得可以这样用下面代码,去掉captionbar,然后响应WM_NCCALCSIZE消息,设置NC尺寸。
    // Hide the captionbar
    long style = GetWindowLong(hWnd,GWL_STYLE);   
    style &= ~(WS_CAPTION);   
    ::SetWindowLong(hWndGWL_STYLE, style);
    或者你处理WM_NCLBUTTONDOWN时,发送 ::SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE|HTCAPTION, 0);试试看
      

  2.   


    //本来我也测试到了 SendMessage( hWnd, WM_SYSCOMMAND, SC_MOVE , lParam ); 
    //但是结果鼠标自动跑到了标题栏的最中间,没有加 HTCAPTION ,呵呵 人才,一语惊人啊
    ::SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE|HTCAPTION, 0);
      

  3.   

    LRESULT CcsdndialogDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
    LRESULT   lResult   =     CDialog::DefWindowProc(message,   wParam,   lParam);   
        
      if((message   ==   WM_MOVE)   ||   (message   ==   WM_NCACTIVATE)   ||   (message   ==   WM_PAINT)   ||(message   ==   WM_NCPAINT))   
      {   
          这里添加代码
        
        
      }   
    return   lResult;   }
      

  4.   

    这个问题是很多自绘标题栏时遇到的问题,基本上都没有一个很完美的解决方案,我就是说说我的方案吧:1.如果要彻底解决掉这个问题就是HOOK Windows的一个内部函数xxxDrawCaptionBar (Win32k.sys),这个函数是未导出的,在不同版本的操作系统地址是有变化的.基本上还是有难度的.2.如果在XP环境下可以屏蔽以下两个消息:
    // 未公布的消息
    #define WM_NCUAHDRAWCAPTION 0x00AE
    #define WM_NCUAHDRAWFRAME 0x00AF在WM_NCACTIVE,WM_NCLBUTTONDOWN消息中使用LookWindowUpdate,调用DefWindowProc后LookWindowUpdate(NULL)解锁3.干脆去掉标题栏
      

  5.   

    参考VS2008的MFC窗口风格支持源码吧.其实做法很简单,去掉窗口的标题栏,可以保留边框用来调整大小位置,重新调整标题栏区大小并计算出客户区,响应WM_NCPAINT消息并使用CWindowDC来绘制.一要要记住,把标题栏(WS_CAPTION)去掉(或在样式中就不设置此值),否则就会出现那个讨厌的"系统按钮"了.
      

  6.   

    这个貌似不好解决。Default()中会把那三个按钮给绘制出来。
    解决办法只有去掉这三个按钮,然后用CDC::DrawFrameControl去绘制自己的按钮,CDC提供的这个函数可以很方便地把按钮绘出来。