diff dwt/widgets/Scrollable.d @ 213:36f5cb12e1a2

Update to SWT 3.4M7
author Frank Benoit <benoit@tionex.de>
date Sat, 17 May 2008 17:34:28 +0200
parents ab60f3309436
children 8efa9bb96c53
line wrap: on
line diff
--- a/dwt/widgets/Scrollable.d	Mon May 05 00:12:38 2008 +0200
+++ b/dwt/widgets/Scrollable.d	Sat May 17 17:34:28 2008 +0200
@@ -12,16 +12,20 @@
  *******************************************************************************/
 module dwt.widgets.Scrollable;
 
-import dwt.widgets.Widget;
-import dwt.widgets.Event;
-import dwt.widgets.Control;
-import dwt.widgets.ScrollBar;
-import dwt.widgets.Composite;
 import dwt.DWT;
 import dwt.DWTException;
+
 import dwt.graphics.Rectangle;
+
 import dwt.internal.win32.OS;
 
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Decorations;
+import dwt.widgets.Event;
+import dwt.widgets.ScrollBar;
+import dwt.widgets.Widget;
+
 import dwt.dwthelper.utils;
 import tango.util.log.Trace;
 void trc( long line ){
@@ -149,6 +153,20 @@
     if ((style & DWT.V_SCROLL) !is 0) verticalBar = createScrollBar (DWT.V_SCROLL);
 }
 
+void destroyScrollBar (int type) {
+    auto hwnd = scrolledHandle ();
+    int bits = OS.GetWindowLong (hwnd, OS.GWL_STYLE);
+    if ((type & DWT.HORIZONTAL) !is 0) {
+        style &= ~DWT.H_SCROLL;
+        bits &= ~OS.WS_HSCROLL;
+    }
+    if ((type & DWT.VERTICAL) !is 0) {
+        style &= ~DWT.V_SCROLL;
+        bits &= ~OS.WS_VSCROLL;
+    }
+    OS.SetWindowLong (hwnd, OS.GWL_STYLE, bits);
+}
+
 /**
  * Returns a rectangle which describes the area of the
  * receiver which is capable of displaying data (that is,
@@ -278,9 +296,9 @@
 
 override LRESULT WM_MOUSEWHEEL (int wParam, int lParam) {
 trc(__LINE__);
+    int scrollRemainder = display.scrollRemainder;
     LRESULT result = super.WM_MOUSEWHEEL (wParam, lParam);
     if (result !is null) return result;
-
     /*
     * Translate WM_MOUSEWHEEL to WM_VSCROLL or WM_HSCROLL.
     */
@@ -288,27 +306,37 @@
         if ((wParam & (OS.MK_SHIFT | OS.MK_CONTROL)) !is 0) return result;
         bool vertical = verticalBar !is null && verticalBar.getEnabled ();
         bool horizontal = horizontalBar !is null && horizontalBar.getEnabled ();
-        int msg = (vertical) ? OS.WM_VSCROLL : (horizontal) ? OS.WM_HSCROLL : 0;
+        int msg = vertical ? OS.WM_VSCROLL : horizontal ? OS.WM_HSCROLL : 0;
         if (msg is 0) return result;
-        int value;
-        OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &value, 0);
-        int delta = cast(short) (wParam >> 16);
-        int code = 0, count = 0;
-        if (value  is OS.WHEEL_PAGESCROLL) {
-            code = delta < 0 ? OS.SB_PAGEDOWN : OS.SB_PAGEUP;
-            count = Math.abs (delta / OS.WHEEL_DELTA);
+        int linesToScroll;
+        OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &linesToScroll, 0);
+        int delta = OS.GET_WHEEL_DELTA_WPARAM (wParam);
+        bool pageScroll = linesToScroll is OS.WHEEL_PAGESCROLL;
+        if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {
+            ScrollBar bar = vertical ? verticalBar : horizontalBar;
+            SCROLLINFO info;
+            info.cbSize = SCROLLINFO.sizeof;
+            info.fMask = OS.SIF_POS;
+            OS.GetScrollInfo (handle, bar.scrollBarType (), &info);
+            if (vertical && !pageScroll) delta *= linesToScroll;
+            int increment = pageScroll ? bar.getPageIncrement () : bar.getIncrement ();
+            info.nPos -=  increment * delta / OS.WHEEL_DELTA;
+            OS.SetScrollInfo (handle, bar.scrollBarType (), &info, true);
+            OS.SendMessage (handle, msg, OS.SB_THUMBPOSITION, 0);
         } else {
-            code = delta < 0 ? OS.SB_LINEDOWN : OS.SB_LINEUP;
-            delta = Math.abs (delta);
-            if (delta < OS.WHEEL_DELTA) return result;
-            if (msg is OS.WM_VSCROLL) {
-                count = value  * delta / OS.WHEEL_DELTA;
+            int code = 0;
+            if (pageScroll) {
+                code = delta < 0 ? OS.SB_PAGEDOWN : OS.SB_PAGEUP;
             } else {
-                count = delta / OS.WHEEL_DELTA;
+                code = delta < 0 ? OS.SB_LINEDOWN : OS.SB_LINEUP;
+                if (msg is OS.WM_VSCROLL) delta *= linesToScroll;
             }
-        }
-        for (int i=0; i<count; i++) {
-            OS.SendMessage (handle, msg, code, 0);
+            /* Check if the delta and the remainder have the same direction (sign) */
+            if ((delta ^ scrollRemainder) >= 0) delta += scrollRemainder;
+            int count = Math.abs (delta) / OS.WHEEL_DELTA;
+            for (int i=0; i<count; i++) {
+                OS.SendMessage (handle, msg, code, 0);
+            }
         }
         return LRESULT.ZERO;
     }
@@ -326,7 +354,7 @@
     */
     int vPosition = verticalBar is null ? 0 : verticalBar.getSelection ();
     int hPosition = horizontalBar is null ? 0 : horizontalBar.getSelection ();
-    int code = callWindowProc (handle, OS.WM_MOUSEWHEEL, wParam, lParam);
+    int /*long*/ code = callWindowProc (handle, OS.WM_MOUSEWHEEL, wParam, lParam);
     if (verticalBar !is null) {
         int position = verticalBar.getSelection ();
         if (position !is vPosition) {
@@ -348,7 +376,7 @@
 
 override LRESULT WM_SIZE (int wParam, int lParam) {
 trc(__LINE__);
-    int code = callWindowProc (handle, OS.WM_SIZE, wParam, lParam);
+    int /*long*/ code = callWindowProc (handle, OS.WM_SIZE, wParam, lParam);
     super.WM_SIZE (wParam, lParam);
     // widget may be disposed at this point
     if (code is 0) return LRESULT.ZERO;
@@ -372,8 +400,64 @@
     return result;
 }
 
-LRESULT wmScroll (ScrollBar bar, bool update, HWND hwnd, int msg, int wParam, int lParam) {
-trc(__LINE__);
+LRESULT wmNCPaint (HWND hwnd, int /*long*/ wParam, int /*long*/ lParam) {
+    LRESULT result = super.wmNCPaint (hwnd, wParam, lParam);
+    if (result !is null) return result;
+    /*
+    * Bug in Windows.  On XP only (not Vista), Windows sometimes
+    * does not redraw the bottom right corner of a window that
+    * has scroll bars, causing pixel corruption.  The fix is to
+    * always draw the corner.
+    */
+    if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+        if (!OS.IsWinCE && OS.WIN32_VERSION < OS.VERSION (6, 0)) {
+            int bits1 = OS.GetWindowLong (hwnd, OS.GWL_STYLE);
+            if ((bits1 & (OS.WS_HSCROLL | OS.WS_VSCROLL)) !is 0) {
+                RECT windowRect;
+                OS.GetWindowRect (hwnd, &windowRect);
+                RECT trimRect;
+                int bits2 = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE);
+                OS.AdjustWindowRectEx (&trimRect, bits1, false, bits2);
+                bool hVisible = false, vVisible = false;
+                SCROLLBARINFO psbi;
+                psbi.cbSize = SCROLLBARINFO.sizeof;
+                if (OS.GetScrollBarInfo (hwnd, OS.OBJID_HSCROLL, &psbi)) {
+                    hVisible = (psbi.rgstate [0] & OS.STATE_SYSTEM_INVISIBLE) is 0;
+                }
+                if (OS.GetScrollBarInfo (hwnd, OS.OBJID_VSCROLL, &psbi)) {
+                    vVisible = (psbi.rgstate [0] & OS.STATE_SYSTEM_INVISIBLE) is 0;
+                }
+                RECT cornerRect;
+                cornerRect.right = windowRect.right - windowRect.left - trimRect.right;
+                cornerRect.bottom = windowRect.bottom - windowRect.top - trimRect.bottom;
+                cornerRect.left = cornerRect.right - (hVisible ? OS.GetSystemMetrics (OS.SM_CXVSCROLL) : 0);
+                cornerRect.top = cornerRect.bottom - (vVisible ? OS.GetSystemMetrics (OS.SM_CYHSCROLL) : 0);
+                if (cornerRect.left !is cornerRect.right && cornerRect.top !is cornerRect.bottom) {
+                    auto hDC = OS.GetWindowDC (hwnd);
+                    OS.FillRect (hDC, &cornerRect, cast(HANDLE)( OS.COLOR_BTNFACE + 1));
+                    Decorations shell = menuShell ();
+                    if ((shell.style & DWT.RESIZE) !is 0) {
+                        auto hwndScroll = shell.scrolledHandle ();
+                        bool drawGripper = hwnd is hwndScroll;
+                        if (!drawGripper) {
+                            RECT shellRect;
+                            OS.GetClientRect (hwndScroll, &shellRect);
+                            OS.MapWindowPoints (hwndScroll, null, cast(POINT*)&shellRect, 2);
+                            drawGripper = shellRect.right is windowRect.right && shellRect.bottom is windowRect.bottom;
+                        }
+                        if (drawGripper) {
+                            OS.DrawThemeBackground (display.hScrollBarTheme(), hDC, OS.SBP_SIZEBOX, 0, &cornerRect, null);
+                        }
+                    }
+                    OS.ReleaseDC (hwnd, hDC);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+LRESULT wmScroll (ScrollBar bar, bool update, HWND hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
     LRESULT result = null;
     if (update) {
         int type = msg is OS.WM_HSCROLL ? OS.SB_HORZ : OS.SB_VERT;
@@ -382,7 +466,7 @@
         info.fMask = OS.SIF_TRACKPOS | OS.SIF_POS | OS.SIF_RANGE;
         OS.GetScrollInfo (hwnd, type, &info);
         info.fMask = OS.SIF_POS;
-        int code = wParam & 0xFFFF;
+        int code = OS.LOWORD (wParam);
         switch (code) {
             case OS.SB_ENDSCROLL:  return null;
             case OS.SB_THUMBPOSITION:
@@ -419,7 +503,7 @@
         }
         OS.SetScrollInfo (hwnd, type, &info, true);
     } else {
-        int code = callWindowProc (hwnd, msg, wParam, lParam);
+        int /*long*/ code = callWindowProc (hwnd, msg, wParam, lParam);
         result = code is 0 ? LRESULT.ZERO : new LRESULT (code);
     }
     bar.wmScrollChild (wParam, lParam);