diff options
author | Steve Northover <steve> | 2005-10-28 19:23:05 +0000 |
---|---|---|
committer | Steve Northover <steve> | 2005-10-28 19:23:05 +0000 |
commit | e38d4aec3f79c42ea6666a7a37c026187a8aa6ea (patch) | |
tree | 88f34e7cad76263c1d87c17fa20c1eee6a11d4fc /bundles/org.eclipse.swt | |
parent | c63ca636edfbea4cd55ccc07da414186be375ce0 (diff) | |
download | eclipse.platform.swt-e38d4aec3f79c42ea6666a7a37c026187a8aa6ea.tar.gz eclipse.platform.swt-e38d4aec3f79c42ea6666a7a37c026187a8aa6ea.tar.xz eclipse.platform.swt-e38d4aec3f79c42ea6666a7a37c026187a8aa6ea.zip |
29994 - Image background Composite / Transparent widget backgrounds (/*public*/)
Diffstat (limited to 'bundles/org.eclipse.swt')
16 files changed, 977 insertions, 342 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java index bcc365d2a2..36a31ebf72 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java @@ -220,6 +220,7 @@ public class OS extends Platform { public static final int BS_LEFT = 0x100; public static final int BS_NOTIFY = 0x4000; public static final int BS_OWNERDRAW = 0xb; + public static final int BS_PATTERN = 0x3; public static final int BS_PUSHBUTTON = 0x0; public static final int BS_PUSHLIKE = 0x1000; public static final int BS_RADIOBUTTON = 0x4; @@ -1394,6 +1395,8 @@ public class OS extends Platform { public static final int UDS_AUTOBUDDY = 0x0010; public static final int UDS_WRAP = 0x0001; public static final int UIS_INITIALIZE = 3; + public static final int UISF_HIDEACCEL = 0x2; + public static final int UISF_HIDEFOCUS = 0x1; public static final String UPDOWN_CLASS = "msctls_updown32"; //$NON-NLS-1$ public static final int USP_E_SCRIPT_NOT_IN_FONT = 0x80040200; public static final int VERTRES = 0xa; @@ -1553,6 +1556,7 @@ public class OS extends Platform { public static final int WM_QUERYENDSESSION = 0x11; public static final int WM_QUERYNEWPALETTE = 0x30f; public static final int WM_QUERYOPEN = 0x13; + public static final int WM_QUERYUISTATE = 0x129; public static final int WM_RBUTTONDBLCLK = 0x206; public static final int WM_RBUTTONDOWN = 0x204; public static final int WM_RBUTTONUP = 0x205; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java index 691ecaa36e..b7bfd7bf64 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java @@ -454,6 +454,9 @@ public Point computeSize (int wHint, int hHint, boolean changed) { void createHandle () { super.createHandle (); state |= TRANSPARENT; + if (OS.COMCTL32_MAJOR >= 6) { + if ((style & SWT.RADIO) != 0) state |= DRAW_BACKGROUND; + } } int defaultBackground () { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java index 9848481035..c6e1f9c5d0 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java @@ -159,23 +159,41 @@ public void scroll (int destX, int destY, int x, int y, int width, int height, b } } int deltaX = destX - x, deltaY = destY - y; - int flags = OS.SW_INVALIDATE | OS.SW_ERASE; - /* - * Feature in Windows. If any child in the widget tree partially - * intersects the scrolling rectangle, Windows moves the child - * and copies the bits that intersect the scrolling rectangle but - * does not redraw the child. - * - * Feature in Windows. When any child in the widget tree does not - * intersect the scrolling rectangle but the parent does intersect, - * Windows does not move the child. This is the documented (but - * strange) Windows behavior. - * - * The fix is to not use SW_SCROLLCHILDREN and move the children - * explicitly after scrolling. - */ -// if (all) flags |= OS.SW_SCROLLCHILDREN; - OS.ScrollWindowEx (handle, deltaX, deltaY, sourceRect, null, 0, null, flags); + if (backgroundImage != null) { + if (OS.IsWinCE) { + OS.InvalidateRect (handle, sourceRect, true); + } else { + int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE; + if (all) flags |= OS.RDW_ALLCHILDREN; + OS.RedrawWindow (handle, sourceRect, 0, flags); + } + OS.OffsetRect (sourceRect, deltaX, deltaY); + if (OS.IsWinCE) { + OS.InvalidateRect (handle, sourceRect, true); + } else { + int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE; + if (all) flags |= OS.RDW_ALLCHILDREN; + OS.RedrawWindow (handle, sourceRect, 0, flags); + } + } else { + int flags = OS.SW_INVALIDATE | OS.SW_ERASE; + /* + * Feature in Windows. If any child in the widget tree partially + * intersects the scrolling rectangle, Windows moves the child + * and copies the bits that intersect the scrolling rectangle but + * does not redraw the child. + * + * Feature in Windows. When any child in the widget tree does not + * intersect the scrolling rectangle but the parent does intersect, + * Windows does not move the child. This is the documented (but + * strange) Windows behavior. + * + * The fix is to not use SW_SCROLLCHILDREN and move the children + * explicitly after scrolling. + */ +// if (all) flags |= OS.SW_SCROLLCHILDREN; + OS.ScrollWindowEx (handle, deltaX, deltaY, sourceRect, null, 0, null, flags); + } if (all) { Control [] children = _getChildren (); for (int i=0; i<children.length; i++) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java index beb13d05f7..f23ba34598 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Composite.java @@ -240,6 +240,27 @@ void createHandle () { } } +/*public*/ void drawBackground (GC gc, int id, int x, int y, int width, int height) { + checkWidget (); + if (gc == null) error (SWT.ERROR_NULL_ARGUMENT); + if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); + int pixel = -1; + switch (id) { + case SWT.COLOR_LIST_BACKGROUND: + pixel = OS.GetSysColor (OS.COLOR_WINDOW); + break; + case SWT.COLOR_INFO_BACKGROUND: + pixel = OS.GetSysColor (OS.COLOR_INFOBK); + break; + case SWT.COLOR_WIDGET_BACKGROUND: + pixel = OS.GetSysColor (OS.COLOR_3DFACE); + break; + } + RECT rect = new RECT (); + OS.SetRect (rect, x, y, x + width, y + height); + drawBackground (gc.handle, rect, pixel); +} + Composite findDeferredControl () { return layoutCount > 0 ? this : parent.findDeferredControl (); } @@ -1292,8 +1313,12 @@ LRESULT WM_SIZE (int wParam, int lParam) { } } } - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - if (findThemeControl () != null) redrawChildren (); + if (backgroundImage != null) { + redrawChildren (); + } else { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + if (findThemeControl () != null) redrawChildren (); + } } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java index 05a86f1109..7a4bf16af9 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java @@ -55,6 +55,7 @@ public abstract class Control extends Widget implements Drawable { String toolTipText; Object layoutData; Accessible accessible; + Image backgroundImage; int drawCount, foreground, background; /** @@ -97,6 +98,11 @@ public Control (Composite parent, int style) { createWidget (); } +void _setBackgroundImage (Image image) { + backgroundImage = image; + redrawChildren (); +} + /** * Adds the listener to the collection of listeners who will * be notified when the control is moved or resized, by sending @@ -534,28 +540,28 @@ void drawBackground (int hDC) { drawBackground (hDC, rect); } -void drawBackground (int hDC, int pixel, RECT rect) { - Control control = null; - if ((state & TRANSPARENT) != 0) { - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - control = findThemeControl (); - } - } - if (control == null) { - int hPalette = display.hPalette; - if (hPalette != 0) { - OS.SelectPalette (hDC, hPalette, false); - OS.RealizePalette (hDC); - } - int hBrush = findBrush (pixel); - OS.FillRect (hDC, rect, hBrush); - } else { - control.drawThemeBackground (hDC, handle, rect); - } +void drawBackground (int hDC, RECT rect) { + drawBackground (hDC, rect, -1); } -void drawBackground (int hDC, RECT rect) { - drawBackground (hDC, getBackgroundPixel (), rect); +void drawBackground (int hDC, RECT rect, int pixel) { + if (backgroundImage != null) { + fillBackground (hDC, backgroundImage, rect); + } else { + if (background == -1) { + if ((state & TRANSPARENT) != 0) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + Control control = findThemeControl (); + if (control != null) { + fillBackground (hDC, control, rect); + return; + } + } + } + } + if (pixel == -1) pixel = getBackgroundPixel (); + fillBackground (hDC, pixel, rect); + } } void drawThemeBackground (int hDC, int hwnd, RECT rect) { @@ -566,8 +572,49 @@ void enableWidget (boolean enabled) { OS.EnableWindow (handle, enabled); } -int findBrush (int pixel) { - return parent.findBrush (pixel); +void fillBackground (int hDC, Control control, RECT rect) { + if (control == null) return; + control.drawThemeBackground (hDC, handle, rect); +} + +void fillBackground (int hDC, Image image, RECT rect) { + Control control = findImageControl (image); + if (control != null) { + int hwnd = control.handle; + int hBitmap = image.handle; + RECT rect2 = new RECT (); + OS.GetClientRect (handle, rect2); + OS.MapWindowPoints (handle, hwnd, rect2, 2); + int hBrush = findBrush (hBitmap, OS.BS_PATTERN); + POINT lpPoint = new POINT (); + OS.GetWindowOrgEx (hDC, lpPoint); + OS.SetBrushOrgEx (hDC, -rect2.left - lpPoint.x, -rect2.top - lpPoint.y, lpPoint); + int hOldBrush = OS.SelectObject (hDC, hBrush); + OS.PatBlt (hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY); + OS.SetBrushOrgEx (hDC, lpPoint.x, lpPoint.y, null); + OS.SelectObject (hDC, hOldBrush); + } +} + +void fillBackground (int hDC, int pixel, RECT rect) { + int hPalette = display.hPalette; + if (hPalette != 0) { + OS.SelectPalette (hDC, hPalette, false); + OS.RealizePalette (hDC); + } + OS.FillRect (hDC, rect, findBrush (pixel, OS.BS_SOLID)); +} + +Control findImageControl (Image image) { + if (backgroundImage != null && backgroundImage == image) { + Control control = parent.findImageControl (image); + return control == null ? this : control; + } + return null; +} + +int findBrush (int value, int lbStyle) { + return parent.findBrush (value, lbStyle); } Cursor findCursor () { @@ -576,7 +623,7 @@ Cursor findCursor () { } Control findThemeControl () { - return background == -1 ? parent.findThemeControl () : null; + return background == -1 && backgroundImage == null ? parent.findThemeControl () : null; } Menu [] findMenus (Control control) { @@ -714,6 +761,22 @@ public Color getBackground () { checkWidget (); return Color.win32_new (display, getBackgroundPixel ()); } +/** + * Returns the receiver's background image. + * + * @return the background image + * + * @exception SWTException <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.2 + */ +/*public*/ Image getBackgroundImage () { + checkWidget (); + return backgroundImage; +} int getBackgroundPixel () { if (background == -1) return defaultBackground (); @@ -1562,13 +1625,15 @@ public void redraw (int x, int y, int width, int height, boolean all) { } boolean redrawChildren () { - if (background == -1) { - if ((state & TRANSPARENT) != 0) { + if (!OS.IsWindowVisible (handle)) return false; + if (backgroundImage != null) { + OS.InvalidateRect (handle, null, true); + return true; + } else { + if ((state & TRANSPARENT) != 0 && background == -1) { if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - if (OS.IsWindowVisible (handle)) { - OS.InvalidateRect (handle, null, true); - return true; - } + OS.InvalidateRect (handle, null, true); + return true; } } } @@ -1906,6 +1971,34 @@ public void setBackground (Color color) { setBackgroundPixel (pixel); } +/** + * Sets the receiver's background image to the image specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param image the new image (or null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> + * <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li> + * </ul> + * @exception SWTException <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.2 + */ +/*public*/ void setBackgroundImage (Image image) { + checkWidget (); + if (image != null) { + if (image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); + if (image.type != SWT.BITMAP) error (SWT.ERROR_INVALID_ARGUMENT); + } + if (backgroundImage == image) return; + _setBackgroundImage (image); +} + void setBackgroundPixel (int pixel) { if (background == pixel) return; background = pixel; @@ -1954,18 +2047,11 @@ void setBounds (int x, int y, int width, int height, int flags, boolean defer) { int topHandle = topHandle (); if (defer && parent != null) { forceResize (); + if (backgroundImage != null && OS.GetWindow (handle, OS.GW_CHILD) == 0) { + flags |= OS.SWP_NOCOPYBITS; + } WINDOWPOS [] lpwp = parent.lpwp; if (lpwp == null) { - /* - * This code is intentionally commented. All widgets that - * are created by SWT have WS_CLIPSIBLINGS to ensure that - * application code does not draw outside of the control. - */ -// int count = parent.getChildrenCount (); -// if (count > 1) { -// int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); -// if ((bits & OS.WS_CLIPSIBLINGS) == 0) flags |= OS.SWP_NOCOPYBITS; -// } SetWindowPos (topHandle, 0, x, y, width, height, flags); } else { int index = 0; @@ -3229,10 +3315,12 @@ LRESULT WM_ENTERIDLE (int wParam, int lParam) { } LRESULT WM_ERASEBKGND (int wParam, int lParam) { + if ((state & DRAW_BACKGROUND) != 0) { + if (backgroundImage != null) return LRESULT.ONE; + } if ((state & TRANSPARENT) != 0) { if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - Control control = findThemeControl (); - if (control != null) return LRESULT.ONE; + if (findThemeControl () != null) return LRESULT.ONE; } } return null; @@ -3553,10 +3641,14 @@ LRESULT WM_MOUSEWHEEL (int wParam, int lParam) { } LRESULT WM_MOVE (int wParam, int lParam) { - if ((state & TRANSPARENT) != 0) { - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - if (OS.IsWindowVisible (handle)) { - if (findThemeControl () != null) redrawChildren (); + if (backgroundImage != null) { + redrawChildren (); + } else { + if ((state & TRANSPARENT) != 0) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + if (OS.IsWindowVisible (handle)) { + if (findThemeControl () != null) redrawChildren (); + } } } } @@ -3871,13 +3963,18 @@ LRESULT WM_XBUTTONUP (int wParam, int lParam) { LRESULT wmColorChild (int wParam, int lParam) { Control control = null; - if ((state & TRANSPARENT) != 0) { - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - control = findThemeControl (); + if (backgroundImage != null) { + if ((state & TRANSPARENT) != 0) { + control = findImageControl (backgroundImage); } } - if (background == -1 && foreground == -1 && control == null) { - return null; + if (foreground == -1 && background == -1 && control == null) { + if ((state & TRANSPARENT) != 0) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + control = findThemeControl (); + } + } + if (control == null) return null; } int forePixel = foreground, backPixel = background; if (forePixel == -1) forePixel = defaultForeground (); @@ -3887,11 +3984,29 @@ LRESULT wmColorChild (int wParam, int lParam) { if (control != null) { RECT rect = new RECT (); OS.GetClientRect (handle, rect); - control.drawThemeBackground (wParam, handle, rect); - OS.SetBkMode (wParam, OS.TRANSPARENT); - return new LRESULT (OS.GetStockObject (OS.NULL_BRUSH)); + if (backgroundImage != null) { + int hwnd = control.handle; + int hBitmap = backgroundImage.handle; + OS.MapWindowPoints (handle, hwnd, rect, 2); + POINT lpPoint = new POINT (); + OS.GetWindowOrgEx (wParam, lpPoint); + OS.SetBrushOrgEx (wParam, -rect.left - lpPoint.x, -rect.top - lpPoint.y, lpPoint); + int hBrush = findBrush (hBitmap, OS.BS_PATTERN); + if ((state & DRAW_BACKGROUND) != 0) { + int hOldBrush = OS.SelectObject (wParam, hBrush); + OS.MapWindowPoints (hwnd, handle, rect, 2); + OS.PatBlt (wParam, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY); + OS.SelectObject (wParam, hOldBrush); + } + OS.SetBkMode (wParam, OS.TRANSPARENT); + return new LRESULT (hBrush); + } else { + fillBackground (wParam, control, rect); + OS.SetBkMode (wParam, OS.TRANSPARENT); + return new LRESULT (OS.GetStockObject (OS.NULL_BRUSH)); + } } - return new LRESULT (findBrush (backPixel)); + return new LRESULT (findBrush (backPixel, OS.BS_SOLID)); } LRESULT wmCommandChild (int wParam, int lParam) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoolBar.java index 9da431a684..a5ea4868ef 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoolBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/CoolBar.java @@ -360,6 +360,12 @@ void destroyItem (CoolItem item) { } void drawThemeBackground (int hDC, int hwnd, RECT rect) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + if (background == -1 && (style & SWT.FLAT) != 0) { + fillBackground (hDC, defaultBackground (), rect); + return; + } + } RECT rect2 = new RECT (); OS.GetClientRect (handle, rect2); OS.MapWindowPoints (handle, hwnd, rect2, 2); @@ -406,7 +412,7 @@ int getMargin (int index) { Control findThemeControl () { if ((style & SWT.FLAT) != 0) return this; - return background == -1 ? this : super.findThemeControl (); + return background == -1 && backgroundImage == null ? this : super.findThemeControl (); } /** @@ -998,8 +1004,6 @@ LRESULT WM_COMMAND (int wParam, int lParam) { LRESULT WM_ERASEBKGND (int wParam, int lParam) { LRESULT result = super.WM_ERASEBKGND (wParam, lParam); - if (result != null) return result; - /* * Feature in Windows. For some reason, Windows * does not fully erase the area that the cool bar @@ -1012,12 +1016,12 @@ LRESULT WM_ERASEBKGND (int wParam, int lParam) { * WM_ERASEBKGND. Therefore it is essential to run * the cool bar window proc after the background has * been erased. - * - * On XP, this work around is unnecessary because - * the background is drawn using NM_CUSTOMDRAW. */ - if (OS.COMCTL32_MAJOR < 6) drawBackground (wParam); - return null; + if (OS.COMCTL32_MAJOR < 6 || !OS.IsAppThemed ()) { + drawBackground (wParam); + return null; + } + return result; } LRESULT WM_NOTIFY (int wParam, int lParam) { @@ -1154,12 +1158,12 @@ LRESULT wmNotifyChild (int wParam, int lParam) { * in WM_ERASEBKGND. */ if (OS.COMCTL32_MAJOR < 6) break; - if (background != -1 || (style & SWT.FLAT) != 0) { + if (background != -1 || backgroundImage != null || (style & SWT.FLAT) != 0) { NMCUSTOMDRAW nmcd = new NMCUSTOMDRAW (); OS.MoveMemory (nmcd, lParam, NMCUSTOMDRAW.sizeof); switch (nmcd.dwDrawStage) { case OS.CDDS_PREERASE: - return new LRESULT (OS.CDRF_NOTIFYPOSTERASE); + return new LRESULT (OS.CDRF_SKIPDEFAULT | OS.CDRF_NOTIFYPOSTERASE); case OS.CDDS_POSTERASE: drawBackground (nmcd.hdc); break; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java index c12edee9ba..8b9557afed 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java @@ -189,6 +189,7 @@ public Rectangle computeTrim (int x, int y, int width, int height) { void createHandle () { super.createHandle (); + state |= DRAW_BACKGROUND; state &= ~CANVAS; } @@ -384,16 +385,19 @@ LRESULT WM_UPDATEUISTATE (int wParam, int lParam) { * NOTE: The DefWindowProc() must be called in order to * broadcast WM_UPDATEUISTATE message to the children. */ - if ((state & TRANSPARENT) != 0) { - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - Control control = findThemeControl (); - if (control != null) { - OS.InvalidateRect (handle, null, false); - int code = OS.DefWindowProc (handle, OS.WM_UPDATEUISTATE, wParam, lParam); - return new LRESULT (code); + boolean redraw = backgroundImage != null; + if (!redraw) { + if ((state & TRANSPARENT) != 0) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + redraw = findThemeControl () != null; } } } + if (redraw) { + OS.InvalidateRect (handle, null, false); + int code = OS.DefWindowProc (handle, OS.WM_UPDATEUISTATE, wParam, lParam); + return new LRESULT (code); + } return result; } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java index 1727e8faaa..522ff9a52f 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java @@ -40,6 +40,7 @@ import org.eclipse.swt.graphics.*; public class Label extends Control { String text = ""; Image image; + static final int MARGIN = 4; static final int LabelProc; static final TCHAR LabelClass = new TCHAR (0, "STATIC", true); static { @@ -105,8 +106,7 @@ static int checkStyle (int style) { public Point computeSize (int wHint, int hHint, boolean changed) { checkWidget (); - int width = 0, height = 0; - int border = getBorderWidth (); + int width = 0, height = 0, border = getBorderWidth (); if ((style & SWT.SEPARATOR) != 0) { int lineWidth = OS.GetSystemMetrics (OS.SM_CXBORDER); if ((style & SWT.HORIZONTAL) != 0) { @@ -119,49 +119,49 @@ public Point computeSize (int wHint, int hHint, boolean changed) { width += border * 2; height += border * 2; return new Point (width, height); } - int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); - boolean isImage = (bits & OS.SS_OWNERDRAW) == OS.SS_OWNERDRAW; - if (isImage) { - if (image != null) { - Rectangle rect = image.getBounds(); - width = rect.width; - height = rect.height; - } + if (image != null) { + Rectangle rect = image.getBounds(); + width = rect.width; + if (text.length () != 0) width += MARGIN; + height = rect.height; + } + int hDC = OS.GetDC (handle); + int newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); + int oldFont = OS.SelectObject (hDC, newFont); + int length = OS.GetWindowTextLength (handle); + if (length == 0) { + TEXTMETRIC tm = OS.IsUnicode ? (TEXTMETRIC) new TEXTMETRICW () : new TEXTMETRICA (); + OS.GetTextMetrics (hDC, tm); + height = Math.max (height, tm.tmHeight); } else { - int hDC = OS.GetDC (handle); - int newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); - int oldFont = OS.SelectObject (hDC, newFont); RECT rect = new RECT (); int flags = OS.DT_CALCRECT | OS.DT_EDITCONTROL | OS.DT_EXPANDTABS; if ((style & SWT.WRAP) != 0 && wHint != SWT.DEFAULT) { flags |= OS.DT_WORDBREAK; rect.right = wHint; } - int length = OS.GetWindowTextLength (handle); TCHAR buffer = new TCHAR (getCodePage (), length + 1); OS.GetWindowText (handle, buffer, length + 1); OS.DrawText (hDC, buffer, length, rect, flags); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - if (height == 0) { - TEXTMETRIC tm = OS.IsUnicode ? (TEXTMETRIC) new TEXTMETRICW () : new TEXTMETRICA (); - OS.GetTextMetrics (hDC, tm); - height = tm.tmHeight; - } - if (newFont != 0) OS.SelectObject (hDC, oldFont); - OS.ReleaseDC (handle, hDC); + width += rect.right - rect.left; + height = Math.max (height, rect.bottom - rect.top); } + if (newFont != 0) OS.SelectObject (hDC, oldFont); + OS.ReleaseDC (handle, hDC); if (wHint != SWT.DEFAULT) width = wHint; if (hHint != SWT.DEFAULT) height = hHint; - width += border * 2; height += border * 2; + width += border * 2; + height += border * 2; /* * Feature in WinCE PPC. Text labels have a trim * of one pixel wide on the right and left side. - * The fix is to increase the size. + * The fix is to increase the width to include + * this trim. */ if (OS.IsWinCE) { - //TEST ME - if (!isImage) width += 2; + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + boolean isOwnerDraw = (bits & OS.SS_OWNERDRAW) == OS.SS_OWNERDRAW; + if (!isOwnerDraw) width += 2; } return new Point (width, height); } @@ -365,19 +365,21 @@ public void setText (String string) { */ if (string.equals (text)) return; text = string; - int oldBits = OS.GetWindowLong (handle, OS.GWL_STYLE); - int newBits = oldBits & ~OS.SS_OWNERDRAW; - if ((style & SWT.LEFT) != 0) { - if ((style & SWT.WRAP) != 0) { - newBits |= OS.SS_LEFT; - } else { + int oldBits = OS.GetWindowLong (handle, OS.GWL_STYLE), newBits = oldBits; + if (image == null) { + newBits &= ~OS.SS_OWNERDRAW; + if ((style & SWT.LEFT) != 0) { + if ((style & SWT.WRAP) != 0) { + newBits |= OS.SS_LEFT; + } else { newBits |= OS.SS_LEFTNOWORDWRAP; + } + } + if ((style & SWT.CENTER) != 0) newBits |= OS.SS_CENTER; + if ((style & SWT.RIGHT) != 0) newBits |= OS.SS_RIGHT; + if (oldBits != newBits) { + OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); } - } - if ((style & SWT.CENTER) != 0) newBits |= OS.SS_CENTER; - if ((style & SWT.RIGHT) != 0) newBits |= OS.SS_RIGHT; - if (oldBits != newBits) { - OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); } string = Display.withCrLf (string); TCHAR buffer = new TCHAR (getCodePage (), string, true); @@ -450,17 +452,20 @@ LRESULT WM_UPDATEUISTATE (int wParam, int lParam) { * foreground and background. If any drawing happens in * WM_CTLCOLORBTN, it overwrites the contents of the control. * The fix is draw the static without drawing the background - * and avoid the group window proc. + * and avoid the static window proc. */ - if ((state & TRANSPARENT) != 0) { - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - Control control = findThemeControl (); - if (control != null) { - OS.InvalidateRect (handle, null, false); - return LRESULT.ZERO; + boolean redraw = backgroundImage != null; + if (!redraw) { + if ((state & TRANSPARENT) != 0) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + redraw = findThemeControl () != null; } } } + if (redraw) { + OS.InvalidateRect (handle, null, false); + return LRESULT.ZERO; + } return result; } @@ -483,28 +488,59 @@ LRESULT wmDrawChild (int wParam, int lParam) { OS.DrawEdge (struct.hDC, rect, flags, OS.BF_RIGHT); } } else { - if (image != null) { - GCData data = new GCData(); - data.device = display; - GC gc = GC.win32_new (struct.hDC, data); - int width = struct.right - struct.left; - int height = struct.bottom - struct.top; - if (width != 0 && height != 0) { - int x = 0, y = 0; - if ((style & SWT.CENTER) != 0) { - Rectangle rect = image.getBounds (); - x = Math.max (0, (width - rect.width) / 2); - } else { - if ((style & SWT.RIGHT) != 0) { - Rectangle rect = image.getBounds (); - x = width - rect.width; - } + int width = struct.right - struct.left; + int height = struct.bottom - struct.top; + if (width != 0 && height != 0) { + int imageWidth = 0, imageHeight = 0; + if (image != null) { + Rectangle rect = image.getBounds (); + imageWidth = rect.width; + imageHeight = rect.height; + } + RECT rect = null; + TCHAR buffer = null; + int textWidth = 0, textHeight = 0, flags = 0; + if (text.length () != 0) { + rect = new RECT (); + flags = OS.DT_CALCRECT | OS.DT_EDITCONTROL | OS.DT_EXPANDTABS; + if ((style & SWT.LEFT) != 0) flags |= OS.DT_LEFT; + if ((style & SWT.CENTER) != 0) flags |= OS.DT_CENTER; + if ((style & SWT.RIGHT) != 0) flags |= OS.DT_RIGHT; + if ((style & SWT.WRAP) != 0) { + flags |= OS.DT_WORDBREAK; + rect.right = Math.max (0, width - imageWidth - MARGIN); } + buffer = new TCHAR (getCodePage (), text, true); + OS.DrawText (struct.hDC, buffer, -1, rect, flags); + textWidth = rect.right - rect.left; + textHeight = rect.bottom - rect.top; + } + int x = 0; + if ((style & SWT.CENTER) != 0) { + x = Math.max (0, (width - imageWidth - textWidth - MARGIN) / 2); + } else { + if ((style & SWT.RIGHT) != 0) { + x = width - imageWidth - textWidth - MARGIN; + } + } + if (image != null) { + GCData data = new GCData(); + data.device = display; + GC gc = GC.win32_new (struct.hDC, data); Image drawnImage = getEnabled () ? image : new Image (display, image, SWT.IMAGE_DISABLE); - gc.drawImage (drawnImage, x, y); + gc.drawImage (drawnImage, x, Math.max (0, (height - imageHeight) / 2)); if (drawnImage != image) drawnImage.dispose (); + gc.dispose (); + x += imageWidth + MARGIN; + } + if (text.length () != 0) { + flags &= ~OS.DT_CALCRECT; + rect.left = x; + rect.right += rect.left; + rect.top = Math.max (0, (height - textHeight) / 2); + rect.bottom += rect.top; + OS.DrawText (struct.hDC, buffer, -1, rect, flags); } - gc.dispose (); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Scale.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Scale.java index d32f5d5cfc..f392a5ad14 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Scale.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Scale.java @@ -168,7 +168,7 @@ public Point computeSize (int wHint, int hHint, boolean changed) { void createHandle () { super.createHandle (); - state |= TRANSPARENT; + state |= TRANSPARENT | DRAW_BACKGROUND; OS.SendMessage (handle, OS.TBM_SETRANGEMAX, 0, 100); OS.SendMessage (handle, OS.TBM_SETPAGESIZE, 0, 10); OS.SendMessage (handle, OS.TBM_SETTICFREQ, 10, 0); @@ -424,18 +424,22 @@ LRESULT WM_PAINT (int wParam, int lParam) { * results. The fix is to send a fake WM_SIZE to force it * to redraw every time there is a WM_PAINT. */ - if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { - Control control = findThemeControl (); - if (control != null) { - boolean redraw = drawCount == 0 && OS.IsWindowVisible (handle); - if (redraw) OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); - ignoreResize = true; - OS.SendMessage (handle, OS.WM_SIZE, 0, 0); - ignoreResize = false; - if (redraw) { - OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); - OS.InvalidateRect (handle, null, true); - } + boolean fixPaint = backgroundImage != null; + if (!fixPaint) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + Control control = findThemeControl (); + fixPaint = control != null; + } + } + if (fixPaint) { + boolean redraw = drawCount == 0 && OS.IsWindowVisible (handle); + if (redraw) OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); + ignoreResize = true; + OS.SendMessage (handle, OS.WM_SIZE, 0, 0); + ignoreResize = false; + if (redraw) { + OS.SendMessage (handle, OS.WM_SETREDRAW, 1, 0); + OS.InvalidateRect (handle, null, true); } } return super.WM_PAINT (wParam, lParam); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java index a5adb4d699..5f8ed6b089 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java @@ -109,6 +109,15 @@ public class Shell extends Decorations { Region region; static final int DialogProc; static final TCHAR DialogClass = new TCHAR (0, OS.IsWinCE ? "Dialog" : "#32770", true); + final static int [] SYSTEM_COLORS = { + OS.COLOR_BTNFACE, + OS.COLOR_WINDOW, + OS.COLOR_BTNTEXT, + OS.COLOR_WINDOWTEXT, + OS.COLOR_HIGHLIGHT, + OS.COLOR_SCROLLBAR, + }; + final static int BRUSHES_SIZE = 32; static { WNDCLASS lpWndClass = new WNDCLASS (); OS.GetClassInfo (0, DialogClass, lpWndClass); @@ -514,33 +523,56 @@ void enableWidget (boolean enabled) { } } -int findBrush (int pixel) { - if (pixel == OS.GetSysColor (OS.COLOR_BTNFACE)) { - return OS.GetSysColorBrush (OS.COLOR_BTNFACE); - } - if (pixel == OS.GetSysColor (OS.COLOR_WINDOW)) { - return OS.GetSysColorBrush (OS.COLOR_WINDOW); +int findBrush (int value, int lbStyle) { + if (lbStyle == OS.BS_SOLID) { + for (int i=0; i<SYSTEM_COLORS.length; i++) { + if (value == OS.GetSysColor (SYSTEM_COLORS [i])) { + return OS.GetSysColorBrush (SYSTEM_COLORS [i]); + } + } } - if (brushes == null) brushes = new int [4]; + if (brushes == null) brushes = new int [BRUSHES_SIZE]; LOGBRUSH logBrush = new LOGBRUSH (); for (int i=0; i<brushes.length; i++) { int hBrush = brushes [i]; if (hBrush == 0) break; OS.GetObject (hBrush, LOGBRUSH.sizeof, logBrush); - if (logBrush.lbColor == pixel) return hBrush; + switch (logBrush.lbStyle) { + case OS.BS_SOLID: + if (lbStyle == OS.BS_SOLID) { + if (logBrush.lbColor == value) return hBrush; + } + break; + case OS.BS_PATTERN: + if (lbStyle == OS.BS_PATTERN) { + if (logBrush.lbHatch == value) return hBrush; + } + break; + } } int length = brushes.length; int hBrush = brushes [--length]; if (hBrush != 0) OS.DeleteObject (hBrush); System.arraycopy (brushes, 0, brushes, 1, length); - brushes [0] = hBrush = OS.CreateSolidBrush (pixel); - return hBrush; + switch (lbStyle) { + case OS.BS_SOLID: + hBrush = OS.CreateSolidBrush (value); + break; + case OS.BS_PATTERN: + hBrush = OS.CreatePatternBrush (value); + break; + } + return brushes [0] = hBrush; } Cursor findCursor () { return cursor; } +Control findImageControl (Image image) { + return backgroundImage == image ? this : null; +} + Control findThemeControl () { return null; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java index c9dc299755..273a52dd85 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TabFolder.java @@ -307,7 +307,8 @@ void drawThemeBackground (int hDC, int hwnd, RECT rect) { } Control findThemeControl () { - return background == -1 ? this : super.findThemeControl (); + /* On Windows, it is not possible to change the background of this control */ + return this; } public Rectangle getClientArea () { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java index 610328935f..b8bebe6fef 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java @@ -109,6 +109,38 @@ TableItem _getItem (int index) { return items [index] = new TableItem (this, SWT.NONE, -1, false); } +void _setBackgroundImage (Image image) { + super._setBackgroundImage (image); + int pixel = OS.SendMessage (handle, OS.LVM_GETBKCOLOR, 0, 0); + if (image != null) { + if (pixel != OS.CLR_NONE) { + OS.SendMessage (handle, OS.LVM_SETBKCOLOR, 0, OS.CLR_NONE); + OS.SendMessage (handle, OS.LVM_SETTEXTBKCOLOR, 0, OS.CLR_NONE); + } + if ((style & SWT.FULL_SELECTION) != 0) { + int bits = OS.LVS_EX_FULLROWSELECT; + OS.SendMessage (handle, OS.LVM_SETEXTENDEDLISTVIEWSTYLE, bits, 0); + } + } else { + if (pixel == OS.CLR_NONE) { + pixel = background != -1 ? background : defaultBackground (); + OS.SendMessage (handle, OS.LVM_SETBKCOLOR, 0, pixel); + OS.SendMessage (handle, OS.LVM_SETTEXTBKCOLOR, 0, pixel); + if ((style & SWT.CHECK) != 0) setCheckboxImageListColor (); + } + if ((style & SWT.FULL_SELECTION) != 0) { + int bits = OS.LVS_EX_FULLROWSELECT; + OS.SendMessage (handle, OS.LVM_SETEXTENDEDLISTVIEWSTYLE, bits, bits); + } + } + /* + * Feature in Windows. When the background color is + * changed, the table does not redraw until the next + * WM_PAINT. The fix is to force a redraw. + */ + OS.InvalidateRect (handle, null, true); +} + /** * Adds the listener to the collection of listeners who will * be notified when the receiver's selection changes, by sending @@ -156,42 +188,65 @@ int callWindowProc (int hwnd, int msg, int wParam, int lParam, boolean forceSele return OS.CallWindowProc (HeaderProc, hwnd, msg, wParam, lParam); } } + int topIndex = 0; boolean checkSelection = false, checkActivate = false; switch (msg) { + /* Keyboard messages */ + /* + * Feature in Windows. Windows sends LVN_ITEMACTIVATE from WM_KEYDOWN + * instead of WM_CHAR. This means that application code that expects + * to consume the key press and therefore avoid a SWT.DefaultSelection + * event will fail. The fix is to ignore LVN_ITEMACTIVATE when it is + * caused by WM_KEYDOWN and send SWT.DefaultSelection from WM_CHAR. + */ + case OS.WM_KEYDOWN: + checkSelection = checkActivate = true; + //FALL THROUGH case OS.WM_CHAR: case OS.WM_IME_CHAR: case OS.WM_KEYUP: case OS.WM_SYSCHAR: case OS.WM_SYSKEYDOWN: case OS.WM_SYSKEYUP: + checkSelection = true; + //FALL THROUGH + + /* Scroll messages */ + case OS.WM_HSCROLL: + case OS.WM_VSCROLL: + + /* Resize messages */ + case OS.WM_WINDOWPOSCHANGED: + if (backgroundImage != null && drawCount == 0) { + OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); + } + //FALL THROUGH + + /* Mouse messages */ case OS.WM_LBUTTONDBLCLK: + case OS.WM_LBUTTONDOWN: case OS.WM_LBUTTONUP: case OS.WM_MBUTTONDBLCLK: + case OS.WM_MBUTTONDOWN: case OS.WM_MBUTTONUP: case OS.WM_MOUSEHOVER: case OS.WM_MOUSELEAVE: case OS.WM_MOUSEMOVE: -// case OS.WM_MOUSEWHEEL: + case OS.WM_MOUSEWHEEL: case OS.WM_RBUTTONDBLCLK: + case OS.WM_RBUTTONDOWN: case OS.WM_RBUTTONUP: case OS.WM_XBUTTONDBLCLK: - case OS.WM_XBUTTONUP: - case OS.WM_LBUTTONDOWN: - case OS.WM_MBUTTONDOWN: - case OS.WM_RBUTTONDOWN: case OS.WM_XBUTTONDOWN: - checkSelection = true; - break; - /* - * Feature in Windows. Windows sends LVN_ITEMACTIVATE from WM_KEYDOWN - * instead of WM_CHAR. This means that application code that expects - * to consume the key press and therefore avoid a SWT.DefaultSelection - * event will fail. The fix is to ignore LVN_ITEMACTIVATE when it is - * caused by WM_KEYDOWN and send SWT.DefaultSelection from WM_CHAR. - */ - case OS.WM_KEYDOWN: - checkSelection = checkActivate = true; - break; + case OS.WM_XBUTTONUP: + + /* Other messages */ + case OS.WM_SETFONT: + case OS.WM_TIMER: { + if (backgroundImage != null) { + topIndex = OS.SendMessage (handle, OS.LVM_GETTOPINDEX, 0, 0); + } + } } boolean oldSelected = wasSelected; if (checkSelection) wasSelected = false; @@ -207,6 +262,58 @@ int callWindowProc (int hwnd, int msg, int wParam, int lParam, boolean forceSele } wasSelected = oldSelected; } + switch (msg) { + /* Keyboard messages */ + case OS.WM_KEYDOWN: + case OS.WM_CHAR: + case OS.WM_IME_CHAR: + case OS.WM_KEYUP: + case OS.WM_SYSCHAR: + case OS.WM_SYSKEYDOWN: + case OS.WM_SYSKEYUP: + + /* Scroll messages */ + case OS.WM_HSCROLL: + case OS.WM_VSCROLL: + + /* Resize messages */ + case OS.WM_WINDOWPOSCHANGED: + if (backgroundImage != null && drawCount == 0) { + OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); + OS.InvalidateRect (handle, null, true); + int hwndHeader = OS.SendMessage (handle, OS.LVM_GETHEADER, 0, 0); + if (hwndHeader != 0) OS.InvalidateRect (hwndHeader, null, true); + } + //FALL THROUGH + + /* Mouse messages */ + case OS.WM_LBUTTONDBLCLK: + case OS.WM_LBUTTONDOWN: + case OS.WM_LBUTTONUP: + case OS.WM_MBUTTONDBLCLK: + case OS.WM_MBUTTONDOWN: + case OS.WM_MBUTTONUP: + case OS.WM_MOUSEHOVER: + case OS.WM_MOUSELEAVE: + case OS.WM_MOUSEMOVE: + case OS.WM_MOUSEWHEEL: + case OS.WM_RBUTTONDBLCLK: + case OS.WM_RBUTTONDOWN: + case OS.WM_RBUTTONUP: + case OS.WM_XBUTTONDBLCLK: + case OS.WM_XBUTTONDOWN: + case OS.WM_XBUTTONUP: + + /* Other messages */ + case OS.WM_SETFONT: + case OS.WM_TIMER: { + if (backgroundImage != null) { + if (topIndex != OS.SendMessage (handle, OS.LVM_GETTOPINDEX, 0, 0)) { + OS.InvalidateRect (handle, null, true); + } + } + } + } return code; } @@ -2382,6 +2489,7 @@ LRESULT sendMouseDownEvent (int type, int button, int msg, int wParam, int lPara void setBackgroundPixel (int pixel) { if (background == pixel) return; background = pixel; + if (backgroundImage != null) return; if (pixel == -1) pixel = defaultBackground (); OS.SendMessage (handle, OS.LVM_SETBKCOLOR, 0, pixel); OS.SendMessage (handle, OS.LVM_SETTEXTBKCOLOR, 0, pixel); @@ -3975,7 +4083,7 @@ LRESULT WM_SIZE (int wParam, int lParam) { LRESULT WM_SYSCOLORCHANGE (int wParam, int lParam) { LRESULT result = super.WM_SYSCOLORCHANGE (wParam, lParam); if (result != null) return result; - if (background == -1) { + if (background == -1 && backgroundImage == null) { int pixel = defaultBackground (); OS.SendMessage (handle, OS.LVM_SETBKCOLOR, 0, pixel); OS.SendMessage (handle, OS.LVM_SETTEXTBKCOLOR, 0, pixel); @@ -4125,14 +4233,28 @@ LRESULT wmNotifyChild (int wParam, int lParam) { break; } case OS.NM_CUSTOMDRAW: { - if (!customDraw) break; + if (!customDraw) { + if (backgroundImage == null) break; + } int hwndHeader = OS.SendMessage (handle, OS.LVM_GETHEADER, 0, 0); if (hdr.hwndFrom == hwndHeader) break; NMLVCUSTOMDRAW nmcd = new NMLVCUSTOMDRAW (); OS.MoveMemory (nmcd, lParam, NMLVCUSTOMDRAW.sizeof); switch (nmcd.dwDrawStage) { - case OS.CDDS_PREPAINT: return new LRESULT (OS.CDRF_NOTIFYITEMDRAW); - case OS.CDDS_ITEMPREPAINT: return new LRESULT (OS.CDRF_NOTIFYSUBITEMDRAW); + case OS.CDDS_PREPAINT: { +// if (drawCount != 0 || !OS.IsWindowVisible (handle)) { +// if (!OS.IsWinCE && OS.WindowFromDC (nmcd.hdc) == handle) break; +// } + if (backgroundImage != null) { + RECT rect = new RECT (); + OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); + fillBackground (nmcd.hdc, backgroundImage, rect); + } + return new LRESULT (OS.CDRF_NOTIFYITEMDRAW); + } + case OS.CDDS_ITEMPREPAINT: { + return new LRESULT (OS.CDRF_NOTIFYSUBITEMDRAW); + } case OS.CDDS_ITEMPREPAINT | OS.CDDS_SUBITEM: { TableItem item = _getItem (nmcd.dwItemSpec); int hFont = item.cellFont != null ? item.cellFont [nmcd.iSubItem] : -1; @@ -4159,7 +4281,9 @@ LRESULT wmNotifyChild (int wParam, int lParam) { OS.SelectObject (nmcd.hdc, hFont); if (OS.IsWindowEnabled (handle)) { nmcd.clrText = clrText == -1 ? getForegroundPixel () : clrText; - nmcd.clrTextBk = clrTextBk == -1 ? getBackgroundPixel () : clrTextBk; + if (backgroundImage == null) { + nmcd.clrTextBk = clrTextBk == -1 ? getBackgroundPixel () : clrTextBk; + } OS.MoveMemory (lParam, nmcd, NMLVCUSTOMDRAW.sizeof); } return new LRESULT (OS.CDRF_NEWFONT); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java index 45268767fe..eeed582f06 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java @@ -1113,16 +1113,27 @@ LRESULT wmNotifyChild (int wParam, int lParam) { child.postEvent (SWT.Selection, event); } break; - case OS.NM_CUSTOMDRAW: - if (findThemeControl() == null && background == -1) break; + case OS.NM_CUSTOMDRAW: + if (background == -1 && backgroundImage == null) { + if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { + if (findThemeControl () == null) break; + } + } NMCUSTOMDRAW nmcd = new NMCUSTOMDRAW (); OS.MoveMemory (nmcd, lParam, NMCUSTOMDRAW.sizeof); +// if (drawCount != 0 || !OS.IsWindowVisible (handle)) { +// if (!OS.IsWinCE && OS.WindowFromDC (nmcd.hdc) == handle) break; +// } switch (nmcd.dwDrawStage) { - case OS.CDDS_PREERASE: + case OS.CDDS_PREERASE: { return new LRESULT (OS.CDRF_NOTIFYPOSTERASE); - case OS.CDDS_POSTERASE: - drawBackground (nmcd.hdc); - return null; + } + case OS.CDDS_POSTERASE: { + RECT rect = new RECT (); + OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); + drawBackground (nmcd.hdc, rect); + break; + } } break; case OS.TBN_HOTITEMCHANGE: diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java index ebc327dac2..3771936e07 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java @@ -131,9 +131,43 @@ TreeItem _getItem (int hItem, int id) { return id != -1 ? items [id] : new TreeItem (this, SWT.NONE, -1, -1, hItem); } +void _setBackgroundImage (Image image) { + super._setBackgroundImage (image); + + /* + * Feature in Windows. If TVM_SETBKCOLOR is never + * used to set the background color of a tree, the + * background color of the lines and the plus/minus + * will not be drawn using the default background + * color, not the HBRUSH returned from WM_CTLCOLOR. + * The fix is to set the background color to the + * default (when it is already the default) to make + * Windows use the brush. + */ + if (OS.COMCTL32_MAJOR < 6) { + if (OS.SendMessage (handle, OS.TVM_GETBKCOLOR, 0, 0) == -1) { + OS.SendMessage (handle, OS.TVM_SETBKCOLOR, 0, -1); + } + } + + //FIXME - images do not draw properly with TVS_FULLROWSELECT + if ((style & SWT.FULL_SELECTION) != 0) { + int newBits = OS.GetWindowLong (handle, OS.GWL_STYLE), oldBits = newBits; + if (image == null) { + newBits |= OS.TVS_FULLROWSELECT; + } else { + newBits &= ~OS.TVS_FULLROWSELECT; + } + if (newBits != oldBits) { + OS.SetWindowLong (handle, OS.GWL_STYLE, newBits); + OS.InvalidateRect (handle, null, true); + } + } +} + void _setBackgroundPixel (int pixel) { /* - * Bug in Windows. When TVM_GETBKCOLOR is used more + * Bug in Windows. When TVM_SETBKCOLOR is used more * than once to set the background color of a tree, * the background color of the lines and the plus/minus * does not change to the new color. The fix is to set @@ -248,14 +282,114 @@ int callWindowProc (int hwnd, int msg, int wParam, int lParam) { } } break; + } + } + int hItem = 0; + switch (msg) { + /* Keyboard messages */ + case OS.WM_KEYDOWN: + if (wParam == OS.VK_CONTROL || wParam == OS.VK_SHIFT) break; + //FALL THROUGH + case OS.WM_CHAR: + case OS.WM_IME_CHAR: + case OS.WM_KEYUP: + case OS.WM_SYSCHAR: + case OS.WM_SYSKEYDOWN: + case OS.WM_SYSKEYUP: + + /* Scroll messages */ + case OS.WM_HSCROLL: + case OS.WM_VSCROLL: + + /* Resize messages */ + case OS.WM_SIZE: + if (backgroundImage != null && drawCount == 0) { + OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); + } + //FALL THROUGH + + /* Mouse messages */ + case OS.WM_LBUTTONDBLCLK: + case OS.WM_LBUTTONDOWN: + case OS.WM_LBUTTONUP: + case OS.WM_MBUTTONDBLCLK: + case OS.WM_MBUTTONDOWN: + case OS.WM_MBUTTONUP: + case OS.WM_MOUSEHOVER: + case OS.WM_MOUSELEAVE: + case OS.WM_MOUSEMOVE: + case OS.WM_MOUSEWHEEL: + case OS.WM_RBUTTONDBLCLK: + case OS.WM_RBUTTONDOWN: + case OS.WM_RBUTTONUP: + case OS.WM_XBUTTONDBLCLK: + case OS.WM_XBUTTONDOWN: + case OS.WM_XBUTTONUP: + + /* Other messages */ + case OS.WM_SETFONT: + case OS.WM_TIMER: { + if (backgroundImage != null) { + hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); + } } - case OS.WM_MOUSEWHEEL: { - int code = OS.CallWindowProc (TreeProc, hwnd, msg, wParam, lParam); + } + int code = OS.CallWindowProc (TreeProc, hwnd, msg, wParam, lParam); + switch (msg) { + /* Keyboard messages */ + case OS.WM_KEYDOWN: + if (wParam == OS.VK_CONTROL || wParam == OS.VK_SHIFT) break; + //FALL THROUGH + case OS.WM_CHAR: + case OS.WM_IME_CHAR: + case OS.WM_KEYUP: + case OS.WM_SYSCHAR: + case OS.WM_SYSKEYDOWN: + case OS.WM_SYSKEYUP: + + /* Scroll messages */ + case OS.WM_HSCROLL: + case OS.WM_VSCROLL: + + /* Resize messages */ + case OS.WM_SIZE: + if (backgroundImage != null && drawCount == 0) { + OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); + OS.InvalidateRect (handle, null, true); + if (hwndHeader != 0) OS.InvalidateRect (hwndHeader, null, true); + } + //FALL THROUGH + + /* Mouse messages */ + case OS.WM_LBUTTONDBLCLK: + case OS.WM_LBUTTONDOWN: + case OS.WM_LBUTTONUP: + case OS.WM_MBUTTONDBLCLK: + case OS.WM_MBUTTONDOWN: + case OS.WM_MBUTTONUP: + case OS.WM_MOUSEHOVER: + case OS.WM_MOUSELEAVE: + case OS.WM_MOUSEMOVE: + case OS.WM_MOUSEWHEEL: + case OS.WM_RBUTTONDBLCLK: + case OS.WM_RBUTTONDOWN: + case OS.WM_RBUTTONUP: + case OS.WM_XBUTTONDBLCLK: + case OS.WM_XBUTTONDOWN: + case OS.WM_XBUTTONUP: + + /* Other messages */ + case OS.WM_SETFONT: + case OS.WM_TIMER: { + if (backgroundImage != null) { + if (hItem != OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0)) { + OS.InvalidateRect (handle, null, true); + } + } updateScrollBar (); - return code; } } - return OS.CallWindowProc (TreeProc, hwnd, msg, wParam, lParam); + return code; } boolean checkData (TreeItem item, boolean redraw) { @@ -1184,9 +1318,7 @@ int getBackgroundPixel () { * The fix is to set the default background color while the tree * is disabled and restore it when enabled. */ - if (!OS.IsWindowEnabled (handle) && background != -1) { - return background; - } + if (!OS.IsWindowEnabled (handle) && background != -1) return background; return _getBackgroundPixel (); } @@ -1454,7 +1586,8 @@ public TreeItem getItem (Point point) { lpht.y = point.y; OS.SendMessage (handle, OS.TVM_HITTEST, 0, lpht); if (lpht.hItem != 0) { - if ((style & SWT.FULL_SELECTION) != 0 || (lpht.flags & OS.TVHT_ONITEM) != 0) { + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + if ((bits & OS.TVS_FULLROWSELECT) != 0 || (lpht.flags & OS.TVHT_ONITEM) != 0) { TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; tvItem.hItem = lpht.hItem; @@ -3259,43 +3392,7 @@ int windowProc (int hwnd, int msg, int wParam, int lParam) { } return callWindowProc (hwnd, msg, wParam, lParam); } - int code = super.windowProc (handle, msg, wParam, lParam); - switch (msg) { - /* Keyboard messages */ - case OS.WM_CHAR: - case OS.WM_IME_CHAR: - case OS.WM_KEYDOWN: - case OS.WM_KEYUP: - case OS.WM_SYSCHAR: - case OS.WM_SYSKEYDOWN: - case OS.WM_SYSKEYUP: - - /* Mouse messages */ - case OS.WM_LBUTTONDBLCLK: - case OS.WM_LBUTTONDOWN: - case OS.WM_LBUTTONUP: - case OS.WM_MBUTTONDBLCLK: - case OS.WM_MBUTTONDOWN: - case OS.WM_MBUTTONUP: - case OS.WM_MOUSEHOVER: - case OS.WM_MOUSELEAVE: - case OS.WM_MOUSEMOVE: - case OS.WM_MOUSEWHEEL: - case OS.WM_RBUTTONDBLCLK: - case OS.WM_RBUTTONDOWN: - case OS.WM_RBUTTONUP: - case OS.WM_XBUTTONDBLCLK: - case OS.WM_XBUTTONDOWN: - case OS.WM_XBUTTONUP: - - /* Other messages */ - case OS.WM_SIZE: - case OS.WM_SETFONT: - case OS.WM_TIMER: { - updateScrollBar (); - } - } - return code; + return super.windowProc (hwnd, msg, wParam, lParam); } LRESULT WM_CHAR (int wParam, int lParam) { @@ -3390,6 +3487,12 @@ LRESULT WM_CHAR (int wParam, int lParam) { return result; } +LRESULT WM_ERASEBKGND (int wParam, int lParam) { + LRESULT result = super.WM_ERASEBKGND (wParam, lParam); + if (backgroundImage != null) return LRESULT.ONE; + return result; +} + LRESULT WM_GETOBJECT (int wParam, int lParam) { /* * Ensure that there is an accessible object created for this @@ -3632,7 +3735,8 @@ LRESULT WM_LBUTTONDBLCLK (int wParam, int lParam) { } LRESULT result = super.WM_LBUTTONDBLCLK (wParam, lParam); if (lpht.hItem != 0) { - if ((style & SWT.FULL_SELECTION) != 0 || (lpht.flags & OS.TVHT_ONITEM) != 0) { + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + if ((bits & OS.TVS_FULLROWSELECT) != 0 || (lpht.flags & OS.TVHT_ONITEM) != 0) { Event event = new Event (); TVITEM tvItem = new TVITEM (); tvItem.hItem = lpht.hItem; @@ -4025,24 +4129,28 @@ LRESULT WM_NOTIFY (int wParam, int lParam) { HDITEM newItem = new HDITEM (); OS.MoveMemory (newItem, phdn.pitem, HDITEM.sizeof); if ((newItem.mask & OS.HDI_WIDTH) != 0) { - HDITEM oldItem = new HDITEM (); - oldItem.mask = OS.HDI_WIDTH; - OS.SendMessage (hwndHeader, OS.HDM_GETITEM, phdn.iItem, oldItem); - int deltaX = newItem.cxy - oldItem.cxy; - RECT rect = new RECT (), itemRect = new RECT (); + RECT rect = new RECT (); OS.GetClientRect (handle, rect); - OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, phdn.iItem, itemRect); - int gridWidth = getLinesVisible () ? GRID_WIDTH : 0; - rect.left = itemRect.right - gridWidth; + RECT itemRect = new RECT (); int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, count - 1, 0); OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, itemRect); rect.right = itemRect.right; - int flags = OS.SW_INVALIDATE | OS.SW_ERASE; - OS.ScrollWindowEx (handle, deltaX, 0, rect, null, 0, null, flags); - //TODO - column flashes when resized + OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, phdn.iItem, itemRect); + int gridWidth = getLinesVisible () ? GRID_WIDTH : 0; + rect.left = itemRect.right - gridWidth; + if (backgroundImage != null) { + OS.InvalidateRect (handle, rect, true); + } else { + HDITEM oldItem = new HDITEM (); + oldItem.mask = OS.HDI_WIDTH; + OS.SendMessage (hwndHeader, OS.HDM_GETITEM, phdn.iItem, oldItem); + int deltaX = newItem.cxy - oldItem.cxy; + int flags = OS.SW_INVALIDATE | OS.SW_ERASE; + OS.ScrollWindowEx (handle, deltaX, 0, rect, null, 0, null, flags); + } + //TODO - column flashes when resized and not double buffered if (phdn.iItem != 0) { - OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, phdn.iItem, itemRect); rect.left = itemRect.left; rect.right = itemRect.right; OS.InvalidateRect (handle, rect, true); @@ -4144,7 +4252,9 @@ LRESULT WM_RBUTTONDOWN (int wParam, int lParam) { lpht.y = (short) (lParam >> 16); OS.SendMessage (handle, OS.TVM_HITTEST, 0, lpht); if (lpht.hItem != 0) { - if ((style & SWT.FULL_SELECTION) != 0 || (lpht.flags & (OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL)) != 0) { + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + int flags = OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL; + if ((bits & OS.TVS_FULLROWSELECT) != 0 || (lpht.flags & flags) != 0) { if ((wParam & (OS.MK_CONTROL | OS.MK_SHIFT)) == 0) { TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; @@ -4180,6 +4290,55 @@ LRESULT WM_PAINT (int wParam, int lParam) { } shrink = false; } + if (backgroundImage != null) { + GC gc = null; + int paintDC = 0; + PAINTSTRUCT ps = new PAINTSTRUCT (); + if (hooks (SWT.Paint)) { + GCData data = new GCData (); + data.ps = ps; + data.hwnd = handle; + gc = GC.win32_new (this, data); + paintDC = gc.handle; + } else { + paintDC = OS.BeginPaint (handle, ps); + } + + //TODO - only double buffer the damage +// int x = ps.left, y = ps.top; +// int width = ps.right - ps.left; +// int height = ps.bottom - ps.top; + RECT rect = new RECT (); + OS.GetClientRect (handle, rect); + int x = rect.left, y = rect.top; + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + + int hDC = OS.CreateCompatibleDC (paintDC); + int hBitmap = OS.CreateCompatibleBitmap (paintDC, width, height); + int hOldBitmap = OS.SelectObject (hDC, hBitmap); + fillBackground (hDC, backgroundImage, rect); + int code = callWindowProc (handle, OS.WM_PAINT, hDC, 0); + OS.BitBlt (paintDC, x, y, width, height, hDC, 0, 0, OS.SRCCOPY); + OS.SelectObject (hDC, hOldBitmap); + OS.DeleteObject (hBitmap); + OS.DeleteObject (hDC); + if (hooks (SWT.Paint)) { + Event event = new Event (); + event.gc = gc; + event.x = ps.left; + event.y = ps.top; + event.width = ps.right - ps.left; + event.height = ps.bottom - ps.top; + sendEvent (SWT.Paint, event); + // widget could be disposed at this point + event.gc = null; + gc.dispose (); + } else { + OS.EndPaint (handle, ps); + } + return new LRESULT (code); + } return super.WM_PAINT (wParam, lParam); } @@ -4239,6 +4398,16 @@ LRESULT WM_SYSCOLORCHANGE (int wParam, int lParam) { } LRESULT wmColorChild (int wParam, int lParam) { + if (backgroundImage != null) { + if (OS.COMCTL32_MAJOR < 6) { + //FIXME - TEMPORARY CODE + state |= TRANSPARENT; + LRESULT result = super.wmColorChild (wParam, lParam); + state &= ~TRANSPARENT; + return result; + } + return new LRESULT (OS.GetStockObject (OS.NULL_BRUSH)); + } /* * Feature in Windows. Tree controls send WM_CTLCOLOREDIT * to allow application code to change the default colors. @@ -4331,12 +4500,17 @@ LRESULT wmNotifyChild (int wParam, int lParam) { break; } case OS.NM_CUSTOMDRAW: { - if (!customDraw) break; if (hdr.hwndFrom == hwndHeader) break; + if (!customDraw) { + if (backgroundImage == null) break; + } NMTVCUSTOMDRAW nmcd = new NMTVCUSTOMDRAW (); OS.MoveMemory (nmcd, lParam, NMTVCUSTOMDRAW.sizeof); switch (nmcd.dwDrawStage) { case OS.CDDS_PREPAINT: { +// if (drawCount != 0 || !OS.IsWindowVisible (handle)) { +// if (!OS.IsWinCE && OS.WindowFromDC (nmcd.hdc) == handle) break; +// } return new LRESULT (OS.CDRF_NOTIFYITEMDRAW | OS.CDRF_NOTIFYPOSTPAINT); } case OS.CDDS_POSTPAINT: { @@ -4402,7 +4576,8 @@ LRESULT wmNotifyChild (int wParam, int lParam) { OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); OS.DrawEdge (hDC, rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); } - if (!printClient && (style & SWT.FULL_SELECTION) == 0) { + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + if (!printClient && (bits & OS.TVS_FULLROWSELECT) == 0) { if (hwndHeader != 0) { int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); if (count != 0) { @@ -4489,14 +4664,16 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } int hDC = nmcd.hdc; OS.RestoreDC (hDC, -1); + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); + if (backgroundImage != null) OS.SetBkMode (hDC, OS.TRANSPARENT); boolean useColor = OS.IsWindowEnabled (handle); if (useColor) { - if ((style & SWT.FULL_SELECTION) != 0) { + if ((bits & OS.TVS_FULLROWSELECT) != 0) { TVITEM tvItem = new TVITEM (); tvItem.mask = OS.TVIF_STATE; tvItem.hItem = item.handle; OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); - if ((tvItem.state & OS.TVIS_SELECTED) != 0) { + if ((tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0) { useColor = false; /* * Feature in Windows. When the mouse is pressed and the @@ -4547,37 +4724,97 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } } } - } else { - OS.SetTextColor (hDC, getForegroundPixel ()); - OS.SetBkColor (hDC, getBackgroundPixel ()); } } - if (hwndHeader != 0) { - GCData data = new GCData(); - data.device = display; - GC gc = GC.win32_new (hDC, data); - int x = 0, gridWidth = linesVisible ? GRID_WIDTH : 0; - Point size = null; - RECT rect = new RECT (); - HDITEM hdItem = new HDITEM (); - hdItem.mask = OS.HDI_WIDTH; - int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); - for (int i=0; i<count; i++) { - int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, i, 0); + GCData data = new GCData(); + data.device = display; + GC gc = GC.win32_new (hDC, data); + int x = 0, gridWidth = linesVisible ? GRID_WIDTH : 0; + Point size = null; + int count = hwndHeader != 0 ? OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) : 0; + for (int i=0; i<Math.max (1, count); i++) { + boolean drawItem = true; + int index = i, width = nmcd.right - nmcd.left; + if (count > 0 && hwndHeader != 0) { + HDITEM hdItem = new HDITEM (); + hdItem.mask = OS.HDI_WIDTH; + index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, i, 0); OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem); - if (i > 0) { - int clrTextBk = -1; - OS.SetRect (rect, x, nmcd.top, x + hdItem.cxy, nmcd.bottom - gridWidth); - if (useColor) { - clrTextBk = item.cellBackground != null ? item.cellBackground [index] : -1; - if (clrTextBk == -1) clrTextBk = item.background; - } - if (clrTextBk == -1) { - if (printClient || (style & SWT.FULL_SELECTION) != 0) { - clrTextBk = OS.GetBkColor (hDC); + width = hdItem.cxy; + } + RECT rect = new RECT (); + if (i == 0) { + drawItem = false; + if (useColor) { + if (backgroundImage != null) { + /* + * Feature in Windows. When the mouse is pressed in a + * single select tree, the previous item is no longer + * selected, but the TVIS_SELECTED bits for that item + * are not set. The fix is to test for the selection + * colors and guess that the item is selected. + * + * NOTE: This code does not work when the foreground and + * background of the tree are set to the selection colors + * but this does not happen in a regular application. + */ + boolean selected = false; + if ((style & SWT.SINGLE) != 0) { + if (OS.GetTextColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) { + if (OS.GetBkColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHT)) { + selected = true; + } + } + } else { + TVITEM tvItem = new TVITEM (); + tvItem.mask = OS.TVIF_STATE; + tvItem.hItem = item.handle; + OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem); + selected = (tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0; + } + if (!selected) { + rect.left = item.handle; + if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, rect) != 0) { + drawItem = true; + int right = Math.min (rect.right, width); + OS.SetRect (rect, rect.left, rect.top, right, rect.bottom); + fillBackground (hDC, backgroundImage, rect); + if (handle == OS.GetFocus ()) { + int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); + if ((uiState & OS.UISF_HIDEFOCUS) == 0) { + int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); + if (hItem == item.handle) OS.DrawFocusRect (hDC, rect); + } + } + rect.left = Math.min (rect.right, rect.left + 2); + } } } - if (clrTextBk != -1) drawBackground (hDC, clrTextBk, rect); + OS.SetTextColor (hDC, getForegroundPixel ()); + OS.SetBkColor (hDC, getBackgroundPixel ()); + } + } else { + OS.SetRect (rect, x, nmcd.top, x + width, nmcd.bottom - gridWidth); + } + if (drawItem) { + int clrTextBk = -1; + if (useColor) { + clrTextBk = item.cellBackground != null ? item.cellBackground [index] : -1; + if (clrTextBk == -1) clrTextBk = item.background; + } + if (clrTextBk == -1) { + if (printClient || (bits & OS.TVS_FULLROWSELECT) != 0) { + clrTextBk = OS.GetBkColor (hDC); + } + } + if (clrTextBk != -1) { + if (backgroundImage != null) { + fillBackground (hDC, backgroundImage, rect); + } else { + fillBackground (hDC, clrTextBk, rect); + } + } + if (i > 0) { Image image = null; if (index == 0) { image = item.image; @@ -4593,59 +4830,65 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } else { OS.SetRect (rect, rect.left + INSET, rect.top, rect.right - INSET, rect.bottom); } - /* - * Bug in Windows. When DrawText() is used with DT_VCENTER - * and DT_ENDELLIPSIS, the ellipsis can draw outside of the - * rectangle when the rectangle is empty. The fix is avoid - * all text drawing for empty rectangles. - */ - if (rect.left < rect.right) { - String string = null; - if (index == 0) { - string = item.text; - } else { - String [] strings = item.strings; - if (strings != null) string = strings [index]; + } + /* + * Bug in Windows. When DrawText() is used with DT_VCENTER + * and DT_ENDELLIPSIS, the ellipsis can draw outside of the + * rectangle when the rectangle is empty. The fix is avoid + * all text drawing for empty rectangles. + */ + if (rect.left < rect.right) { + String string = null; + if (index == 0) { + string = item.text; + } else { + String [] strings = item.strings; + if (strings != null) string = strings [index]; + } + if (string != null) { + int hFont = item.cellFont != null ? item.cellFont [index] : -1; + if (hFont == -1) hFont = item.font; + hFont = hFont != -1 ? OS.SelectObject (hDC, hFont) : -1; + int clrText = -1; + if (useColor) { + clrText = item.cellForeground != null ? item.cellForeground [index] : -1; + if (clrText == -1) clrText = item.foreground; + clrText = clrText != -1 ? OS.SetTextColor (hDC, clrText) : -1; } - if (string != null) { - int hFont = item.cellFont != null ? item.cellFont [index] : -1; - if (hFont == -1) hFont = item.font; - hFont = hFont != -1 ? OS.SelectObject (hDC, hFont) : -1; - int clrText = -1; - if (useColor) { - clrText = item.cellForeground != null ? item.cellForeground [index] : -1; - if (clrText == -1) clrText = item.foreground; - clrText = clrText != -1 ? OS.SetTextColor (hDC, clrText) : -1; - } - int oldMode = clrTextBk != -1 ? OS.SetBkMode (hDC, OS.TRANSPARENT) : -1; - int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER | OS.DT_ENDELLIPSIS; - TreeColumn column = columns [index]; + int oldMode = clrTextBk != -1 ? OS.SetBkMode (hDC, OS.TRANSPARENT) : -1; + int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER; + if (i != 0) flags |= OS.DT_ENDELLIPSIS; + flags |= OS.DT_LEFT; + TreeColumn column = columns != null ? columns [index] : null; + if (column != null) { if ((column.style & SWT.LEFT) != 0) flags |= OS.DT_LEFT; if ((column.style & SWT.CENTER) != 0) flags |= OS.DT_CENTER; if ((column.style & SWT.RIGHT) != 0) flags |= OS.DT_RIGHT; - TCHAR buffer = new TCHAR (getCodePage (), string, false); - OS.DrawText (hDC, buffer, buffer.length (), rect, flags); - if (hFont != -1) OS.SelectObject (hDC, hFont); - if (clrText != -1) OS.SetTextColor (hDC, clrText); - if (oldMode != -1) OS.SetBkMode (hDC, oldMode); } + TCHAR buffer = new TCHAR (getCodePage (), string, false); + OS.DrawText (hDC, buffer, buffer.length (), rect, flags); + if (hFont != -1) OS.SelectObject (hDC, hFont); + if (clrText != -1) OS.SetTextColor (hDC, clrText); + if (oldMode != -1) OS.SetBkMode (hDC, oldMode); } } - x += hdItem.cxy; } - if (count > 0) { - if (printClient || (style & SWT.FULL_SELECTION) != 0) { - OS.SetRect (rect, x, nmcd.top, nmcd.right, nmcd.bottom - gridWidth); - drawBackground (hDC, OS.GetBkColor (hDC), rect); - } + x += width; + } + if (count > 0) { + if (printClient || (bits & OS.TVS_FULLROWSELECT) != 0) { + RECT rect = new RECT (); + OS.SetRect (rect, x, nmcd.top, nmcd.right, nmcd.bottom - gridWidth); + fillBackground (hDC, OS.GetBkColor (hDC), rect); + /* This code is intentionally commented */ + //drawBackground (hDC, rect); } - gc.dispose (); } + gc.dispose (); if (linesVisible) { - if (printClient && (style & SWT.FULL_SELECTION) == 0) { + if (printClient && (bits & OS.TVS_FULLROWSELECT) != 0) { if (hwndHeader != 0) { - int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); - if (count != 0 && printClient) { + if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) != 0 && printClient) { HDITEM hdItem = new HDITEM (); hdItem.mask = OS.HDI_WIDTH; OS.SendMessage (hwndHeader, OS.HDM_GETITEM, 0, hdItem); @@ -4656,7 +4899,7 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } } RECT rect = new RECT (); - if (OS.COMCTL32_MAJOR < 6 || (style & SWT.FULL_SELECTION) != 0) { + if (OS.COMCTL32_MAJOR < 6 || (bits & OS.TVS_FULLROWSELECT) != 0) { OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); } else { rect.left = item.handle; @@ -4749,6 +4992,10 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } case OS.TVN_ITEMEXPANDEDA: case OS.TVN_ITEMEXPANDEDW: { + if (backgroundImage != null && drawCount == 0) { + OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); + OS.InvalidateRect (handle, null, true); + } /* * Bug in Windows. When TVM_SETINSERTMARK is used to set * an insert mark for a tree and an item is expanded or @@ -4764,6 +5011,9 @@ LRESULT wmNotifyChild (int wParam, int lParam) { } case OS.TVN_ITEMEXPANDINGA: case OS.TVN_ITEMEXPANDINGW: { + if (backgroundImage != null && drawCount == 0) { + OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); + } /* * Bug in Windows. When TVM_SETINSERTMARK is used to set * an insert mark for a tree and an item is expanded or diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java index bbdd139b48..1a6e15caaa 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TreeItem.java @@ -876,7 +876,8 @@ void redraw () { * full selection, redraw only the text. This is * an optimization to reduce flashing. */ - boolean full = (parent.style & SWT.FULL_SELECTION) != 0; + int bits = OS.GetWindowLong (hwnd, OS.GWL_STYLE); + boolean full = (bits & OS.TVS_FULLROWSELECT) != 0; if (!full) { int hwndHeader = parent.hwndHeader; if (hwndHeader != 0) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java index 02a435dd76..b84de78075 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java @@ -66,10 +66,13 @@ public abstract class Widget { /* A layout was requested in this widget hierachy */ static final int LAYOUT_CHILD = 1<<7; - /* More global state flags */ - static final int TRANSPARENT = 1<<8; - static final int RELEASED = 1<<9; - static final int DISPOSE_SENT = 1<<10; + /* Background flags */ + static final int TRANSPARENT = 1<<8; + static final int DRAW_BACKGROUND = 1<<9; + + /* Dispose and release flags */ + static final int RELEASED = 1<<10; + static final int DISPOSE_SENT = 1<<11; /* Default size for widgets */ static final int DEFAULT_WIDTH = 64; |