I'm trying to draw a custom title bar, and I've read that in order to paint outside a window's client area, I need to override WndProc and handle the WM_NCPAINT message. Currently, I'm doing that like this:
//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;
}
}
Which works, because I can put a breakpoint in and it gets hit. If I remove the call to the original, the window's frame isn't drawn. DrawTitleBar
looks like this:
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);
}
I first get the DC from the window handle. Then I get the Graphics
object by using Graphics::FromHdc
. I release the DC with ReleaseDC
. Incase there's an issue here, this is how I import the native Win32 functions:
[DllImport("user32.dll")]
extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
Also: I've tried a bunch of different methods, all with the same results. I can find a bunch of C# and VB examples on the web, but no C++ examples. I've also read about Windows Vista compatibility being an issue with this sort of thing. Currently, I don't care about that, as I will add it later.