I download your RadControls for WinForms Q3 2008 SP2. I notice that the RadForm (FirstLook) wasn't actually not drawing the non-client area of the form until I size the form . So I did a little research by examing your library with Red Gate's .NET Reflector and I notice that in your PaintNC(wm_ncpaint) method that you was going about it the wrong way. MSDN states that ....
The DefWindowProc function paints the window frame.
An application can intercept the WM_NCPAINT message and paint its own custom window frame. The clipping region for a window is always rectangular, even if the shape of the frame is altered.
The wParam value can be passed to GetDCEx as in the following example.
case WM_NCPAINT:
{
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
// Paint into this DC
ReleaseDC(hwnd, hdc);
}
First off ---- The update region is clipped to the window frame. When wParam is 1, the entire window frame
needs to be updated. How you got it is the same as MSDN states it. This is for use when the wParam not
equal 1. If the wParam equals 1 the entire window frame needs to be updated. So you don't need
DCX_INTERSECTRGN when it equals 1. So the piece of code thats on this page was used for in a project of
mines. So I want to share somthing that I had problems with and I see that your team got now. Here is a
piece of code to go about it (example)...All of this is done on a subclass of a System.Windows.Forms.Form.
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case (int)WindowMessages.WM_NCPAINT: //0x85
WmNCPaint(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
private void WmNCPaint(ref Message msg)
{
RECT windowRect = new RECT();
if (GetWindowRect(msg.HWnd, ref windowRect) == false)
return;
Rectangle bounds = new Rectangle(0, 0,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top);
if (bounds.Width == 0 || bounds.Height == 0)
return;
// retrieves the device context (DC) for the entire window,
// including title bar, menus, and scroll bars
IntPtr hDC = GetDC(msg);
if (hDC == IntPtr.Zero)
return;
// assign clip region to exclude client area
Rectangle clientRect = ExcludePadding(bounds, this.ClientAreaOffSet);
ExcludeClipRect(hDC, clientRect.Left, clientRect.Top, clientRect.Right, clientRect.Bottom);
try
{
// Double-buffering technique the old way
IntPtr CompatiblehDC = CreateCompatibleDC(hDC);
IntPtr CompatibleBitmap = CreateCompatibleBitmap(hDC, bounds.Width, bounds.Height);
try
{
SelectObject(CompatiblehDC, CompatibleBitmap);
using (Graphics g = Graphics.FromHdc(CompatiblehDC))
{
// Do your drawing here.
}
// copy current bitmap to screen, blast bits to screen
BitBlt(hDC, 0, 0, bounds.Width, bounds.Height, CompatiblehDC, 0, 0, 0x00CC0020/*SRCCOPY*/);
//goto Label_0178;
}
finally
{
DeleteObject(CompatibleBitmap);
DeleteDC(CompatiblehDC);
}
}
finally
{
//DeleteObject(hrgnClip);
ReleaseDC(msg.HWnd, hDC);
}
//Label_0178:
// we handled everything MSDN states that an application returns zero if it processes
// this message.
msg.Result = ((IntPtr)0);
}
public static IntPtr GetDC(Message msg)
{
if (msg.Msg != (int)WindowMessages.WM_NCPAINT)
{
return GetWindowDC(msg.HWnd);
}
int flags = (int)(DCX.DCX_CACHE | DCX.DCX_CLIPSIBLINGS
| DCX.DCX_WINDOW );
IntPtr zero = IntPtr.Zero;
if (msg.WParam.ToInt32() != 1)
{
flags |= (int)DCX.DCX_INTERSECTRGN;//0x80;
zero = msg.WParam;
}
// check out http://www.codeproject.com/KB/GDI/updatergn.aspx on GetDCEx
// the best I seen so far on this
return GetDCEx(msg.HWnd, zero, flags);
}
Still need to elaborate a lit bit more just post.