Non-Client Drawing (WM_NCPAINT) Problem

dpcpro

New member
Joined
Dec 9, 2004
Messages
2
I am inheriting from a textbox and creating some extra non-client space (using WM_NCCALCSIZE) on the right side. During WM_NCPAINT, I am drawing a button in the extra non-client space.

Everything works fine, until I change the forms opacity to anything other than 100%. This is causing the extra non-client space to be come invalid or undrawable. If I run the form with opacity being 100%, the control I am designing looks fine, however if I change the opacity to less than 100%, my button area becomes black. Even if (while the form is still running), I change the opacity back to 100%, my button area always remains black.

What is happening to the non-client space that I allocated after the forms opacity is changed? Is there something that I am missing or leaving out?

Here is the code for WM_NCPAINT & WM_NCCALCSIZE:

Code:
------------------------------------------------ 

WM_NCPAINT Processing 

Let the base class do its thing. 
MyBase.WndProc(m) 

Grab a pointer to the control windows device context. 
Dim hdc As IntPtr = NativeMethods.GetWindowDC(m.HWnd) 
Dim hdc As IntPtr = NativeMethods.GetDCEx(m.HWnd, m.WParam, 1 Or &H20 Or &H10000) 

Create a graphics object from the windows device context. 
Dim g As Graphics = Graphics.FromHdc(hdc) 

Create the display and bounds rectangles for the button. 
Me.btnNC.DisplayRectangle = New Rectangle(Me.Bounds.Width - (Me.BUTTON_WIDTH + 2), Me.BUTTON_START_Y, Me.BUTTON_WIDTH, Me.Bounds.Height - (Me.BUTTON_START_Y * 2)) 
Me.btnNC.Bounds = New Rectangle(Me.Bounds.X + (Me.Bounds.Width - (Me.BUTTON_WIDTH + 2)), Me.Bounds.Y + Me.BUTTON_START_Y, Me.BUTTON_WIDTH, Me.Bounds.Height - (Me.BUTTON_START_Y * 2)) 

Draw a normal button. 
ControlPaint.DrawButton(g, Me.btnNC.DisplayRectangle, ButtonState.Normal) 

Dispose the graphics object. 
g.Dispose() 

Release the windows device context. 
NativeMethods.ReleaseDC(m.HWnd, hdc) 

Return 

------------------------------------------------ 

WM_NCCALCSIZE Processing 

Let the base class do its thing. 
MyBase.WndProc(m) 

Make some space in the non-client area to draw the button. 
If m.WParam.ToInt32 = 1 Then 

[INDENT]Dim p As NCCALCSIZE_PARAMS = Marshal.PtrToStructure(m.LParam, GetType(NCCALCSIZE_PARAMS)) 
p.rgrc0.right -= (Me.BUTTON_WIDTH - 1) 
Marshal.StructureToPtr(p, m.LParam, True) [/INDENT] 

Else 

[INDENT]Dim rect As RECT = Marshal.PtrToStructure(m.LParam, GetType(RECT)) 
rect.Right -= (Me.BUTTON_WIDTH - 1) 
Marshal.StructureToPtr(rect, m.LParam, True) [/INDENT] 

End If 

Return

Any help would greatly be appreciated. Thanks...

dpcpro
 
After further testing, I realized that the graphics object that I am creating from the Windows DC has clipped the extra non-client space out of its drawing area when the opacity is anything less than 100% on the form.

I tried drawing in this area using standard GDI APIs and it works. So how can I regain access to this already clipped portion of the graphics object?

I have tried resetting the clip or even resetting the region that the graphics object is using but none have worked.

Any help would be appreciated. Thanks.

dpcpro
 
Back
Top