C++/VB - Resouce leak (WM_NCPAINT)

Asked By Robert
06-Jan-10 12:27 AM
I am trying to draw my own border on a usercontrol by subclassing the
WM_NCPAINT message. Everything works fine for a while but eventually
the window stops drawing properly (goes black / bits drawn in wrong
place) which I assume is due to a resource leak.

I think I have narrowed it down to the CreateRectRgn and CombineRgn
calls but I cannot work out why it is wrong. I assumed DefWindowProc
would clean up any regions it found in wParam.

Any suggestions would be greatly appreciated.

Regards
Robert

--- UserControl Code ----

Friend Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

Select Case uMsg
Case WM_NCPAINT
If (m_bThemeActive) Then
wParam = ThemeBorder(wParam)
End If

WndProc = DefWindowProc(hWnd, WM_NCPAINT, wParam, 0)

Case Else
WndProc = CallWindowProc(m_SubClass.wndprocNext, _
hWnd, uMsg, wParam, ByVal lParam)

End Select
End Function

Private Function ThemeBorder(ByVal hrgnUpdate As Long) As Long
Dim hdc As Long
Dim rc As RECT
Dim rcWindow As RECT
Dim hrgnClip As Long

hdc = GetWindowDC(hWnd)

GetWindowRect hWnd, rcWindow
GetClientRect hWnd, rc
ClientToScreenAny hWnd, rc.Left
ClientToScreenAny hWnd, rc.Right

rc.Right = rcWindow.Right - (rc.Left - rcWindow.Left)
rc.bottom = rcWindow.bottom - (rc.Top - rcWindow.Top)

hrgnClip = CreateRectRgn(rc.Left, rc.Top, rc.Right, rc.bottom)

If (hrgnUpdate <> 1) Then
CombineRgn hrgnClip, hrgnClip, hrgnUpdate, RGN_AND
End If

OffsetRect rc, -rcWindow.Left, -rcWindow.Top
ExcludeClipRect hdc, rc.Left, rc.Top, rc.Right, rc.bottom
OffsetRect rcWindow, -rcWindow.Left, -rcWindow.Top

DrawBorder hdc, rcWindow

ReleaseDC hWnd, hdc

ThemeBorder = hrgnClip
End Function
SubClass.wndprocNext
(1)
ClientToScreenAny
(1)
GetWindowDC
(1)
GDIView
(1)
ExcludeClipRect
(1)
CallWindowProc
(1)
GetWindowRect
(1)
GetClientRect
(1)
  Nobody replied to Robert
06-Jan-10 05:25 AM
You need to call DeleteObject(wParam) here if wParam <> 0 And m_bThemeActive
= True.
  Robert replied to Nobody
06-Jan-10 07:15 PM
Many thanks. That appears to have solved the problem.

It seems a strange thing to have to do, though. Does this mean that
Windows is only deleting the region it receives if it matches what it
sent?
  Nobody replied to Robert
06-Jan-10 07:20 PM
I do not see in WM_NCPAINT documentation that the region is automatically
deleted, just that DefWindowProc() would draw the window frame, so it is
necessary to use DeleteObject().
  Nobody replied to Robert
06-Jan-10 07:22 PM
See also this tool which shows how many GDI objects you are using:

GDIView v1.04 - View GDI handles/resources list and detect GDI leaks
http://www.nirsoft.net/utils/gdi_handles.html
Create New Account
help
any one can give me some document, thanks a lot daniel wang VC MFC Discussions GetWindowDC (1) WindowProc (1) Gindi (1) Danielgindi (1) NCCALCSIZE (1) NCPAINT (1) Window (1) Wang (1 change, then handle WM_NCPAINT and WM_NCCALCSIZE to set skin dimensions and draw the skin. Use GetWindowDC() to get a device context of the whole window including the non-client area - that
my program. Here is my code, which doesn't bring up the image: HDC desktopHDC = GetWindowDC(NULL); HDC splashHDC = CreateCompatibleDC(desktopHDC ); HBITMAP splashBM = CreateCompatibleBitmap(desktopHDC, 480, 180); SelectObject(splashHDC, "C: \ Dev the same thing on the Mac?) Thanks for your time! VC Language Discussions CreateCompatibleDC (1) GetWindowDC (1) CreateCompatibleBitmap (1) GetSystemMetrics (1) DesktopHDC (1) SplashHDC (1) SelectObject (1) LoadImage (1) Did you
over an open window to log messages Could someone help me please ? VC MFC Discussions GetWindowDC (1) WindowFromPoint (1) GetWindowRect (1) GetCursorPos (1) ReleaseDC (1) ReleaseCapture (1) You will need to GetCursorPos) * Get the HWND of the window beneath the mouse (WindowFromPoint) * * ** ** ** *> > > > > Highlight the window (GetWindowRect, GetWindowDC, SelectObject, Rectangle, ReleaseDC). * When the user lifts up the left-mouse button, stop monitoring mouse