diff dwt/widgets/Link.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 b4846fd3437a
line wrap: on
line diff
--- a/dwt/widgets/Link.d	Mon May 05 00:12:38 2008 +0200
+++ b/dwt/widgets/Link.d	Sat May 17 17:34:28 2008 +0200
@@ -92,6 +92,34 @@
                 WNDCLASS lpWndClass;
                 OS.GetClassInfo (null, LinkClass.ptr, &lpWndClass);
                 LinkProc = lpWndClass.lpfnWndProc;
+            /*
+            * Feature in Windows.  The SysLink window class
+            * does not include CS_DBLCLKS.  This means that these
+            * controls will not get double click messages such as
+            * WM_LBUTTONDBLCLK.  The fix is to register a new
+            * window class with CS_DBLCLKS.
+            *
+            * NOTE:  Screen readers look for the exact class name
+            * of the control in order to provide the correct kind
+            * of assistance.  Therefore, it is critical that the
+            * new window class have the same name.  It is possible
+            * to register a local window class with the same name
+            * as a global class.  Since bits that affect the class
+            * are being changed, it is possible that other native
+            * code, other than DWT, could create a control with
+            * this class name, and fail unexpectedly.
+            */
+            auto hInstance = OS.GetModuleHandle (null);
+            auto hHeap = OS.GetProcessHeap ();
+            lpWndClass.hInstance = hInstance;
+            lpWndClass.style &= ~OS.CS_GLOBALCLASS;
+            lpWndClass.style |= OS.CS_DBLCLKS;
+            int byteCount = LinkClass.length * TCHAR.sizeof;
+            auto lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+            OS.MoveMemory (lpszClassName, LinkClass.ptr, byteCount);
+            lpWndClass.lpszClassName = lpszClassName;
+            OS.RegisterClass (&lpWndClass);
+            OS.HeapFree (hHeap, 0, lpszClassName);
             } else {
                 LinkProc = null;
             }
@@ -165,7 +193,24 @@
 
 override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) {
     if (handle is null) return 0;
-    if (LinkProc !is null) return OS.CallWindowProc (LinkProc, hwnd, msg, wParam, lParam);
+    if (LinkProc !is null) {
+        /*
+        * Feature in Windows.  By convention, native Windows controls
+        * check for a non-NULL wParam, assume that it is an HDC and
+        * paint using that device.  The SysLink control does not.
+        * The fix is to check for an HDC and use WM_PRINTCLIENT.
+        */
+        switch (msg) {
+            case OS.WM_PAINT:
+                if (wParam !is 0) {
+                    OS.SendMessage (hwnd, OS.WM_PRINTCLIENT, wParam, 0);
+                    return 0;
+                }
+                break;
+            default:
+        }
+        return OS.CallWindowProc (LinkProc, hwnd, msg, wParam, lParam);
+    }
     return OS.DefWindowProc (hwnd, msg, wParam, lParam);
 }
 
@@ -178,16 +223,23 @@
         auto hDC = OS.GetDC (handle);
         auto newFont = cast(HFONT) OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
         auto oldFont = OS.SelectObject (hDC, newFont);
-        TCHAR[] buffer = StrToTCHARs (getCodePage (), parse (text));
-        RECT rect;
-        int flags = OS.DT_CALCRECT | OS.DT_NOPREFIX;
-        if (wHint !is DWT.DEFAULT) {
-            flags |= OS.DT_WORDBREAK;
-            rect.right = wHint;
+        if (text.length > 0) {
+            TCHAR[] buffer = StrToTCHARs (getCodePage (), parse (text));
+            RECT rect;
+            int flags = OS.DT_CALCRECT | OS.DT_NOPREFIX;
+            if (wHint !is DWT.DEFAULT) {
+                flags |= OS.DT_WORDBREAK;
+                rect.right = wHint;
+            }
+            OS.DrawText (hDC, buffer.ptr, buffer.length, &rect, flags);
+            width = rect.right - rect.left;
+            height = rect.bottom;
+        } else {
+            TEXTMETRIC lptm;
+            OS.GetTextMetrics (hDC, &lptm);
+            width = 0;
+            height = lptm.tmHeight;
         }
-        OS.DrawText (hDC, buffer.ptr, buffer.length, &rect, flags);
-        width = rect.right - rect.left;
-        height = rect.bottom;
         if (newFont !is null) OS.SelectObject (hDC, oldFont);
         OS.ReleaseDC (handle, hDC);
     } else {
@@ -527,7 +579,7 @@
     }
     if (start < length_) {
         int tmp = parseMnemonics (buffer, start, tagStart, result);
-        int mnemonic = parseMnemonics (buffer, linkStart, index, result);
+        int mnemonic = parseMnemonics (buffer, Math.max (tagStart, linkStart), length_, result);
         if (mnemonic is -1) mnemonic = tmp;
         mnemonics [linkIndex] = mnemonic;
     } else {
@@ -726,7 +778,7 @@
                 * This allows the application to cancel an operation that is normally
                 * performed in WM_KEYDOWN from WM_CHAR.
                 */
-                int code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam);
+                int /*long*/ code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam);
                 return new LRESULT (code);
             default:
         }
@@ -738,7 +790,8 @@
 override LRESULT WM_GETDLGCODE (int wParam, int lParam) {
     LRESULT result = super.WM_GETDLGCODE (wParam, lParam);
     if (result !is null) return result;
-    int index, count, code = 0;
+    int index, count;
+    int /*long*/ code = 0;
     if (OS.COMCTL32_MAJOR >= 6) {
         LITEM item;
         item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
@@ -772,7 +825,7 @@
 override LRESULT WM_GETFONT (int wParam, int lParam) {
     LRESULT result = super.WM_GETFONT (wParam, lParam);
     if (result !is null) return result;
-    int code = callWindowProc (handle, OS.WM_GETFONT, wParam, lParam);
+    int /*long*/ code = callWindowProc (handle, OS.WM_GETFONT, wParam, lParam);
     if (code !is 0) return new LRESULT (code);
     if (font is null) font = defaultFont ();
     return new LRESULT ( cast(int) font);
@@ -810,8 +863,8 @@
     if (result is LRESULT.ZERO) return result;
     if (OS.COMCTL32_MAJOR < 6) {
         if (focusIndex !is -1) setFocus ();
-        int x = lParam & 0xFFFF;
-        int y = lParam >> 16;
+        int x = OS.GET_X_LPARAM (lParam);
+        int y = OS.GET_Y_LPARAM (lParam);
         int offset = layout.getOffset (x, y, null);
         int oldSelectionX = selection.x;
         int oldSelectionY = selection.y;
@@ -848,8 +901,8 @@
     if (result is LRESULT.ZERO) return result;
     if (OS.COMCTL32_MAJOR < 6) {
         if (mouseDownIndex is -1) return result;
-        int x = lParam & 0xFFFF;
-        int y = lParam >> 16;
+        int x = OS.GET_X_LPARAM (lParam);
+        int y = OS.GET_Y_LPARAM (lParam);
         Rectangle [] rects = getRectangles (mouseDownIndex);
         for (int i = 0; i < rects.length; i++) {
             Rectangle rect = rects [i];
@@ -865,11 +918,25 @@
     return result;
 }
 
+override LRESULT WM_NCHITTEST (int wParam, int lParam) {
+    LRESULT result = super.WM_NCHITTEST (wParam, lParam);
+    if (result !is null) return result;
+
+    /*
+    * Feature in Windows. For WM_NCHITTEST, the Syslink window proc
+    * returns HTTRANSPARENT when mouse is over plain text. The fix is
+    * to always return HTCLIENT.
+    */
+    if (OS.COMCTL32_MAJOR >= 6) return new LRESULT (OS.HTCLIENT);
+
+    return result;
+}
+
 override LRESULT WM_MOUSEMOVE (int wParam, int lParam) {
     LRESULT result = super.WM_MOUSEMOVE (wParam, lParam);
     if (OS.COMCTL32_MAJOR < 6) {
-        int x = lParam & 0xFFFF;
-        int y = lParam >> 16;
+        int x = OS.GET_X_LPARAM (lParam);
+        int y = OS.GET_Y_LPARAM (lParam);
         if (OS.GetKeyState (OS.VK_LBUTTON) < 0) {
             int oldSelection = selection.y;
             selection.y = layout.getOffset (x, y, null);