Discussion:
SetWindowRgn kills client area
(too old to reply)
Dakota Ridge
2007-04-30 03:38:00 UTC
Permalink
I'm using a custom frame on a window, including borders and caption. I
handle the WM_NCCalcSize message to set the appropriate client area. This
works perfectly ... until I create a path and use SetWindowRgn to set the
rounded corners on the window. When I implement this function, the client
area becomes the full size of the window. Remove the SetWindowRgn call and
everything once again works perfectly. I tried SetWindowPos with
SWP_FrameChanged to force a new WM_NCCalcSize message immediately after
calling SetWindowRgn. No luck - the client area still remains as large as
the window and there is no non client area per se. Any ideas?
Ivan Brugiolo [MSFT]
2007-05-03 19:55:06 UTC
Permalink
I cannot repro on my end.
I could create a window that answers to WM_NCCALCSIZE and has a region.

case WM_CREATE: {
WINDOWINFO WinInfo = {sizeof(WinInfo)};
GetWindowInfo(hWnd,&WinInfo);

UINT frameCornerRadius = 6;
UINT CornerRadius = 2 * frameCornerRadius;

OffsetRect(&WinInfo.rcWindow,-WinInfo.rcWindow.left,-WinInfo.rcWindow.top);
const RECT & rectWindow = WinInfo.rcWindow;

HRGN hRoundRectRegion = CreateRoundRectRgn(rectWindow.left,
rectWindow.top,
rectWindow.right + 1,
rectWindow.bottom + 1,
CornerRadius,
CornerRadius);
SetWindowRgn(hWnd,hRoundRectRegion,FALSE);

return TRUE;
};
case WM_NCCALCSIZE: {
if (WinStylesSettings->bUseNcCalc) {
if (FALSE == wParam) {
return DefWindowProc(hWnd,uMsg,wParam,lParam);
} else {
LPNCCALCSIZE_PARAMS CalcSizeParam =
(LPNCCALCSIZE_PARAMS)lParam;

// extend upward the client area
INT SaveTop = CalcSizeParam->rgrc[0].top;

CalcSizeParam->rgrc[0] = CalcSizeParam->rgrc[2];
CalcSizeParam->rgrc[0].top = SaveTop;

return 0;
}
} else {
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
};

lkd> !userkdx.dw -vof 0xfffff97ff7cc9d70
s 0 et 0xfffffadfeba59600 t 0xfffffa80040307e0 q 0xfffffa8004896eb0 ppi
0xfffffa8004279d40 i c70.f60 WinStyles.exe
pwnd = 0xfffff97ff7cc9d70
handle 0x0000000000550d62
spwndNext 0xfffff97ff7cca060 "WinStyles"
spwndPrev 0xfffff97ff7dae370 "Default IME"
spwndParent 0xfffff97ff7c20d90 "<null>"
spwndChild 0x0000000000000000 ""
spwndOwner 0x0000000000000000 ""
rcWindow (220,220)-(620,420) 400x200
rcClient (223,220)-(617,417) 394x197 <<<<<< the client
area is extended to the top
lpfnWndProc 0x00000001000019d8 () Unicode
pcls 0xfffff97ff7cc9b20 (V):0xc3d0 (NV):0xc3d0
Name:"TestWindowStyle_Class"
hrgnUpdate 0x0000000000000000
spwndLastActive 0xfffff97ff7cc9d70 "<null>"
ppropList 0x0000000000000000
pSBInfo 0x0000000000000000
spmenuSys 0x0000000000000000
spmenu/id 0x0000000000000000
hrgnClip 0x000000006004263e <<<< the window region, is
with round corners, see the scanlines below.
pName "<null>"
dwUserData 0x0000000000000000
state 0x40000008
state2 0x80000700
ExStyle 0x00000900
style 0x14c80000
fnid 0x00000000
hImc 0x0d8005e3
bFullScreen 0y0
hModule 0x00000000
pActCtx 0x0000000000000000
WEFGHOSTMAKEVISIBLE fffff97ff7cc9da1:08
WEFWINDOWEDGE fffff97ff7cc9da1:01
WFBORDER fffff97ff7cc9da6:80
WFCAPTION fffff97ff7cc9da6:c0
WFCLIPSIBLINGS fffff97ff7cc9da7:04
WFCPRESENT fffff97ff7cc9d98:08
WFDLGFRAME fffff97ff7cc9da6:40
WFREALLYMAXIMIZABLE fffff97ff7cc9d9b:40
WFSYSMENU fffff97ff7cc9da6:08
WFTOPLEVEL fffff97ff7cc9da6:40
WFVISIBLE fffff97ff7cc9da7:10
WFWIN31COMPAT fffff97ff7cc9d9d:01
WFWIN40COMPAT fffff97ff7cc9d9d:02
WFWIN50COMPAT fffff97ff7cc9d9d:04
NULL Property List
---
lkd> !gdikdx.dh 6004263e
--------------------------------------------------
GDI Entry for handle 0x000000006004263e:
pobj : 0xfffffa80`035f35a0 _BASEOBJECT
Lock : 0y0
Pid : 0x0 (0)
ulObj : 0
FullUnique : 0x6004 RGN_TYPE : LO_REGION_TYPE
Objt : 0x4 '' (RGN_TYPE)
Flags : 0 ''
pUser : (null)
--------------------------------------------------
GDI BaseObject @ 0xfffffa80035f35a0:
hHmgr : 0x00000000`6004263e RGN_TYPE : LO_REGION_TYPE
ulShareCount : 0
cExclusiveLock : 0
BaseFlags : 0
Tid : 0xfffffadf`e607abf0 _W32THREAD
--------------------------------------------------
lkd> !iexts.region 0xfffffa80035f35a0
- 00000000 win32k!SCAN fffffa80035f3608 - -2147483648 220
- 00000001 win32k!SCAN fffffa80035f3618 - 220 221
225
615
- 00000002 win32k!SCAN fffffa80035f3630 - 221 222
223
617
- 00000003 win32k!SCAN fffffa80035f3648 - 222 223
222
618
- 00000004 win32k!SCAN fffffa80035f3660 - 223 226
221
619
- 00000005 win32k!SCAN fffffa80035f3678 - 226 414
220
620
- 00000006 win32k!SCAN fffffa80035f3690 - 414 417
221
619
- 00000007 win32k!SCAN fffffa80035f36a8 - 417 418
222
618
- 00000008 win32k!SCAN fffffa80035f36c0 - 418 419
223
617
- 00000009 win32k!SCAN fffffa80035f36d8 - 419 420
225
615
- 00000010 win32k!SCAN fffffa80035f36f0 - 420 2147483647
lkd>
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Dakota Ridge
I'm using a custom frame on a window, including borders and caption. I
handle the WM_NCCalcSize message to set the appropriate client area. This
works perfectly ... until I create a path and use SetWindowRgn to set the
rounded corners on the window. When I implement this function, the client
area becomes the full size of the window. Remove the SetWindowRgn call and
everything once again works perfectly. I tried SetWindowPos with
SWP_FrameChanged to force a new WM_NCCalcSize message immediately after
calling SetWindowRgn. No luck - the client area still remains as large as
the window and there is no non client area per se. Any ideas?
Loading...