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