DefWindowproc NCCALC fix for WS_xSCROLL styles
Rein Klazes
wijn at wanadoo.nl
Mon Feb 21 14:42:32 CST 2005
Hi,
This fixes a bug that was exposed by this change:
| Log message:
| Vitaly Lipatov <lav at etersoft.ru>
| Rename SCROLL_GetScrollBarInfo to SCROLL_GetInternalInfo and make
| allocation of a new info structure optional.
| Add some descriptions.
|
| Patch: http://cvs.winehq.org/patch.py?id=16164
A horizontal scrollbar control in Visual Studio 6 is created with the
WS_HSCROLL window style set. Now Windows will happily add a scroll bar
to a scroll bar control, but only if there is space enough.
If there is not, DefWindowProc's WM_NCCALC handler will not subtract the
scrollbar's height (or width for vertical sb's), leaving the client
space to draw Visual Studio's control.
Changelog:
windows : nonclient.c
dlls/user/tests : win.c
DefWindowProc's WM_NCCALC handler must not subtract space for
scrollbars if there is not enough space for it anyway. With
tests
to confirm the behavior.
Rein.
-------------- next part --------------
--- wine/windows/nonclient.c 2005-02-16 12:27:51.000000000 +0100
+++ mywine/windows/nonclient.c 2005-02-21 12:29:10.000000000 +0100
@@ -402,12 +402,23 @@ LONG NC_HandleNCCalcSize( HWND hwnd, REC
-tmpRect.left, -tmpRect.top ) + 1;
}
- SetRect(&tmpRect, 0, 0, 0, 0);
- NC_AdjustRectInner (&tmpRect, style, exStyle);
- winRect->left -= tmpRect.left;
- winRect->top -= tmpRect.top;
- winRect->right -= tmpRect.right;
- winRect->bottom -= tmpRect.bottom;
+ if( exStyle & WS_EX_CLIENTEDGE)
+ if( winRect->right - winRect->left > 2 * GetSystemMetrics(SM_CXEDGE) &&
+ winRect->bottom - winRect->top > 2 * GetSystemMetrics(SM_CYEDGE))
+ InflateRect( winRect, - GetSystemMetrics(SM_CXEDGE),
+ - GetSystemMetrics(SM_CYEDGE));
+
+ if (style & WS_VSCROLL)
+ if( winRect->right - winRect->left >= GetSystemMetrics(SM_CXVSCROLL)){
+ if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
+ winRect->left += GetSystemMetrics(SM_CXVSCROLL);
+ else
+ winRect->right -= GetSystemMetrics(SM_CXVSCROLL);
+ }
+
+ if (style & WS_HSCROLL)
+ if( winRect->bottom - winRect->top > GetSystemMetrics(SM_CYHSCROLL))
+ winRect->bottom -= GetSystemMetrics(SM_CYHSCROLL);
if (winRect->top > winRect->bottom)
winRect->bottom = winRect->top;
--- wine/dlls/user/tests/win.c 2005-02-18 14:38:24.000000000 +0100
+++ mywine/dlls/user/tests/win.c 2005-02-21 15:36:11.000000000 +0100
@@ -2231,6 +2231,58 @@ static void test_validatergn(HWND hwnd)
DestroyWindow( child );
}
+
+void nccalchelper( HWND hwnd, INT x, INT y, RECT *prc)
+{
+ MoveWindow( hwnd, 0, 0, x, y, 0);
+ GetWindowRect( hwnd, prc);
+ trace("window rect is %ld,%ld - %ld,%ld\n",
+ prc->left,prc->top,prc->right,prc->bottom);
+ DefWindowProcA(hwnd, WM_NCCALCSIZE, 0, (LPARAM)prc);
+ trace("nccalc rect is %ld,%ld - %ld,%ld\n",
+ prc->left,prc->top,prc->right,prc->bottom);
+}
+
+void test_nccalcscroll( HWND parent)
+{
+ RECT rc1;
+ INT sbheight = GetSystemMetrics( SM_CYHSCROLL);
+ INT sbwidth = GetSystemMetrics( SM_CXVSCROLL);
+ HWND hwnd = CreateWindowExA(0, "static", NULL,
+ WS_CHILD| WS_VISIBLE | WS_VSCROLL | WS_HSCROLL ,
+ 10, 10, 200, 200, parent, 0, 0, NULL);
+ ShowWindow( parent, SW_SHOW);
+ UpdateWindow( parent);
+
+ /* test window too low for a horizontal scroll bar */
+ nccalchelper( hwnd, 100, sbheight, &rc1);
+ ok( rc1.bottom - rc1.top == sbheight, "Height should be %d size is %ld,%ld - %ld,%ld\n",
+ sbheight, rc1.left, rc1.top, rc1.right, rc1.bottom);
+
+ /* test window just high enough for a horizontal scroll bar */
+ nccalchelper( hwnd, 100, sbheight + 1, &rc1);
+ ok( rc1.bottom - rc1.top == 1, "Height should be %d size is %ld,%ld - %ld,%ld\n",
+ 1, rc1.left, rc1.top, rc1.right, rc1.bottom);
+
+ /* test window too narrow for a vertical scroll bar */
+ nccalchelper( hwnd, sbwidth - 1, 100, &rc1);
+ ok( rc1.right - rc1.left == sbwidth - 1 , "Width should be %d size is %ld,%ld - %ld,%ld\n",
+ sbwidth - 1, rc1.left, rc1.top, rc1.right, rc1.bottom);
+
+ /* test window just wide enough for a vertical scroll bar */
+ nccalchelper( hwnd, sbwidth, 100, &rc1);
+ ok( rc1.right - rc1.left == 0, "Width should be %d size is %ld,%ld - %ld,%ld\n",
+ 0, rc1.left, rc1.top, rc1.right, rc1.bottom);
+
+ /* same test, but with client edge: not enough width */
+ SetWindowLong( hwnd, GWL_EXSTYLE, WS_EX_CLIENTEDGE | GetWindowLong( hwnd, GWL_EXSTYLE));
+ nccalchelper( hwnd, sbwidth, 100, &rc1);
+ ok( rc1.right - rc1.left == sbwidth - 2 * GetSystemMetrics(SM_CXEDGE),
+ "Width should be %d size is %ld,%ld - %ld,%ld\n",
+ sbwidth - 2 * GetSystemMetrics(SM_CXEDGE), rc1.left, rc1.top, rc1.right, rc1.bottom);
+
+ DestroyWindow( hwnd);
+}
START_TEST(win)
{
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
@@ -2287,6 +2339,7 @@ START_TEST(win)
test_keyboard_input(hwndMain);
test_mouse_input(hwndMain);
test_validatergn(hwndMain);
+ test_nccalcscroll( hwndMain);
UnhookWindowsHookEx(hhook);
}
More information about the wine-patches
mailing list