SCROLLBARINFO fixes

Phil Krylov phil at newstar.rinet.ru
Mon Mar 7 13:18:33 CST 2005


The MSDN documentation for the rgstate member of SCROLLBARINFO structure is not
very clear and seems to have typos/errors. I tried to implement everything as
close to the documentation as possible.

ChangeLog:

Implemented GetScrollBarInfo() function and SBM_GETSCROLLBARINFO message.

-- Ph.
-------------- next part --------------
Index: scroll.c
===================================================================
RCS file: /home/wine/wine/dlls/user/scroll.c,v
retrieving revision 1.8
diff -p -u -r1.8 scroll.c
--- scroll.c	24 Feb 2005 19:38:56 -0000	1.8
+++ scroll.c	7 Mar 2005 18:57:43 -0000
@@ -26,11 +26,6 @@
  * Unless otherwise noted, we believe this code to be complete, as per
  * the specification mentioned above.
  * If you discover missing features, or bugs, please note them below.
- *
- * TODO:
- *   - GetScrollBarInfo
- *   - SBM_GETSCROLLBARINFO
- *   - SCROLLBARINFO
  */
 
 #include <stdarg.h>
@@ -1209,6 +1204,101 @@ static BOOL SCROLL_GetScrollInfo(HWND hw
 
 
 /*************************************************************************
+ *           SCROLL_GetScrollBarInfo
+ *
+ * Internal helper for the API function
+ *
+ * PARAMS
+ *    hwnd     [I]  Handle of window with scrollbar(s)
+ *    idObject [I]  One of OBJID_CLIENT, OBJID_HSCROLL, or OBJID_VSCROLL
+ *    info     [IO] cbSize specifies the size of the structure
+ *
+ * RETURNS
+ *    FALSE if failed
+ */
+static BOOL SCROLL_GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO info)
+{
+    LPSCROLLBAR_INFO infoPtr;
+    INT nBar;
+    INT nDummy;
+    DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+    BOOL pressed;
+
+    switch (idObject)
+    {
+        case OBJID_CLIENT: nBar = SB_CTL; break;
+        case OBJID_HSCROLL: nBar = SB_HORZ; break;
+        case OBJID_VSCROLL: nBar = SB_VERT; break;
+        default: return FALSE;
+    }
+
+    /* handle invalid data structure */
+    if (!info->cbSize != sizeof(*info))
+        return FALSE;
+
+    if (!SCROLL_GetScrollBarRect(hwnd, nBar, &info->rcScrollBar, &nDummy,
+                                 &info->dxyLineButton, &info->xyThumbTop))
+        return FALSE;
+
+    info->xyThumbBottom = info->xyThumbTop + info->dxyLineButton;
+
+    infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, TRUE);
+    
+    /* Scroll bar state */
+    info->rgstate[0] = 0;
+    if ((nBar == SB_HORZ && !(style & WS_HSCROLL))
+        || (nBar == SB_VERT && !(style & WS_VSCROLL)))
+        info->rgstate[0] |= STATE_SYSTEM_INVISIBLE;
+    if (infoPtr->minVal >= infoPtr->maxVal - max(infoPtr->page - 1, 0))
+    {
+        if (!(info->rgstate[0] & STATE_SYSTEM_INVISIBLE))
+            info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE;
+        else
+            info->rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
+    }
+    if (nBar == SB_CTL && !IsWindowEnabled(hwnd))
+        info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE;
+    
+    pressed = ((nBar == SB_VERT) == SCROLL_trackVertical && GetCapture() == hwnd);
+    
+    /* Top/left arrow button state. MSDN says top/right, but I don't believe it */
+    info->rgstate[1] = 0;
+    if (pressed && SCROLL_trackHitTest == SCROLL_TOP_ARROW)
+        info->rgstate[1] |= STATE_SYSTEM_PRESSED;
+    if (infoPtr->flags & ESB_DISABLE_LTUP)
+        info->rgstate[1] |= STATE_SYSTEM_UNAVAILABLE;
+
+    /* Page up/left region state. MSDN says up/right, but I don't believe it */
+    info->rgstate[2] = 0;
+    if (infoPtr->curVal == infoPtr->minVal)
+        info->rgstate[2] |= STATE_SYSTEM_INVISIBLE;
+    if (pressed && SCROLL_trackHitTest == SCROLL_TOP_RECT)
+        info->rgstate[2] |= STATE_SYSTEM_PRESSED;
+
+    /* Thumb state */
+    info->rgstate[3] = 0;
+    if (pressed && SCROLL_trackHitTest == SCROLL_THUMB)
+        info->rgstate[3] |= STATE_SYSTEM_PRESSED;
+
+    /* Page down/right region state. MSDN says down/left, but I don't believe it */
+    info->rgstate[4] = 0;
+    if (infoPtr->curVal >= infoPtr->maxVal - 1)
+        info->rgstate[4] |= STATE_SYSTEM_INVISIBLE;
+    if (pressed && SCROLL_trackHitTest == SCROLL_BOTTOM_RECT)
+        info->rgstate[4] |= STATE_SYSTEM_PRESSED;
+    
+    /* Bottom/right arrow button state. MSDN says bottom/left, but I don't believe it */
+    info->rgstate[5] = 0;
+    if (pressed && SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW)
+        info->rgstate[5] |= STATE_SYSTEM_PRESSED;
+    if (infoPtr->flags & ESB_DISABLE_RTDN)
+        info->rgstate[5] |= STATE_SYSTEM_UNAVAILABLE;
+        
+    return TRUE;
+}
+
+
+/*************************************************************************
  *           SCROLL_GetScrollPos
  *
  *  Internal helper for the API function
@@ -1439,10 +1529,12 @@ static LRESULT WINAPI ScrollBarWndProc( 
     case SBM_GETSCROLLINFO:
         return SCROLL_GetScrollInfo(hwnd, SB_CTL, (SCROLLINFO *)lParam);
 
+    case SBM_GETSCROLLBARINFO:
+        return SCROLL_GetScrollBarInfo(hwnd, OBJID_CLIENT, (SCROLLBARINFO *)lParam);
+
     case 0x00e5:
     case 0x00e7:
     case 0x00e8:
-    case 0x00eb:
     case 0x00ec:
     case 0x00ed:
     case 0x00ee:
@@ -1661,6 +1753,32 @@ BOOL WINAPI GetScrollInfo(HWND hwnd, INT
         SCROLL_GetScrollInfo(hwnd, nBar, info);
 
     return TRUE;
+}
+
+
+/*************************************************************************
+ *           GetScrollBarInfo   (USER32.@)
+ *
+ * GetScrollBarInfo can be used to retrieve information about a scrollbar
+ * control.
+ *
+ * PARAMS
+ *  hwnd     [I]  Handle of window with scrollbar(s)
+ *  idObject [I]  One of OBJID_CLIENT, OBJID_HSCROLL, or OBJID_VSCROLL
+ *  info     [IO] cbSize specifies the size of SCROLLBARINFO
+ *
+ * RETURNS
+ *  TRUE if success
+ */
+BOOL WINAPI GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO info)
+{
+    TRACE("hwnd=%p idObject=%ld info=%p\n", hwnd, idObject, info);
+
+    /* Refer OBJID_CLIENT requests to the window */
+    if (idObject == OBJID_CLIENT)
+        return SendMessageW(hwnd, SBM_GETSCROLLBARINFO, (WPARAM)0, (LPARAM)info);
+    else
+        return SCROLL_GetScrollBarInfo(hwnd, idObject, info);
 }
 
 
Index: user32.spec
===================================================================
RCS file: /home/wine/wine/dlls/user/user32.spec,v
retrieving revision 1.100
diff -p -u -r1.100 user32.spec
--- user32.spec	1 Feb 2005 18:54:51 -0000	1.100
+++ user32.spec	7 Mar 2005 18:57:43 -0000
@@ -294,7 +294,7 @@
 @ stdcall GetPropA(long str)
 @ stdcall GetPropW(long wstr)
 @ stdcall GetQueueStatus(long)
-@ stub GetScrollBarInfo
+@ stdcall GetScrollBarInfo(long long ptr)
 @ stdcall GetScrollInfo(long long ptr)
 @ stdcall GetScrollPos(long long)
 @ stdcall GetScrollRange(long long ptr ptr)


More information about the wine-patches mailing list