2012-08-07 81 views
0

我想繪製一個自定義標題欄,我已經讀過,爲了在窗口的客戶區域之外繪畫,我需要重寫WndProc並處理WM_NCPAINT消息。目前,我正在做的是這樣的:如何在C++。NET中繪製窗口的標題欄?

//WndProc override 
virtual void WndProc(Message% m) override 
{ 
    switch(m.Msg) 
    { 
     case 0x85: //WM_NCPAINT 
     case 0x0A: //WM_PAINT 
      //Call original 
      System::Windows::Forms::Form::WndProc(m); 

      //Now we'll do our painting 
      DrawTitleBar(m.HWnd); 

      break; 
     default: 
      System::Windows::Forms::Form::WndProc(m); 
      break; 
    } 
} 

其中一期工程,因爲我可以把一個斷點,它被擊中。如果我刪除對原稿的調用,則不會繪製窗口的框架。 DrawTitleBar看起來像這樣:

void DrawTitleBar(IntPtr hWnd) 
{ 
    IntPtr hDC; 
    Graphics^ g; 

    //Get the device context (DC) 
    hDC = GetWindowDC(hWnd); 
    //Get the graphics 
    g = Graphics::FromHdc(hDC); 

    //Draw 
    g->FillRectangle(Brushes::Blue, 0, 0, 100, 10); 

    //Cleanup 
    g->Flush(); 
    ReleaseDC(hWnd, hDC); 
} 

我首先從窗口句柄中獲取DC。然後我使用Graphics::FromHdc得到Graphics對象。我用ReleaseDC發佈DC。櫃面這裏有一個問題,我這是怎麼導入原生Win32函數:

[DllImport("user32.dll")] 
extern IntPtr GetWindowDC(IntPtr hWnd); 
[DllImport("user32.dll")] 
extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 

另外:我已經嘗試了一堆不同的方法,都具有相同的結果。我可以在網上找到一堆C#和VB示例,但沒有C++示例。我也讀過Windows Vista的兼容性問題。目前,我不在乎這一點,因爲我稍後會添加它。

+1

需要GetDCEx()或GetWindowDC()來獲取整個窗口的繪製上下文,而不僅僅是FromHwnd返回的客戶區。然後Graphics :: FromHdc()。視覺樣式阻止它正常工作,只考慮自定義僞造標題欄的無邊框窗口。 – 2012-08-07 02:58:55

+0

@HansPassant好吧,我已經改變了我的DrawTitleBar方法來使用'GetWindowDC'。但是,我仍然沒有畫任何東西。我如何禁用視覺樣式?我必須在我的'main'方法中去除對'Application :: EnableVisualStyles'的調用嗎?這樣做不會產生任何明顯的結果。此外,對於無邊界窗口,我只是將FormBorderStyle屬性設置爲None? – smoth190 2012-08-07 03:08:29

+0

與您遇到的問題無關,但如果您願意,可以通過#include 獲得GetWindowDC和ReleaseDC函數。如果你最終使用了很多Win32方法,那可能比爲它們編寫一個DllImport容易。 – 2012-08-08 17:09:08

回答

0

兩個簡單的事實。 1. DWM下的GetWindowDC基本上被打破了。 2.部分存在兩種解決方法A.將兼容性模式設置爲xp或98或95. B.存在msdn社交中的程序示例。搜索 「GetWindowDC破碎」,然後按照冗長的網址代碼 示例[通過添加尾隨修復破損的網址]]。 不幸的是,窗口顯示與 圓角我的盒子構建9200,贏得8.0,沒有更新。