RESEND: Add a test case for scroll APIs, fix a few bugs spotted by it

Dmitry Timoshkov dmitry at baikal.ru
Fri Jul 9 01:46:21 CDT 2004


Hello,

here a diff against current CVS.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add a test case for scroll APIs, fix a few bugs spotted by it.

--- cvs/hq/wine/controls/scroll.c	2004-07-09 15:30:07.000000000 +0900
+++ wine/controls/scroll.c	2004-07-09 15:38:16.000000000 +0900
@@ -94,7 +94,7 @@ static BOOL SCROLL_MovingThumb = FALSE;
 static BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
 				    BOOL fShowH, BOOL fShowV );
 static INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar,
-				   const SCROLLINFO *info, INT *action );
+                                 const SCROLLINFO *info, BOOL bRedraw );
 static void SCROLL_DrawInterior_9x( HWND hwnd, HDC hdc, INT nBar,
 				    RECT *rect, INT arrowSize,
 				    INT thumbSize, INT thumbPos,
@@ -464,7 +464,7 @@ static void SCROLL_DrawInterior_9x( HWND
      */
     if (nBar == SB_CTL)
     {
-      hBrush = (HBRUSH)SendMessageA( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
+      hBrush = (HBRUSH)SendMessageW( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
 				     (WPARAM)hdc,(LPARAM)hwnd);
     }
     else
@@ -560,7 +560,7 @@ static void SCROLL_DrawInterior( HWND hw
      * to correctly setup default scrollbar colors
      */
     if (nBar == SB_CTL) {
-        hBrush = (HBRUSH)SendMessageA( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
+        hBrush = (HBRUSH)SendMessageW( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
                                        (WPARAM)hdc,(LPARAM)hwnd);
     } else {
         hBrush = DEFWND_ControlColor( hdc, CTLCOLOR_SCROLLBAR );
@@ -768,7 +768,7 @@ LPARAM lParam /* [in] Variable input inc
     default: return;
     }
     SendMessageW(GetParent(hwnd),
-        ((GetWindowLongA( hwnd, GWL_STYLE ) & SBS_VERT) ?
+        ((GetWindowLongW( hwnd, GWL_STYLE ) & SBS_VERT) ?
             WM_VSCROLL : WM_HSCROLL), wParam, (LPARAM)hwnd);
 }
 
@@ -845,7 +845,7 @@ static void SCROLL_HandleScrollEvent( HW
           lastMousePos  = lastClickPos;
           trackThumbPos = thumbPos;
           prevPt = pt;
-          if (nBar == SB_CTL && (GetWindowLongA(hwnd, GWL_STYLE) & WS_TABSTOP)) SetFocus( hwnd );
+          if (nBar == SB_CTL && (GetWindowLongW(hwnd, GWL_STYLE) & WS_TABSTOP)) SetFocus( hwnd );
           SetCapture( hwnd );
           break;
 
@@ -885,7 +885,7 @@ static void SCROLL_HandleScrollEvent( HW
         {
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
-                SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                                 SB_LINEUP, (LPARAM)hwndCtl );
 	    }
 
@@ -904,7 +904,7 @@ static void SCROLL_HandleScrollEvent( HW
         {
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
-                SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                                 SB_PAGEUP, (LPARAM)hwndCtl );
             }
             SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
@@ -955,7 +955,7 @@ static void SCROLL_HandleScrollEvent( HW
                 SCROLL_TrackingVal = SCROLL_GetThumbVal( infoPtr, &rect,
                                                          vertical,
                                                          SCROLL_TrackingPos );
-                SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                                 MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
                                 (LPARAM)hwndCtl );
 		if (!SCROLL_MovingThumb)
@@ -973,7 +973,7 @@ static void SCROLL_HandleScrollEvent( HW
         {
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
-                SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                                 SB_PAGEDOWN, (LPARAM)hwndCtl );
             }
             SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
@@ -990,7 +990,7 @@ static void SCROLL_HandleScrollEvent( HW
         {
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
-                SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                                 SB_LINEDOWN, (LPARAM)hwndCtl );
 	    }
 
@@ -1009,7 +1009,7 @@ static void SCROLL_HandleScrollEvent( HW
         {
             UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
-            SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+            SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                             MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)hwndCtl );
         }
     }
@@ -1023,10 +1023,10 @@ static void SCROLL_HandleScrollEvent( HW
         {
             UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
-            SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+            SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                             MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)hwndCtl );
         }
-        SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+        SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                           SB_ENDSCROLL, (LPARAM)hwndCtl );
     }
 
@@ -1207,7 +1207,7 @@ LPINT lpMax /* [out] Where to store maxi
     if (lpMin) *lpMin = infoPtr ? infoPtr->minVal : 0;
     if (lpMax) *lpMax = infoPtr ? infoPtr->maxVal : 0;
 
-    return infoPtr ? TRUE : FALSE;
+    return TRUE;
 }
 
 
@@ -1230,7 +1230,7 @@ static BOOL SCROLL_SetScrollRange(
         infoPtr->minVal = minVal;
         infoPtr->maxVal = maxVal;
     }
-    return infoPtr ? TRUE : FALSE;
+    return TRUE;
 }
 
 
@@ -1393,7 +1393,7 @@ static LRESULT WINAPI ScrollBarWndProc( 
         return EnableScrollBar( hwnd, SB_CTL, wParam );
 
     case SBM_SETSCROLLINFO:
-        return SetScrollInfo( hwnd, SB_CTL, (SCROLLINFO *)lParam, wParam );
+        return SCROLL_SetScrollInfo( hwnd, SB_CTL, (SCROLLINFO *)lParam, wParam );
 
     case SBM_GETSCROLLINFO:
         return SCROLL_GetScrollInfo(hwnd, SB_CTL, (SCROLLINFO *)lParam);
@@ -1440,27 +1440,16 @@ INT nBar /* [in] One of SB_HORZ, SB_VERT
 const SCROLLINFO *info /* [in] Specifies what to change and new values */,
 BOOL bRedraw /* [in] Should scrollbar be redrawn afterwards ? */)
 {
-    INT action;
-    INT retVal = SCROLL_SetScrollInfo( hwnd, nBar, info, &action );
+    TRACE("hwnd=%p nBar=%d info=%p, bRedraw=%d\n", hwnd, nBar, info, bRedraw);
 
-    if( action & SA_SSI_HIDE )
-	SCROLL_ShowScrollBar( hwnd, nBar, FALSE, FALSE );
+    /* Refer SB_CTL requests to the window */
+    if (nBar == SB_CTL)
+        return SendMessageW(hwnd, SBM_SETSCROLLINFO, bRedraw, (LPARAM)info);
     else
-    {
-	if( action & SA_SSI_SHOW )
-	    if( SCROLL_ShowScrollBar( hwnd, nBar, TRUE, TRUE ) )
-		return retVal; /* SetWindowPos() already did the painting */
-
-	if( bRedraw )
-	    SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
-	else if( action & SA_SSI_REPAINT_ARROWS )
-	    SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, FALSE );
-    }
-    return retVal;
+        return SCROLL_SetScrollInfo( hwnd, nBar, info, bRedraw );
 }
 
-INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar,
-			    const SCROLLINFO *info, INT *action  )
+static INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar, const SCROLLINFO *info, BOOL bRedraw )
 {
     /* Update the scrollbar state and set action flags according to
      * what has to be done graphics wise. */
@@ -1468,8 +1457,7 @@ INT SCROLL_SetScrollInfo( HWND hwnd, INT
     SCROLLBAR_INFO *infoPtr;
     UINT new_flags;
     BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */
-
-   *action = 0;
+    INT action = 0;
 
     if (!(infoPtr = SCROLL_GetScrollBarInfo(hwnd, nBar))) return 0;
     if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
@@ -1492,7 +1480,7 @@ INT SCROLL_SetScrollInfo( HWND hwnd, INT
 	if( infoPtr->page != info->nPage )
 	{
             infoPtr->page = info->nPage;
-	   *action |= SA_SSI_REFRESH;
+            action |= SA_SSI_REFRESH;
            bChangeParams = TRUE;
 	}
     }
@@ -1504,7 +1492,7 @@ INT SCROLL_SetScrollInfo( HWND hwnd, INT
 	if( infoPtr->curVal != info->nPos )
 	{
 	    infoPtr->curVal = info->nPos;
-	   *action |= SA_SSI_REFRESH;
+            action |= SA_SSI_REFRESH;
 	}
     }
 
@@ -1525,7 +1513,7 @@ INT SCROLL_SetScrollInfo( HWND hwnd, INT
 	    if( infoPtr->minVal != info->nMin ||
 		infoPtr->maxVal != info->nMax )
 	    {
-                *action |= SA_SSI_REFRESH;
+                action |= SA_SSI_REFRESH;
                 infoPtr->minVal = info->nMin;
                 infoPtr->maxVal = info->nMax;
                 bChangeParams = TRUE;
@@ -1566,11 +1554,11 @@ INT SCROLL_SetScrollInfo( HWND hwnd, INT
             if (info->fMask & SIF_DISABLENOSCROLL)
 	    {
                 new_flags = ESB_DISABLE_BOTH;
-	       *action |= SA_SSI_REFRESH;
+                action |= SA_SSI_REFRESH;
 	    }
             else if ((nBar != SB_CTL) && bChangeParams)
 	    {
-		*action = SA_SSI_HIDE;
+                action = SA_SSI_HIDE;
 		goto done;
             }
         }
@@ -1578,19 +1566,32 @@ INT SCROLL_SetScrollInfo( HWND hwnd, INT
         {
 	    new_flags = 0;
             if ((nBar != SB_CTL) && bChangeParams)
-		*action |= SA_SSI_SHOW;
+                action |= SA_SSI_SHOW;
         }
 
         if (infoPtr->flags != new_flags) /* check arrow flags */
         {
             infoPtr->flags = new_flags;
-           *action |= SA_SSI_REPAINT_ARROWS;
+            action |= SA_SSI_REPAINT_ARROWS;
         }
     }
 
 done:
-    /* Return current position */
+    if( action & SA_SSI_HIDE )
+        SCROLL_ShowScrollBar( hwnd, nBar, FALSE, FALSE );
+    else
+    {
+        if( action & SA_SSI_SHOW )
+            if( SCROLL_ShowScrollBar( hwnd, nBar, TRUE, TRUE ) )
+                return infoPtr->curVal; /* SetWindowPos() already did the painting */
+
+        if( bRedraw )
+            SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
+        else if( action & SA_SSI_REPAINT_ARROWS )
+            SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, FALSE );
+    }
 
+    /* Return current position */
     return infoPtr->curVal;
 }
 
@@ -1612,9 +1613,11 @@ LPSCROLLINFO info /* [in/out] (fMask spe
 
     /* Refer SB_CTL requests to the window */
     if (nBar == SB_CTL)
-        return SendMessageA(hwnd, SBM_GETSCROLLINFO, (WPARAM)0, (LPARAM)info);
+        SendMessageW(hwnd, SBM_GETSCROLLINFO, (WPARAM)0, (LPARAM)info);
     else
-        return SCROLL_GetScrollInfo(hwnd, nBar, info);
+        SCROLL_GetScrollInfo(hwnd, nBar, info);
+
+    return TRUE;
 }
 
 
@@ -1668,7 +1671,7 @@ INT nBar /* [in] One of SB_HORZ, SB_VERT
 
     /* Refer SB_CTL requests to the window */
     if (nBar == SB_CTL)
-        return SendMessageA(hwnd, SBM_GETPOS, (WPARAM)0, (LPARAM)0);
+        return SendMessageW(hwnd, SBM_GETPOS, (WPARAM)0, (LPARAM)0);
     else
         return SCROLL_GetScrollPos(hwnd, nBar);
 }
@@ -1686,22 +1689,16 @@ INT minVal, /* [in] New minimum value */
 INT maxVal, /* [in] New maximum value */
 BOOL bRedraw /* [in] Should scrollbar be redrawn afterwards ? */)
 {
-    BOOL ret;
-
-    TRACE("hwnd=%p nBar=%d min=%d max=%d\n", hwnd, nBar, minVal, maxVal);
-
-    /* Refer SB_CTL requests to the window */
-    if (nBar == SB_CTL)
-        ret = SendMessageW(hwnd, SBM_SETRANGE, minVal, maxVal);
-    else
-    {
-        ret = SCROLL_SetScrollRange(hwnd, nBar, minVal, maxVal);
-        ShowScrollBar(hwnd, nBar, minVal != maxVal);
-    }
-
-    if (bRedraw)
-        SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
-    return ret;
+    SCROLLINFO info;
+ 
+    TRACE("hwnd=%p nBar=%d min=%d max=%d, bRedraw=%d\n", hwnd, nBar, minVal, maxVal, bRedraw);
+ 
+    info.cbSize = sizeof(info);
+    info.fMask  = SIF_RANGE;
+    info.nMin   = minVal;
+    info.nMax   = maxVal;
+    SetScrollInfo( hwnd, nBar, &info, bRedraw );
+    return TRUE;
 }
 
 
@@ -1713,7 +1710,6 @@ BOOL bRedraw /* [in] Should scrollbar be
 INT SCROLL_SetNCSbState(HWND hwnd, int vMin, int vMax, int vPos,
                         int hMin, int hMax, int hPos)
 {
-    INT vA, hA;
     SCROLLINFO vInfo, hInfo;
 
     vInfo.cbSize = hInfo.cbSize = sizeof(SCROLLINFO);
@@ -1725,19 +1721,9 @@ INT SCROLL_SetNCSbState(HWND hwnd, int v
     hInfo.nPos   = hPos;
     vInfo.fMask  = hInfo.fMask = SIF_RANGE | SIF_POS;
 
-    SCROLL_SetScrollInfo( hwnd, SB_VERT, &vInfo, &vA );
-    SCROLL_SetScrollInfo( hwnd, SB_HORZ, &hInfo, &hA );
-
-    if( !SCROLL_ShowScrollBar( hwnd, SB_BOTH,
-			      (hA & SA_SSI_SHOW),(vA & SA_SSI_SHOW) ) )
-    {
-	/* SetWindowPos() wasn't called, just redraw the scrollbars if needed */
-	if( vA & SA_SSI_REFRESH )
-	    SCROLL_RefreshScrollBar( hwnd, SB_VERT, FALSE, TRUE );
+    SCROLL_SetScrollInfo( hwnd, SB_VERT, &vInfo, TRUE );
+    SCROLL_SetScrollInfo( hwnd, SB_HORZ, &hInfo, TRUE );
 
-	if( hA & SA_SSI_REFRESH )
-	    SCROLL_RefreshScrollBar( hwnd, SB_HORZ, FALSE, TRUE );
-    }
     return 0;
 }
 
@@ -1757,9 +1743,11 @@ LPINT lpMax /* [out] Where to store maxi
 
     /* Refer SB_CTL requests to the window */
     if (nBar == SB_CTL)
-        return SendMessageA(hwnd, SBM_GETRANGE, (WPARAM)lpMin, (LPARAM)lpMax);
+        SendMessageW(hwnd, SBM_GETRANGE, (WPARAM)lpMin, (LPARAM)lpMax);
     else
-        return SCROLL_GetScrollRange(hwnd, nBar, lpMin, lpMax);
+        SCROLL_GetScrollRange(hwnd, nBar, lpMin, lpMax);
+
+    return TRUE;
 }
 
 
diff -u cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2004-07-06 11:26:42.000000000 +0900
+++ wine/dlls/user/tests/msg.c	2004-07-09 15:32:05.000000000 +0900
@@ -54,6 +54,11 @@ struct message {
     LPARAM lParam;         /* expected value of lParam */
 };
 
+/* Empty message sequence */
+static const struct message WmEmptySeq[] =
+{
+    { 0 }
+};
 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
 static const struct message WmCreateOverlappedSeq[] = {
     { HCBT_CREATEWND, hook },
@@ -188,10 +193,6 @@ static const struct message WmCreateInvi
     { WM_MOVE, sent },
     { 0 }
 };
-/* ShowWindow (for a popup window with WS_VISIBLE style set) */
-static const struct message WmShowVisiblePopupSeq[] = {
-    { 0 }
-};
 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
  * for a popup window with WS_VISIBLE style set
  */
@@ -644,6 +645,48 @@ static const struct message WmEnableWind
     { 0 }
 };
 
+static const struct message WmGetScrollRangeSeq[] =
+{
+    { SBM_GETRANGE, sent },
+    { 0 }
+};
+static const struct message WmGetScrollInfoSeq[] =
+{
+    { SBM_GETSCROLLINFO, sent },
+    { 0 }
+};
+static const struct message WmSetScrollRangeSeq[] =
+{
+    /* MSDN claims that Windows sends SBM_SETRANGE message, but win2k SP4
+       sends SBM_SETSCROLLINFO.
+     */
+    { SBM_SETSCROLLINFO, sent },
+    { 0 }
+};
+/* SetScrollRange for a window without a non-client area */
+static const struct message WmSetScrollRangeHVSeq[] =
+{
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { 0 }
+};
+/* SetScrollRange for a window with a non-client area */
+static const struct message WmSetScrollRangeHV_NC_Seq[] =
+{
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_NCPAINT, sent|optional },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_CTLCOLORDLG, sent|defwinproc|optional }, /* sent to a parent of the dialog */
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_SIZE, sent|defwinproc },
+    { 0 }
+};
+
 static int after_end_dialog;
 static int sequence_cnt, sequence_size;
 static struct message* sequence;
@@ -1173,6 +1216,172 @@ static INT_PTR CALLBACK TestModalDlgProc
     return 0;
 }
 
+static void test_hv_scroll_1(HWND hwnd, INT ctl, DWORD clear, DWORD set, INT min, INT max)
+{
+    DWORD style, exstyle;
+    INT xmin, xmax;
+
+    exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
+    style = GetWindowLongA(hwnd, GWL_STYLE);
+    /* do not be confused by WS_DLGFRAME set */
+    if ((style & WS_CAPTION) == WS_CAPTION) style &= ~WS_CAPTION;
+
+    if (clear) ok(style & clear, "style %08lx should be set\n", clear);
+    if (set) ok(!(style & set), "style %08lx should not be set\n", set);
+
+    ok(SetScrollRange(hwnd, ctl, min, max, FALSE), "SetScrollRange(%d) error %ld\n", ctl, GetLastError());
+    if ((style & (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME)) || (exstyle & WS_EX_DLGMODALFRAME))
+        ok_sequence(WmSetScrollRangeHV_NC_Seq, "SetScrollRange(SB_HORZ/SB_VERT) NC");
+    else
+        ok_sequence(WmSetScrollRangeHVSeq, "SetScrollRange(SB_HORZ/SB_VERT)");
+
+    style = GetWindowLongA(hwnd, GWL_STYLE);
+    if (set) ok(style & set, "style %08lx should be set\n", set);
+    if (clear) ok(!(style & clear), "style %08lx should not be set\n", clear);
+
+    /* a subsequent call should do nothing */
+    ok(SetScrollRange(hwnd, ctl, min, max, FALSE), "SetScrollRange(%d) error %ld\n", ctl, GetLastError());
+    ok_sequence(WmEmptySeq, "SetScrollRange(SB_HORZ/SB_VERT)");
+
+    xmin = 0xdeadbeef;
+    xmax = 0xdeadbeef;
+    trace("Ignore GetScrollRange error below if you are on Win9x\n");
+    ok(GetScrollRange(hwnd, ctl, &xmin, &xmax), "GetScrollRange(%d) error %ld\n", ctl, GetLastError());
+    ok_sequence(WmEmptySeq, "GetScrollRange(SB_HORZ/SB_VERT)");
+    ok(xmin == min, "unexpected min scroll value %d\n", xmin);
+    ok(xmax == max, "unexpected max scroll value %d\n", xmax);
+}
+
+static void test_hv_scroll_2(HWND hwnd, INT ctl, DWORD clear, DWORD set, INT min, INT max)
+{
+    DWORD style, exstyle;
+    SCROLLINFO si;
+
+    exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
+    style = GetWindowLongA(hwnd, GWL_STYLE);
+    /* do not be confused by WS_DLGFRAME set */
+    if ((style & WS_CAPTION) == WS_CAPTION) style &= ~WS_CAPTION;
+
+    if (clear) ok(style & clear, "style %08lx should be set\n", clear);
+    if (set) ok(!(style & set), "style %08lx should not be set\n", set);
+
+    si.cbSize = sizeof(si);
+    si.fMask = SIF_RANGE;
+    si.nMin = min;
+    si.nMax = max;
+    SetScrollInfo(hwnd, ctl, &si, TRUE);
+    if ((style & (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME)) || (exstyle & WS_EX_DLGMODALFRAME))
+        ok_sequence(WmSetScrollRangeHV_NC_Seq, "SetScrollInfo(SB_HORZ/SB_VERT) NC");
+    else
+        ok_sequence(WmSetScrollRangeHVSeq, "SetScrollInfo(SB_HORZ/SB_VERT)");
+
+    style = GetWindowLongA(hwnd, GWL_STYLE);
+    if (set) ok(style & set, "style %08lx should be set\n", set);
+    if (clear) ok(!(style & clear), "style %08lx should not be set\n", clear);
+
+    /* a subsequent call should do nothing */
+    SetScrollInfo(hwnd, ctl, &si, TRUE);
+    ok_sequence(WmEmptySeq, "SetScrollInfo(SB_HORZ/SB_VERT)");
+
+    si.fMask = SIF_PAGE;
+    si.nPage = 5;
+    SetScrollInfo(hwnd, ctl, &si, FALSE);
+    ok_sequence(WmEmptySeq, "SetScrollInfo(SB_HORZ/SB_VERT)");
+
+    si.fMask = SIF_POS;
+    si.nPos = max - 1;
+    SetScrollInfo(hwnd, ctl, &si, FALSE);
+    ok_sequence(WmEmptySeq, "SetScrollInfo(SB_HORZ/SB_VERT)");
+
+    si.fMask = SIF_RANGE;
+    si.nMin = 0xdeadbeef;
+    si.nMax = 0xdeadbeef;
+    ok(GetScrollInfo(hwnd, ctl, &si), "GetScrollInfo error %ld\n", GetLastError());
+    ok_sequence(WmEmptySeq, "GetScrollRange(SB_HORZ/SB_VERT)");
+    ok(si.nMin == min, "unexpected min scroll value %d\n", si.nMin);
+    ok(si.nMax == max, "unexpected max scroll value %d\n", si.nMax);
+}
+
+/* Win9x sends WM_USER+xxx while and NT versions send SBM_xxx messages */
+static void test_scroll_messages(HWND hwnd)
+{
+    SCROLLINFO si;
+    INT min, max;
+
+    min = 0xdeadbeef;
+    max = 0xdeadbeef;
+    ok(GetScrollRange(hwnd, SB_CTL, &min, &max), "GetScrollRange error %ld\n", GetLastError());
+    if (sequence->message != WmGetScrollRangeSeq[0].message)
+        trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence->message);
+    /* values of min and max are undefined */
+    flush_sequence();
+
+    ok(SetScrollRange(hwnd, SB_CTL, 10, 150, FALSE), "SetScrollRange error %ld\n", GetLastError());
+    if (sequence->message != WmSetScrollRangeSeq[0].message)
+        trace("SetScrollRange(SB_CTL) generated unknown message %04x\n", sequence->message);
+    flush_sequence();
+
+    min = 0xdeadbeef;
+    max = 0xdeadbeef;
+    ok(GetScrollRange(hwnd, SB_CTL, &min, &max), "GetScrollRange error %ld\n", GetLastError());
+    if (sequence->message != WmGetScrollRangeSeq[0].message)
+        trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence->message);
+    /* values of min and max are undefined */
+    flush_sequence();
+
+    si.cbSize = sizeof(si);
+    si.fMask = SIF_RANGE;
+    si.nMin = 20;
+    si.nMax = 160;
+    SetScrollInfo(hwnd, SB_CTL, &si, FALSE);
+    if (sequence->message != WmSetScrollRangeSeq[0].message)
+        trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
+    flush_sequence();
+
+    si.fMask = SIF_PAGE;
+    si.nPage = 10;
+    SetScrollInfo(hwnd, SB_CTL, &si, FALSE);
+    if (sequence->message != WmSetScrollRangeSeq[0].message)
+        trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
+    flush_sequence();
+
+    si.fMask = SIF_POS;
+    si.nPos = 20;
+    SetScrollInfo(hwnd, SB_CTL, &si, FALSE);
+    if (sequence->message != WmSetScrollRangeSeq[0].message)
+        trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
+    flush_sequence();
+
+    si.fMask = SIF_RANGE;
+    si.nMin = 0xdeadbeef;
+    si.nMax = 0xdeadbeef;
+    ok(GetScrollInfo(hwnd, SB_CTL, &si), "GetScrollInfo error %ld\n", GetLastError());
+    if (sequence->message != WmGetScrollInfoSeq[0].message)
+        trace("GetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
+    /* values of min and max are undefined */
+    flush_sequence();
+
+    /* set WS_HSCROLL */
+    test_hv_scroll_1(hwnd, SB_HORZ, 0, WS_HSCROLL, 10, 150);
+    /* clear WS_HSCROLL */
+    test_hv_scroll_1(hwnd, SB_HORZ, WS_HSCROLL, 0, 0, 0);
+
+    /* set WS_HSCROLL */
+    test_hv_scroll_2(hwnd, SB_HORZ, 0, WS_HSCROLL, 10, 150);
+    /* clear WS_HSCROLL */
+    test_hv_scroll_2(hwnd, SB_HORZ, WS_HSCROLL, 0, 0, 0);
+
+    /* set WS_VSCROLL */
+    test_hv_scroll_1(hwnd, SB_VERT, 0, WS_VSCROLL, 10, 150);
+    /* clear WS_VSCROLL */
+    test_hv_scroll_1(hwnd, SB_VERT, WS_VSCROLL, 0, 0, 0);
+
+    /* set WS_VSCROLL */
+    test_hv_scroll_2(hwnd, SB_VERT, 0, WS_VSCROLL, 10, 150);
+    /* clear WS_VSCROLL */
+    test_hv_scroll_2(hwnd, SB_VERT, WS_VSCROLL, 0, 0, 0);
+}
+
 /* test if we receive the right sequence of messages */
 static void test_messages(void)
 {
@@ -1214,6 +1423,9 @@ static void test_messages(void)
     ShowWindow(hwnd, SW_SHOW);
     test_WM_SETREDRAW(hwnd);
 
+    trace("testing scroll APIs on a visible top level window %p\n", hwnd);
+    test_scroll_messages(hwnd);
+
     DestroyWindow(hwnd);
     ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped");
 
@@ -1233,6 +1445,10 @@ static void test_messages(void)
                              0, 0, 10, 10, hparent, 0, 0, NULL);
     ok (hchild != 0, "Failed to create child window\n");
     ok_sequence(WmCreateVisibleChildSeq, "CreateWindow:visible child");
+
+    trace("testing scroll APIs on a visible child window %p\n", hchild);
+    test_scroll_messages(hchild);
+
     DestroyWindow(hchild);
     flush_sequence();
 
@@ -1298,7 +1514,7 @@ static void test_messages(void)
     ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
     flush_sequence();
     ShowWindow(hchild, SW_SHOW);
-    ok_sequence(WmShowVisiblePopupSeq, "ShowWindow:show_visible_popup");
+    ok_sequence(WmEmptySeq, "ShowWindow:show_visible_popup");
     flush_sequence();
     SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
     ok_sequence(WmShowVisiblePopupSeq_2, "SetWindowPos:show_visible_popup_2");
@@ -1319,7 +1535,7 @@ static void test_messages(void)
     ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
     flush_sequence();
     ShowWindow(hchild, SW_SHOW);
-    ok_sequence(WmShowVisiblePopupSeq, "ShowWindow:show_visible_popup");
+    ok_sequence(WmEmptySeq, "ShowWindow:show_visible_popup");
     flush_sequence();
     SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
     ok_sequence(WmShowVisiblePopupSeq_2, "SetWindowPos:show_visible_popup_2");
@@ -1331,6 +1547,9 @@ static void test_messages(void)
     ok(hwnd != 0, "Failed to create custom dialog window\n");
     ok_sequence(WmCreateCustomDialogSeq, "CreateCustomDialog");
 
+    trace("testing scroll APIs on a visible dialog %p\n", hwnd);
+    test_scroll_messages(hwnd);
+
     flush_sequence();
     after_end_dialog = 1;
     EndDialog( hwnd, 0 );






More information about the wine-patches mailing list