我想繪製一個自定義標題欄,我已經讀過,爲了在窗口的客戶區域之外繪畫,我需要重寫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的兼容性問題。目前,我不在乎這一點,因爲我稍後會添加它。
需要GetDCEx()或GetWindowDC()來獲取整個窗口的繪製上下文,而不僅僅是FromHwnd返回的客戶區。然後Graphics :: FromHdc()。視覺樣式阻止它正常工作,只考慮自定義僞造標題欄的無邊框窗口。 – 2012-08-07 02:58:55
@HansPassant好吧,我已經改變了我的DrawTitleBar方法來使用'GetWindowDC'。但是,我仍然沒有畫任何東西。我如何禁用視覺樣式?我必須在我的'main'方法中去除對'Application :: EnableVisualStyles'的調用嗎?這樣做不會產生任何明顯的結果。此外,對於無邊界窗口,我只是將FormBorderStyle屬性設置爲None? – smoth190 2012-08-07 03:08:29
與您遇到的問題無關,但如果您願意,可以通過#include獲得GetWindowDC和ReleaseDC函數。如果你最終使用了很多Win32方法,那可能比爲它們編寫一個DllImport容易。 –
2012-08-08 17:09:08