Mercurial > projects > dwt-win
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);