diff dwt/widgets/Combo.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 a8fed3e56433
line wrap: on
line diff
--- a/dwt/widgets/Combo.d	Mon May 05 00:12:38 2008 +0200
+++ b/dwt/widgets/Combo.d	Sat May 17 17:34:28 2008 +0200
@@ -78,7 +78,7 @@
     alias Composite.setToolTipText setToolTipText;
 
     private static Combo pThis;
-    bool noSelection, ignoreDefaultSelection, ignoreCharacter, ignoreModify;
+    bool noSelection, ignoreDefaultSelection, ignoreCharacter, ignoreModify, ignoreResize;
     HHOOK cbtHook;
     int scrollWidth, visibleCount = 5;
 
@@ -321,6 +321,14 @@
 override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) {
     if (handle is null) return 0;
     if (hwnd is handle) {
+        switch (msg) {
+            case OS.WM_SIZE: {
+                ignoreResize = true;
+                int /*long*/ result = OS.CallWindowProc (ComboProc, hwnd, msg, wParam, lParam);
+                ignoreResize = false;
+                return result;
+            }
+        }
         return OS.CallWindowProc( ComboProc, hwnd, msg, wParam, lParam);
     }
     auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
@@ -462,8 +470,8 @@
     } else {
         auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
         if (hwndText !is null) {
-            int margins = OS.SendMessage (hwndText, OS.EM_GETMARGINS, 0, 0);
-            int marginWidth = (margins & 0xFFFF) + ((margins >> 16) & 0xFFFF);
+            int /*long*/ margins = OS.SendMessage (hwndText, OS.EM_GETMARGINS, 0, 0);
+            int marginWidth = OS.LOWORD (margins) + OS.HIWORD (margins);
             width += marginWidth + 3;
         }
     }
@@ -537,11 +545,11 @@
     /* Get the text and list window procs */
     auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
     if (hwndText !is null && EditProc is null) {
-        EditProc = cast(WNDPROC) OS.GetWindowLong (hwndText, OS.GWL_WNDPROC);
+        EditProc = cast(WNDPROC) OS.GetWindowLongPtr (hwndText, OS.GWLP_WNDPROC);
     }
     auto hwndList = OS.GetDlgItem (handle, CBID_LIST);
     if (hwndList !is null && ListProc is null) {
-        ListProc = cast(WNDPROC) OS.GetWindowLong (hwndList, OS.GWL_WNDPROC);
+        ListProc = cast(WNDPROC) OS.GetWindowLongPtr (hwndList, OS.GWLP_WNDPROC);
     }
 
     /*
@@ -638,8 +646,8 @@
             int start, end;
             OS.SendMessage (handle, OS.CB_GETEDITSEL, &start, &end);
             if (start !is end ) {
-                int lParam = (x & 0xFFFF) | ((y << 16) & 0xFFFF0000);
-                int position = OS.SendMessage (hwndText, OS.EM_CHARFROMPOS, 0, lParam) & 0xFFFF;
+                int /*long*/ lParam = OS.MAKELPARAM (x, y);
+                int position = OS.LOWORD (OS.SendMessage (hwndText, OS.EM_CHARFROMPOS, 0, lParam));
                 if (start <= position && position < end ) {
                     if (super.dragDetect (hwnd, x, y, filter, detect, consume)) {
                         if (consume !is null) consume [0] = true;
@@ -759,9 +767,9 @@
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  * </ul>
  *
- * @since 3.3
+ * @since 3.4
  */
-/*public*/ bool getListVisible () {
+public bool getListVisible () {
     checkWidget ();
     if ((style & DWT.DROP_DOWN) !is 0) {
         return OS.SendMessage (handle, OS.CB_GETDROPPEDSTATE, 0, 0) !is 0;
@@ -774,6 +782,29 @@
 }
 
 /**
+ * Marks the receiver's list as visible if the argument is <code>true</code>,
+ * and marks it invisible otherwise.
+ * <p>
+ * If one of the receiver's ancestors is not visible or some
+ * other condition makes the receiver not visible, marking
+ * it visible may not actually cause it to be displayed.
+ * </p>
+ *
+ * @param visible the new visibility state
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.4
+ */
+public void setListVisible (bool visible) {
+    checkWidget ();
+    OS.SendMessage (handle, OS.CB_SHOWDROPDOWN, visible ? 1 : 0, 0);
+}
+
+/**
  * Returns the orientation of the receiver.
  *
  * @return the orientation style
@@ -1570,29 +1601,6 @@
 }
 
 /**
- * Marks the receiver's list as visible if the argument is <code>true</code>,
- * and marks it invisible otherwise.
- * <p>
- * If one of the receiver's ancestors is not visible or some
- * other condition makes the receiver not visible, marking
- * it visible may not actually cause it to be displayed.
- * </p>
- *
- * @param visible the new visibility state
- *
- * @exception DWTException <ul>
- *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- *
- * @since 3.3
- */
-/*public*/ void setListVisible (bool visible) {
-    checkWidget ();
-    OS.SendMessage (handle, OS.CB_SHOWDROPDOWN, visible ? 1 : 0, 0);
-}
-
-/**
  * Sets the orientation of the receiver, which must be one
  * of the constants <code>DWT.LEFT_TO_RIGHT</code> or <code>DWT.RIGHT_TO_LEFT</code>.
  * <p>
@@ -1778,7 +1786,7 @@
         start = wcsToMbcsPos (start);
         end = wcsToMbcsPos (end);
     }
-    int bits = (start & 0xFFFF) | ((end << 16) & 0xFFFF0000);
+    int /*long*/ bits = OS.MAKELPARAM (start, end);
     OS.SendMessage (handle, OS.CB_SETEDITSEL, 0, bits);
 }
 
@@ -1814,7 +1822,7 @@
     int limit = LIMIT;
     auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
     if (hwndText !is null) {
-        limit = OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0);
+        limit = OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
     }
     if (string.length  > limit) string = string.substring (0, limit);
     TCHAR* buffer = StrToTCHARz( string );
@@ -1893,11 +1901,11 @@
     auto newProc = display.windowProc;
     auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
     if (hwndText !is null) {
-        OS.SetWindowLong (hwndText, OS.GWL_WNDPROC, newProc);
+        OS.SetWindowLongPtr (hwndText, OS.GWLP_WNDPROC, newProc);
     }
     auto hwndList = OS.GetDlgItem (handle, CBID_LIST);
     if (hwndList !is null) {
-        OS.SetWindowLong (hwndList, OS.GWL_WNDPROC, newProc);
+        OS.SetWindowLongPtr (hwndList, OS.GWLP_WNDPROC, newProc);
     }
 }
 
@@ -1907,7 +1915,7 @@
     * to select an item in the list and escape to close
     * the combo box.
     */
-    switch (msg.wParam) {
+    switch ((msg.wParam)) {
         case OS.VK_RETURN:
         case OS.VK_ESCAPE:
             if ((style & DWT.DROP_DOWN) !is 0) {
@@ -1944,11 +1952,11 @@
     super.unsubclass ();
     auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
     if (hwndText !is null && EditProc !is null) {
-        OS.SetWindowLong (hwndText, OS.GWL_WNDPROC, cast(int) EditProc);
+        OS.SetWindowLongPtr (hwndText, OS.GWLP_WNDPROC, cast(LONG_PTR)EditProc);
     }
     auto hwndList = OS.GetDlgItem (handle, CBID_LIST);
     if (hwndList !is null && ListProc !is null) {
-        OS.SetWindowLong (hwndList, OS.GWL_WNDPROC, cast(int) ListProc);
+        OS.SetWindowLongPtr (hwndList, OS.GWLP_WNDPROC, cast(LONG_PTR)ListProc);
     }
 }
 
@@ -2107,7 +2115,7 @@
 }
 
 override LRESULT WM_GETDLGCODE (int wParam, int lParam) {
-    int code = callWindowProc (handle, OS.WM_GETDLGCODE, wParam, lParam);
+    int /*long*/ code = callWindowProc (handle, OS.WM_GETDLGCODE, wParam, lParam);
     return new LRESULT (code | OS.DLGC_WANTARROWS);
 }
 
@@ -2164,6 +2172,16 @@
 
 override LRESULT WM_SIZE (int wParam, int lParam) {
     /*
+    * Feature in Windows.  When a combo box is resized,
+    * the size of the drop down rectangle is specified
+    * using the height and then the combo box resizes
+    * to be the height of the text field.  This causes
+    * two WM_SIZE messages to be sent and two DWT.Resize
+    * events to be issued.  The fix is to ignore the
+    * second resize.
+    */
+    if (ignoreResize) return null;
+    /*
     * Bug in Windows.  If the combo box has the CBS_SIMPLE style,
     * the list portion of the combo box is not redrawn when the
     * combo box is resized.  The fix is to force a redraw when
@@ -2221,7 +2239,7 @@
         if (isDisposed ()) return result;
         if (buffer !is null) {
             OS.SetWindowText (handle, buffer.ptr);
-            int bits = (start & 0xFFFF) | ((end << 16) & 0xFFFF0000);
+            int /*long*/ bits = OS.MAKELPARAM (start, end);
             OS.SendMessage (handle, OS.CB_SETEDITSEL, 0, bits);
             if (redraw) setRedraw (true);
         }
@@ -2236,6 +2254,56 @@
     return result;
 }
 
+override LRESULT WM_WINDOWPOSCHANGING (int /*long*/ wParam, int /*long*/ lParam) {
+    LRESULT result = super.WM_WINDOWPOSCHANGING (wParam, lParam);
+    if (result !is null) return result;
+    /*
+    * Feature in Windows.  When a combo box is resized,
+    * the size of the drop down rectangle is specified
+    * using the height and then the combo box resizes
+    * to be the height of the text field.  This causes
+    * sibling windows that intersect with the original
+    * bounds to redrawn.  The fix is to stop the redraw
+    * using SWP_NOREDRAW and then damage the combo box
+    * text field and the area in the parent where the
+    * combo box used to be.
+    */
+    if (OS.IsWinCE) return result;
+    if (drawCount !is 0) return result;
+    if (!OS.IsWindowVisible (handle)) return result;
+    if (ignoreResize) {
+        WINDOWPOS* lpwp = cast(WINDOWPOS*)lParam;
+        if ((lpwp.flags & OS.SWP_NOSIZE) is 0) {
+            lpwp.flags |= OS.SWP_NOREDRAW;
+            OS.InvalidateRect (handle, null, true);
+            RECT rect;
+            OS.GetWindowRect (handle, &rect);
+            int width = rect.right - rect.left;
+            int height = rect.bottom - rect.top;
+            if (width !is 0 && height !is 0) {
+                auto hwndParent = parent.handle;
+                auto hwndChild = OS.GetWindow (hwndParent, OS.GW_CHILD);
+                OS.MapWindowPoints (null, hwndParent, cast(POINT*)&rect, 2);
+                auto rgn1 = OS.CreateRectRgn (rect.left, rect.top, rect.right, rect.bottom);
+                while (hwndChild !is null) {
+                    if (hwndChild !is handle) {
+                        OS.GetWindowRect (hwndChild, &rect);
+                        OS.MapWindowPoints (null, hwndParent, cast(POINT*)&rect, 2);
+                        auto rgn2 = OS.CreateRectRgn (rect.left, rect.top, rect.right, rect.bottom);
+                        OS.CombineRgn (rgn1, rgn1, rgn2, OS.RGN_DIFF);
+                        OS.DeleteObject (rgn2);
+                    }
+                    hwndChild = OS.GetWindow (hwndChild, OS.GW_HWNDNEXT);
+                }
+                int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
+                OS.RedrawWindow (hwndParent, null, rgn1, flags);
+                OS.DeleteObject (rgn1);
+            }
+        }
+    }
+    return result;
+}
+
 override LRESULT wmChar (HWND hwnd, int wParam, int lParam) {
     if (ignoreCharacter) return null;
     LRESULT result = super.wmChar (hwnd, wParam, lParam);
@@ -2345,7 +2413,7 @@
 }
 
 override LRESULT wmCommandChild (int wParam, int lParam) {
-    int code = wParam >> 16;
+    int code = OS.HIWORD (wParam);
     switch (code) {
         case OS.CBN_EDITCHANGE:
             if (ignoreModify) break;
@@ -2429,7 +2497,7 @@
     * them to the application.
     */
     ignoreCharacter = true;
-    int result = callWindowProc (hwnd, OS.WM_IME_CHAR, wParam, lParam);
+    int /*long*/ result = callWindowProc (hwnd, OS.WM_IME_CHAR, wParam, lParam);
     MSG msg;
     int flags = OS.PM_REMOVE | OS.PM_NOYIELD | OS.PM_QS_INPUT | OS.PM_QS_POSTMESSAGE;
     while (OS.PeekMessage (&msg, hwnd, OS.WM_CHAR, OS.WM_CHAR, flags)) {
@@ -2472,7 +2540,7 @@
     if (result !is null) return result;
     if ((style & DWT.READ_ONLY) is 0) {
         if (wParam is OS.VK_DOWN) {
-            int code = callWindowProc (hwnd, OS.WM_SYSKEYDOWN, wParam, lParam);
+            int /*long*/ code = callWindowProc (hwnd, OS.WM_SYSKEYDOWN, wParam, lParam);
             int newSelection = OS.SendMessage (handle, OS.CB_GETCURSEL, 0, 0);
             if (oldSelection !is newSelection) {
                 sendEvent (DWT.Modify);