Mercurial > projects > dwt-win
diff dwt/widgets/Button.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 | 43b41c7fe84a |
line wrap: on
line diff
--- a/dwt/widgets/Button.d Mon May 05 00:12:38 2008 +0200 +++ b/dwt/widgets/Button.d Sat May 17 17:34:28 2008 +0200 @@ -63,7 +63,7 @@ String text = "", message = ""; Image image, image2, disabledImage; ImageList imageList; - bool ignoreMouse; + bool ignoreMouse, grayed; static const int MARGIN = 4; private static /+const+/ int CHECK_WIDTH, CHECK_HEIGHT; static const int ICON_WIDTH = 128, ICON_HEIGHT = 128; @@ -504,8 +504,36 @@ } override void createHandle () { + /* + * Feature in Windows. When a button is created, + * it clears the UI state for all controls in the + * shell by sending WM_CHANGEUISTATE with UIS_SET, + * UISF_HIDEACCEL and UISF_HIDEFOCUS to the parent. + * This is undocumented and unexpected. The fix + * is to ignore the WM_CHANGEUISTATE, when sent + * from CreateWindowEx(). + */ + parent.state |= IGNORE_WM_CHANGEUISTATE; super.createHandle (); - if ((style & DWT.PUSH) is 0) state |= THEME_BACKGROUND; + parent.state &= ~IGNORE_WM_CHANGEUISTATE; + + /* Set the theme background */ + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + /* + * NOTE: On Vista this causes problems when the tab + * key is pressed for push buttons so disable the + * theme background drawing for these widgets for + * now. + */ + if (!OS.IsWinCE && OS.WIN32_VERSION < OS.VERSION (6, 0)) { + state |= THEME_BACKGROUND; + } else { + if ((style & (DWT.PUSH | DWT.TOGGLE)) is 0) { + state |= THEME_BACKGROUND; + } + } + } + /* * Bug in Windows. For some reason, the HBRUSH that * is returned from WM_CTRLCOLOR is misaligned when @@ -521,6 +549,23 @@ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { if ((style & DWT.RADIO) !is 0) state |= DRAW_BACKGROUND; } + + /* + * Feature in Windows. Push buttons draw border around + * the button using the default background color instead + * of using the color provided by WM_CTRLCOLOR. The fix + * is to draw the background in WM_CTRLCOLOR. + * + * NOTE: On Vista this causes problems when the tab key + * is pressed for push buttons so disable the fix for now. + */ + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + if (!OS.IsWinCE && OS.WIN32_VERSION < OS.VERSION (6, 0)) { + if ((style & (DWT.PUSH | DWT.TOGGLE)) !is 0) { + state |= DRAW_BACKGROUND; + } + } + } } override int defaultBackground () { @@ -625,6 +670,24 @@ } /** + * Returns <code>true</code> if the receiver is grayed, + * and false otherwise. When the widget does not have + * the <code>CHECK</code> style, return false. + * + * @return the grayed state of the checkbox + * + * @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> + */ +public bool getGrayed () { + checkWidget(); + if ((style & DWT.CHECK) is 0) return false; + return grayed; +} + +/** * Returns the receiver's image if it has one, or null * if it does not. * @@ -682,8 +745,8 @@ public bool getSelection () { checkWidget (); if ((style & (DWT.CHECK | DWT.RADIO | DWT.TOGGLE)) is 0) return false; - int state = OS.SendMessage (handle, OS.BM_GETCHECK, 0, 0); - return (state & OS.BST_CHECKED) !is 0; + int /*long*/ flags = OS.SendMessage (handle, OS.BM_GETCHECK, 0, 0); + return flags !is OS.BST_UNCHECKED; } /** @@ -705,8 +768,7 @@ } override bool isTabItem () { - //TEMPORARY CODE - //if ((style & DWT.PUSH) !is 0) return true; + if ((style & DWT.PUSH) !is 0) return isTabGroup (); return super.isTabItem (); } @@ -728,6 +790,20 @@ return CharacterToUpper (key) is CharacterToUpper (mnemonic); } +void printWidget (HWND hwnd, HDC hDC) { + /* + * Bug in Windows. For some reason, PrintWindow() fails + * when it is called on a push button. The fix is to + * detect the failure and use WM_PRINT instead. Note + * that WM_PRINT cannot be used all the time because it + * fails for browser controls when the browser has focus. + */ + if (!OS.PrintWindow (hwnd, hDC, 0)) { + int flags = OS.PRF_CLIENT | OS.PRF_NONCLIENT | OS.PRF_ERASEBKGND | OS.PRF_CHILDREN; + OS.SendMessage (hwnd, OS.WM_PRINT, hDC, flags); + } +} + override void releaseWidget () { super.releaseWidget (); if (imageList !is null) imageList.dispose (); @@ -906,6 +982,30 @@ } /** + * Sets the grayed state of the receiver. This state change + * only applies if the control was created with the DWT.CHECK + * style. + * + * @param grayed the new grayed 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> + */ +public void setGrayed (bool grayed) { + checkWidget (); + if ((style & DWT.CHECK) is 0) return; + this.grayed = grayed; + int /*long*/ flags = OS.SendMessage (handle, OS.BM_GETCHECK, 0, 0); + if (grayed) { + if (flags is OS.BST_CHECKED) updateSelection (OS.BST_INDETERMINATE); + } else { + if (flags is OS.BST_INDETERMINATE) updateSelection (OS.BST_CHECKED); + } +} + +/** * Sets the widget message. When the widget is created * with the style <code>DWT.COMMAND</code>, the message text * is displayed to provide further information for the user. @@ -980,16 +1080,10 @@ checkWidget (); if ((style & (DWT.CHECK | DWT.RADIO | DWT.TOGGLE)) is 0) return; int flags = selected ? OS.BST_CHECKED : OS.BST_UNCHECKED; - /* - * Feature in Windows. When BM_SETCHECK is used - * to set the checked state of a radio or check - * button, it sets the WM_TABSTOP style. This - * is undocumented and unwanted. The fix is - * to save and restore the window style bits. - */ - int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); - OS.SendMessage (handle, OS.BM_SETCHECK, flags, 0); - OS.SetWindowLong (handle, OS.GWL_STYLE, bits); + if ((style & DWT.CHECK) !is 0) { + if (selected && grayed) flags = OS.BST_INDETERMINATE; + } + updateSelection (flags); } /** @@ -1038,6 +1132,35 @@ _setText (string); } +void updateSelection (int flags) { + if (flags !is OS.SendMessage (handle, OS.BM_GETCHECK, 0, 0)) { + /* + * Feature in Windows. When BM_SETCHECK is used + * to set the checked state of a radio or check + * button, it sets the WM_TABSTOP style. This + * is undocumented and unwanted. The fix is + * to save and restore the window style bits. + */ + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + if ((style & DWT.CHECK) !is 0) { + if (flags is OS.BST_INDETERMINATE) { + bits &= ~OS.BS_CHECKBOX; + bits |= OS.BS_3STATE; + } else { + bits |= OS.BS_CHECKBOX; + bits &= ~OS.BS_3STATE; + } + if (bits !is OS.GetWindowLong (handle, OS.GWL_STYLE)) { + OS.SetWindowLong (handle, OS.GWL_STYLE, bits); + } + } + OS.SendMessage (handle, OS.BM_SETCHECK, flags, 0); + if (bits !is OS.GetWindowLong (handle, OS.GWL_STYLE)) { + OS.SetWindowLong (handle, OS.GWL_STYLE, bits); + } + } +} + override int widgetStyle () { int bits = super.widgetStyle (); if ((style & DWT.FLAT) !is 0) bits |= OS.BS_FLAT; @@ -1184,7 +1307,7 @@ } if (redraw) { OS.InvalidateRect (handle, null, false); - int code = OS.DefWindowProc (handle, OS.WM_UPDATEUISTATE, wParam, lParam); + int /*long*/ code = OS.DefWindowProc (handle, OS.WM_UPDATEUISTATE, wParam, lParam); return new LRESULT (code); } } @@ -1193,7 +1316,7 @@ } override LRESULT wmCommandChild (int wParam, int lParam) { - int code = wParam >> 16; + int code = OS.HIWORD (wParam); switch (code) { case OS.BN_CLICKED: case OS.BN_DOUBLECLICKED: