Merge branch 'master' into AERO_WORK
diff --git a/bundles/org.eclipse.swt/.classpath b/bundles/org.eclipse.swt/.classpath
new file mode 100644
index 0000000..376d930
--- /dev/null
+++ b/bundles/org.eclipse.swt/.classpath
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/CDC-1.0%Foundation-1.0"/>
+ <classpathentry kind="src" path="Eclipse SWT/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT/common"/>
+ <classpathentry kind="src" path="Eclipse SWT/common_j2se"/>
+ <classpathentry kind="src" path="Eclipse SWT PI/common"/>
+ <classpathentry kind="src" path="Eclipse SWT PI/win32">
+ <attributes>
+ <attribute value="org.eclipse.swt.win32.win32.x86" name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" path="Eclipse SWT PI/common_j2se"/>
+ <classpathentry kind="src" path="Eclipse SWT OLE Win32/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT Accessibility/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT Accessibility/common"/>
+ <classpathentry kind="src" path="Eclipse SWT AWT/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT AWT/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Drag and Drop/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT Drag and Drop/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Printing/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT Printing/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Program/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT Program/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Custom Widgets/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Browser/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Browser/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT Mozilla/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Mozilla/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT WebKit/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT OpenGL/win32"/>
+ <classpathentry kind="src" path="Eclipse SWT OpenGL/common"/>
+ <classpathentry kind="src" path="Eclipse SWT Theme/win32"/>
+ <classpathentry kind="lib" path="extra_jars/exceptions.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.swt/.gitignore b/bundles/org.eclipse.swt/.gitignore
index 8623d47..6420501 100644
--- a/bundles/org.eclipse.swt/.gitignore
+++ b/bundles/org.eclipse.swt/.gitignore
@@ -1,4 +1,4 @@
.classpath
ws/
.build64/
-.buildas/
+.buildas/
\ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.h
index 966233b..fbd3c3b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.h
@@ -689,6 +689,38 @@
#endif
#ifndef _WIN32_WCE
+// Callback function used by DrawTextWithGlow instead of DrawTextW
+typedef
+int
+(WINAPI *DTT_CALLBACK_PROC)
+(
+ __in HDC hdc,
+ __inout_ecount(cchText) LPWSTR pszText,
+ __in int cchText,
+ __inout LPRECT prc,
+ __in UINT dwFlags,
+ __in LPARAM lParam);
+
+typedef struct _DTTOPTS
+{
+ DWORD dwSize; // size of the struct
+ DWORD dwFlags; // which options have been specified
+ COLORREF crText; // color to use for text fill
+ COLORREF crBorder; // color to use for text outline
+ COLORREF crShadow; // color to use for text shadow
+ int iTextShadowType; // TST_SINGLE or TST_CONTINUOUS
+ POINT ptShadowOffset; // where shadow is drawn (relative to text)
+ int iBorderSize; // Border radius around text
+ int iFontPropId; // Font property to use for the text instead of TMT_FONT
+ int iColorPropId; // Color property to use for the text instead of TMT_TEXTCOLOR
+ int iStateId; // Alternate state id
+ BOOL fApplyOverlay; // Overlay text on top of any text effect?
+ int iGlowSize; // Glow radious around text
+ DTT_CALLBACK_PROC pfnDrawTextCallback; // Callback for DrawText
+ LPARAM lParam; // Parameter for callback
+} DTTOPTS, *PDTTOPTS;
+
+
#ifndef _BP_PAINTPARAMS
typedef HANDLE HPAINTBUFFER;
typedef struct _BP_PAINTPARAMS {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h
index 8a995a3..1dcd01b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h
@@ -39,6 +39,7 @@
#define DrawThemeParentBackground_LIB "uxtheme.dll"
#define DrawThemeText_LIB "uxtheme.dll"
#define DrawThemeTextEx_LIB "uxtheme.dll"
+#define DwmIsCompositionEnabled_LIB "dwmapi.dll"
#define DwmEnableBlurBehindWindow_LIB "dwmapi.dll"
#define DwmExtendFrameIntoClientArea_LIB "dwmapi.dll"
#define DwmIsCompositionEnabled_LIB "dwmapi.dll"
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/DTTOPTS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/DTTOPTS.java
index 224d91d..1dec4bb 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/DTTOPTS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/DTTOPTS.java
@@ -29,4 +29,4 @@
public int /*long*/ pfnDrawTextCallback;
public int /*long*/ lParam;
public static final int sizeof = OS.DTTOPTS_sizeof ();
-}
\ No newline at end of file
+}
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 84e8109..9128955 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
@@ -592,6 +592,9 @@
public static final int DTS_SHORTDATEFORMAT = 0x0000;
public static final int DTS_TIMEFORMAT = 0x0009;
public static final int DTS_UPDOWN = 0x0001;
+ public static final int DTT_TEXTCOLOR = 1 << 0;
+ public static final int DTT_GLOWSIZE = 1 << 11;
+ public static final int DTT_COMPOSITED = 1 << 13;
public static final int DWM_BB_ENABLE = 0x1;
public static final int DWM_BB_BLURREGION = 0x2;
public static final int DWM_BB_TRANSITIONONMAXIMIZED = 0x4;
@@ -1780,6 +1783,7 @@
public static final int TME_LEAVE = 0x2;
public static final int TME_QUERY = 0x40000000;
public static final int TMPF_VECTOR = 0x2;
+ public static final int TMT_TEXTGLOWSIZE = 2425;
public static final int TMT_CONTENTMARGINS = 3602;
public static final int TOUCHEVENTF_MOVE = 0x0001;
public static final int TOUCHEVENTF_DOWN = 0x0002;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
index 399bf07..c2ba5fe 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
@@ -1579,6 +1579,9 @@
* </ul></p>
*/
public static final int SMOOTH = 1 << 16;
+
+
+ public static final int TRIM_FILL = 1 << 31; //BAD
/**
* Style constant for no background behavior (value is 1<<18).
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt b/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt
old mode 100644
new mode 100755
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 4b44a64..c30f172 100644
--- 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
@@ -574,6 +574,93 @@
return OS.GetSysColor (OS.COLOR_BTNTEXT);
}
+/*
+ * Reference vsstyle.h in the Windows SDK.
+ *
+ * Return the button style for the PushButton or the ToggleButton. Button styles come in various flavors: disabled, pressed, hot, default
+ * and normal.
+ *
+ */
+int determineStateOfPushButton () {
+ POINT ptCursor = new POINT ();
+ RECT rectWindow = new RECT ();
+ OS.GetWindowRect (handle, rectWindow);
+ OS.GetCursorPos (ptCursor);
+ boolean hovering = OS.PtInRect (rectWindow, ptCursor);
+ boolean captured = OS.GetCapture () == handle;
+
+ if (!getEnabled ()) {
+ return OS.PBS_DISABLED;
+ }
+
+ if (hovering && captured) {
+ return OS.PBS_PRESSED;
+ }
+
+ if (hovering || captured) {
+ return OS.PBS_HOT;
+ }
+
+ int /*long*/ dwCheckState = OS.SendMessage(handle, OS.BM_GETCHECK, 0, 0);
+ if (dwCheckState == OS.BST_CHECKED) {
+ return OS.PBS_PRESSED;
+ }
+
+ if (getDefault ()) {
+ return OS.PBS_DEFAULTED;
+ }
+
+ return OS.PBS_NORMAL;
+}
+
+/*
+ * Reference vsstyle.h in the Windows SDK.
+ *
+ * Button states will determine which bitmap the theme will draw in the background. The visual state comes in 4 states: normal, hot, pressed or
+ * disabled. These 4 visual states are then combined with the checked/unchecked state of the button (in the case of the check box, there's
+ * a 3rd checked state of indeterminate), yielding the final button state that is returned.
+ *
+ */
+int determineStateOfRadioOrCheck () {
+ POINT ptCursor = new POINT ();
+ RECT rectWindow = new RECT ();
+ OS.GetWindowRect (handle, rectWindow);
+ OS.GetCursorPos (ptCursor);
+ boolean hovering = OS.PtInRect (rectWindow, ptCursor);
+ boolean captured = OS.GetCapture () == handle;
+ int /*long*/ dwCheckState = OS.SendMessage (handle, OS.BM_GETCHECK, 0, 0);
+
+ if (!getEnabled ()) {
+ if ((style & SWT.RADIO) != 0) {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.RBS_CHECKEDDISABLED : OS.RBS_UNCHECKEDDISABLED;
+ } else {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.CBS_CHECKEDDISABLED : (dwCheckState == OS.BST_UNCHECKED) ? OS.CBS_UNCHECKEDDISABLED : OS.CBS_MIXEDDISABLED;
+ }
+ }
+
+ if (hovering && captured) {
+ if ((style & SWT.RADIO) != 0) {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.RBS_CHECKEDPRESSED : OS.RBS_UNCHECKEDPRESSED;
+ } else {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.CBS_CHECKEDPRESSED : (dwCheckState == OS.BST_UNCHECKED) ? OS.CBS_UNCHECKEDPRESSED : OS.CBS_MIXEDPRESSED;
+ }
+ }
+
+ if (hovering || captured) {
+ if ((style & SWT.RADIO) != 0) {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.RBS_CHECKEDHOT : OS.RBS_UNCHECKEDHOT;
+ } else {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.CBS_CHECKEDHOT : (dwCheckState == OS.BST_UNCHECKED) ? OS.CBS_UNCHECKEDHOT : OS.CBS_MIXEDHOT;
+ }
+ }
+
+ if ((style & SWT.RADIO) != 0) {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.RBS_CHECKEDNORMAL : OS.RBS_UNCHECKEDNORMAL;
+ } else {
+ return (dwCheckState == OS.BST_CHECKED) ? OS.CBS_CHECKEDNORMAL : (dwCheckState == OS.BST_UNCHECKED) ? OS.CBS_UNCHECKEDNORMAL : OS.CBS_MIXEDNORMAL;
+ }
+}
+
void enableWidget (boolean enabled) {
super.enableWidget (enabled);
/*
@@ -636,6 +723,18 @@
return SWT.LEFT;
}
+boolean getBufferredPaint() {
+ Shell shell = getShell ();
+ if ((shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0) {
+ if ((style & SWT.PUSH) != 0) return true;
+ if ((style & SWT.TOGGLE) != 0) return true;
+ if ((style & SWT.RADIO) != 0) return true;
+ if ((style & SWT.CHECK) != 0) return true;
+ //what about arrow ? should be transparent with custom draw ?
+ }
+ return false;
+}
+
boolean getDefault () {
if ((style & SWT.PUSH) == 0) return false;
int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
@@ -742,6 +841,17 @@
return text;
}
+/*
+ * Return the width of the bitmap that is drawn in the background for the radio or checkbox.
+ */
+int getThemeBitmapWidth (int /*long*/ hTheme, int iPartId, int iState) {
+ BITMAP bm = new BITMAP ();
+ int /*long*/ [] hBitmap = new int /*long*/ [1];
+ OS.GetThemeBitmap (hTheme, iPartId, iState, 0, OS.GBF_DIRECT, hBitmap);
+ OS.GetObject (hBitmap[0], BITMAP.sizeof, bm);
+ return bm.bmWidth;
+}
+
boolean isTabItem () {
if ((style & SWT.PUSH) != 0) return isTabGroup ();
return super.isTabItem ();
@@ -1215,18 +1325,6 @@
return result;
}
-LRESULT WM_GETOBJECT (int /*long*/ wParam, int /*long*/ lParam) {
- /*
- * Ensure that there is an accessible object created for this
- * control because support for radio button position in group
- * accessibility is implemented in the accessibility package.
- */
- if ((style & SWT.RADIO) != 0) {
- if (accessible == null) accessible = new_Accessible (this);
- }
- return super.WM_GETOBJECT (wParam, lParam);
-}
-
LRESULT WM_KILLFOCUS (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_KILLFOCUS (wParam, lParam);
if ((style & SWT.PUSH) != 0 && getDefault ()) {
@@ -1336,6 +1434,77 @@
return result;
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ int /*long*/ paintDC = 0;
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ paintDC = OS.BeginPaint (hWnd, ps);
+
+ RECT rcClient = new RECT();
+ OS.GetClientRect (hWnd, rcClient);
+
+ // setup the theme parameters
+ int /*long*/ hTheme = display.hButtonTheme();
+ int iPartId = ((style & SWT.PUSH) != 0 || (style & SWT.TOGGLE) != 0) ? OS.BP_PUSHBUTTON : ((style & SWT.RADIO) != 0) ? OS.BP_RADIOBUTTON : OS.BP_CHECKBOX;
+ int iState = ((style & SWT.PUSH) != 0 || (style & SWT.TOGGLE) != 0) ? determineStateOfPushButton() : determineStateOfRadioOrCheck();
+
+ // initialize the buffered painting device context
+ BP_PAINTPARAMS params = new BP_PAINTPARAMS();
+ params.cbSize = BP_PAINTPARAMS.sizeof;
+ params.dwFlags = OS.BPPF_ERASE;
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(paintDC, rcClient, OS.BPBF_TOPDOWNDIB, params, hdcBuffered);
+ OS.PatBlt(hdcBuffered[0], 0, 0, rcClient.right, rcClient.bottom, OS.BLACKNESS);
+ OS.BufferedPaintSetAlpha(hdcBuffered[0], rcClient, (byte)0x00);
+
+ // the DrawThemeBackground will draw the radio button or checkbox in the middle of the button's client
+ // area, and hence we need shift the painting rectangle off to the left if this is not a pushbutton
+ int bitmapWidth = ((style & SWT.PUSH) != 0 || (style & SWT.TOGGLE) != 0) ? 0 : getThemeBitmapWidth(hTheme, iPartId, iState);
+ int bitmapOffset = ((style & SWT.PUSH) != 0 || (style & SWT.TOGGLE) != 0) ? 0 : (rcClient.right - rcClient.left) / 2 - bitmapWidth / 2;
+ RECT rcBackground = new RECT();
+ rcBackground.top = rcClient.top;
+ rcBackground.bottom = rcClient.bottom;
+ rcBackground.left = rcClient.left - bitmapOffset;
+ rcBackground.right = rcClient.right - bitmapOffset;
+
+ // get the coordinates of the content rectangle and draw the background bitmap (the content rectangle is later fed into
+ // DrawThemeTextEx and is also used for the focus rectangle)
+ RECT rcContent = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, hdcBuffered[0], iPartId, iState, rcClient, rcContent);
+ OS.DrawThemeBackground(hTheme, hdcBuffered[0], iPartId, iState, rcBackground, null);
+
+ // setup the DTTOPTS structure for calling into DrawThemeTextEx - note how we call getThemeGlowSize()
+ // to apply a glow around the text we are drawing to enhance readability of the text against a glass background
+ DTTOPTS dttOpts =new DTTOPTS();
+ dttOpts.dwSize = DTTOPTS.sizeof;
+ dttOpts.dwFlags = OS.DTT_COMPOSITED | OS.DTT_GLOWSIZE;
+ dttOpts.iGlowSize = getThemeGlowSize();
+
+ // set font before drawing the text
+ int /*long*/ hFont = OS.SendMessage(handle, OS.WM_GETFONT, 0, 0);
+ if (hFont != 0) {
+ hFont = OS.SelectObject(hdcBuffered[0], hFont);
+ }
+
+ // draw the button text in an aero/glass friendly manner
+ rcContent.left += bitmapWidth; // adjust the drawing rectangle to accomodate for the bitmap in case of radio or checkbox
+ int dwFlags = OS.DT_SINGLELINE | OS.DT_CENTER | OS.DT_VCENTER;
+ TCHAR buffer = new TCHAR (getCodePage (), text, true);
+ OS.DrawThemeTextEx(hTheme, hdcBuffered[0], iPartId, iState, buffer.chars, buffer.length()-1, dwFlags, rcContent, dttOpts);
+
+ // draw the focus rectangle if needed
+ if (OS.GetFocus()==handle) {
+ OS.DrawFocusRect(hdcBuffered[0], rcContent);
+ }
+
+ if (hFont != 0) {
+ OS.SelectObject(hdcBuffered[0], hFont);
+ }
+
+ OS.EndBufferedPaint(hBufferedPaint, true);
+ OS.EndPaint (handle, ps);
+ return LRESULT.ZERO;
+}
+
LRESULT wmCommandChild (int /*long*/ wParam, int /*long*/ lParam) {
int code = OS.HIWORD (wParam);
switch (code) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Combo.java
index 443e6ec..255c155 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Combo.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Combo.java
@@ -58,7 +58,7 @@
*/
public class Combo extends Composite {
- boolean noSelection, ignoreDefaultSelection, ignoreCharacter, ignoreModify, ignoreResize, lockText;
+ boolean noSelection, ignoreDefaultSelection, ignoreCharacter, ignoreModify, ignoreResize, ignoreColorChild, lockText;
int scrollWidth, visibleCount;
int /*long*/ cbtHook;
@@ -97,6 +97,7 @@
ComboProc = lpWndClass.lpfnWndProc;
}
+
/**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
@@ -657,6 +658,40 @@
return super.dragDetect (hwnd, x, y, filter, detect, consume);
}
+LRESULT drawBufferedText (int /*long*/ hWnd) {
+ int /*long*/ paintDC = 0;
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ paintDC = OS.BeginPaint (hWnd, ps);
+
+ RECT rect = new RECT();
+ OS.GetClientRect(hWnd, rect);
+
+ // set up the buffered device context - the alpha will be set to 100%, making the device context entirely opaque
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(paintDC, rect, OS.BPBF_TOPDOWNDIB, null, hdcBuffered);
+
+ if (hdcBuffered[0] != 0) {
+ // ask the Edit control to render itself into the buffered device context; note that this will result in
+ // the Edit control issuing a WM_CTLCOLOREDIT message and we need to set the 'bPrintingClient' flag to prevent
+ // a perpetual paint sequence from being triggered
+ ignoreColorChild = true;
+ OS.SendMessage (hWnd, OS.WM_PRINTCLIENT, hdcBuffered[0], OS.PRF_CLIENT);
+ ignoreColorChild = false;
+
+ // entirely opaque
+ OS.BufferedPaintSetAlpha(hBufferedPaint, rect, (byte)0xFF);
+ OS.EndBufferedPaint(hBufferedPaint, true);
+ }
+
+ OS.EndPaint (handle, ps);
+ return LRESULT.ZERO;
+}
+
+boolean getBufferredPaint () {
+ Shell shell = getShell ();
+ return (shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0;
+}
+
/**
* Returns a point describing the location of the caret relative
* to the receiver.
@@ -2212,7 +2247,18 @@
case OS.WM_XBUTTONUP: result = wmXButtonUp (hwnd, wParam, lParam); break;
/* Paint messages */
- case OS.WM_PAINT: result = wmPaint (hwnd, wParam, lParam); break;
+ case OS.WM_PAINT:
+ // the Edit child control of the ComboBox requires special paint handling if glass is on
+ if (hwnd == hwndText && getBufferredPaint()) {
+ result = drawBufferedText(hwnd);
+
+ // a side-effect of the glass painting is that the caret gets turned off, so we need
+ // to turn it back on once the painting is done
+ OS.ShowCaret(0);
+ } else {
+ result = wmPaint (hwnd, wParam, lParam);
+ }
+ break;
/* Menu messages */
case OS.WM_CONTEXTMENU: result = wmContextMenu (hwnd, wParam, lParam); break;
@@ -2534,6 +2580,23 @@
return null;
}
+LRESULT wmColorChild (int /*long*/ wParam, int /*long*/ lParam) {
+ if (!ignoreColorChild) {
+ int /*long*/ hwndEdit = OS.GetDlgItem (handle, CBID_EDIT);
+ if (lParam == hwndEdit) {
+ // a WM_CTLCOLOREDIT message is issued by the Win32 Edit control whenever it's about to be redrawn; the
+ // Control#windowProc routes that message into here, and if glass is turned on we invalidate the window to
+ // trigger a glass-aware repaint of the control
+ if (getBufferredPaint ()) {
+ RECT lpRect = new RECT ();
+ OS.GetClientRect (hwndEdit, lpRect);
+ OS.InvalidateRect (hwndEdit, lpRect, false);
+ }
+ }
+ }
+ return super.wmColorChild (wParam, lParam);
+}
+
LRESULT wmCommandChild (int /*long*/ wParam, int /*long*/ lParam) {
int code = OS.HIWORD (wParam);
switch (code) {
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 ee86187..e75a145 100644
--- 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
@@ -535,6 +535,14 @@
return handle;
}
+void checkAero () {
+ if ((style & SWT.TRIM_FILL) != 0) {
+ if ((parent.style & SWT.TRIM_FILL) == 0) {
+ style &= ~SWT.TRIM_FILL;
+ }
+ }
+}
+
void checkBackground () {
Shell shell = getShell ();
if (this == shell) return;
@@ -741,6 +749,7 @@
state |= DRAG_DETECT;
foreground = background = -1;
checkOrientation (parent);
+ checkAero ();
createHandle ();
checkBackground ();
checkBuffered ();
@@ -917,6 +926,10 @@
}
void drawBackground (int /*long*/ hDC, RECT rect) {
+ if ((style & SWT.TRIM_FILL) != 0) {
+ drawBackgroundBuffered(hDC, rect);
+ return;
+ }
drawBackground (hDC, rect, -1, 0, 0);
}
@@ -944,6 +957,18 @@
fillBackground (hDC, pixel, rect);
}
+void drawBackgroundBuffered (int /*long*/ hDC, RECT rect) {
+ BP_PAINTPARAMS params = new BP_PAINTPARAMS();
+ params.cbSize = BP_PAINTPARAMS.sizeof;
+ params.dwFlags = OS.BPPF_ERASE;
+
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(hDC, rect, OS.BPBF_TOPDOWNDIB, params, hdcBuffered);
+ OS.PatBlt(hdcBuffered[0], 0, 0, rect.right - rect.left, rect.bottom - rect.top, OS.BLACKNESS);
+ OS.BufferedPaintSetAlpha(hBufferedPaint, rect, (byte)0x00);
+ OS.EndBufferedPaint(hBufferedPaint, true);
+}
+
void drawImageBackground (int /*long*/ hDC, int /*long*/ hwnd, int /*long*/ hBitmap, RECT rect, int tx, int ty) {
RECT rect2 = new RECT ();
OS.GetClientRect (hwnd, rect2);
@@ -1192,6 +1217,7 @@
}
int getBackgroundPixel () {
+ if ((style & SWT.TRIM_FILL) != 0 && !getBufferredPaint ()) return 0x0;
return background != -1 ? background : defaultBackground ();
}
@@ -1241,6 +1267,10 @@
return new Rectangle (rect.left, rect.top, width, height);
}
+boolean getBufferredPaint() {
+ return false;
+}
+
int getCodePage () {
if (OS.IsUnicode) return OS.CP_ACP;
int /*long*/ hFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
@@ -5087,6 +5117,7 @@
}
LRESULT WM_PAINT (int /*long*/ wParam, int /*long*/ lParam) {
+ if (getBufferredPaint ()) return wmBufferedPaint (handle, wParam, lParam);
return wmPaint (handle, wParam, lParam);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
index 0bf70ee..86ead1f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
@@ -155,14 +155,17 @@
}
/* XP Themes */
- int /*long*/ hButtonTheme, hEditTheme, hExplorerBarTheme, hScrollBarTheme, hTabTheme;
+ int /*long*/ hButtonTheme, hCompositedWindowTheme, hControlPanelStyleTheme, hEditTheme, hExplorerBarTheme, hScrollBarTheme, hTabTheme, hToolbarTheme;
static final char [] BUTTON = new char [] {'B', 'U', 'T', 'T', 'O', 'N', 0};
+ static final char [] COMPOSITEDWINDOW = new char [] {'C', 'O', 'M', 'P', 'O', 'S', 'I', 'T', 'E', 'D', 'W', 'I', 'N', 'D', 'O', 'W', ':', ':', 'W', 'I', 'N', 'D', 'O', 'W', 0};
+ static final char [] CONTROLPANELSTYLE = new char [] {'C', 'O', 'N', 'T', 'R', 'O', 'L', 'P', 'A', 'N', 'E', 'L', 'S', 'T', 'Y', 'L', 'E', 0};
static final char [] EDIT = new char [] {'E', 'D', 'I', 'T', 0};
static final char [] EXPLORER = new char [] {'E', 'X', 'P', 'L', 'O', 'R', 'E', 'R', 0};
static final char [] EXPLORERBAR = new char [] {'E', 'X', 'P', 'L', 'O', 'R', 'E', 'R', 'B', 'A', 'R', 0};
static final char [] SCROLLBAR = new char [] {'S', 'C', 'R', 'O', 'L', 'L', 'B', 'A', 'R', 0};
static final char [] LISTVIEW = new char [] {'L', 'I', 'S', 'T', 'V', 'I', 'E', 'W', 0};
static final char [] TAB = new char [] {'T', 'A', 'B', 0};
+ static final char [] TOOLBAR = new char [] {'T', 'O', 'O', 'L', 'B', 'A', 'R', 0};
static final char [] TREEVIEW = new char [] {'T', 'R', 'E', 'E', 'V', 'I', 'E', 'W', 0};
/* Focus */
@@ -2625,6 +2628,16 @@
return hButtonTheme = OS.OpenThemeData (hwndMessage, BUTTON);
}
+int /*long*/ hControlPanelStyleTheme () {
+ if (hControlPanelStyleTheme != 0) return hControlPanelStyleTheme;
+ return hControlPanelStyleTheme = OS.OpenThemeData (hwndMessage, CONTROLPANELSTYLE);
+}
+
+int /*long*/ hCompositedWindowTheme () {
+ if (hCompositedWindowTheme != 0) return hCompositedWindowTheme;
+ return hCompositedWindowTheme = OS.OpenThemeData (hwndMessage, COMPOSITEDWINDOW);
+}
+
int /*long*/ hEditTheme () {
if (hEditTheme != 0) return hEditTheme;
return hEditTheme = OS.OpenThemeData (hwndMessage, EDIT);
@@ -2645,6 +2658,11 @@
return hTabTheme = OS.OpenThemeData (hwndMessage, TAB);
}
+int /*long*/ hToolbarTheme () {
+ if (hToolbarTheme != 0) return hToolbarTheme;
+ return hToolbarTheme = OS.OpenThemeData (hwndMessage, TOOLBAR);
+}
+
/**
* Invokes platform specific functionality to allocate a new GC handle.
* <p>
@@ -3336,11 +3354,14 @@
case OS.WM_THEMECHANGED: {
if (OS.COMCTL32_MAJOR >= 6) {
if (hButtonTheme != 0) OS.CloseThemeData (hButtonTheme);
+ if (hControlPanelStyleTheme != 0) OS.CloseThemeData (hControlPanelStyleTheme);
+ if (hCompositedWindowTheme != 0) OS.CloseThemeData (hCompositedWindowTheme);
if (hEditTheme != 0) OS.CloseThemeData (hEditTheme);
if (hExplorerBarTheme != 0) OS.CloseThemeData (hExplorerBarTheme);
if (hScrollBarTheme != 0) OS.CloseThemeData (hScrollBarTheme);
if (hTabTheme != 0) OS.CloseThemeData (hTabTheme);
- hButtonTheme = hEditTheme = hExplorerBarTheme = hScrollBarTheme = hTabTheme = 0;
+ if (hToolbarTheme != 0) OS.CloseThemeData (hToolbarTheme);
+ hButtonTheme = hControlPanelStyleTheme = hCompositedWindowTheme = hEditTheme = hExplorerBarTheme = hScrollBarTheme = hTabTheme = hToolbarTheme = 0;
}
break;
}
@@ -3828,11 +3849,14 @@
/* Release XP Themes */
if (OS.COMCTL32_MAJOR >= 6) {
if (hButtonTheme != 0) OS.CloseThemeData (hButtonTheme);
+ if (hControlPanelStyleTheme != 0) OS.CloseThemeData (hControlPanelStyleTheme);
+ if (hCompositedWindowTheme != 0) OS.CloseThemeData (hCompositedWindowTheme);
if (hEditTheme != 0) OS.CloseThemeData (hEditTheme);
if (hExplorerBarTheme != 0) OS.CloseThemeData (hExplorerBarTheme);
if (hScrollBarTheme != 0) OS.CloseThemeData (hScrollBarTheme);
if (hTabTheme != 0) OS.CloseThemeData (hTabTheme);
- hButtonTheme = hEditTheme = hExplorerBarTheme = hScrollBarTheme = hTabTheme = 0;
+ if (hToolbarTheme != 0) OS.CloseThemeData (hToolbarTheme);
+ hButtonTheme = hControlPanelStyleTheme = hCompositedWindowTheme = hEditTheme = hExplorerBarTheme = hScrollBarTheme = hTabTheme = hToolbarTheme = 0;
}
/* Unhook the message hook */
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 f32a57b..22ab3c0 100644
--- 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
@@ -223,6 +223,15 @@
return SWT.LEFT;
}
+boolean getBufferredPaint() {
+ Shell shell = getShell ();
+ if ((shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0) {
+ // if (image != null) return false;//note: can't be transparent for all images...
+ return true;//bad: should be transparent with custom draw
+ }
+ return false;
+}
+
/**
* Returns the receiver's image if it has one, or null
* if it does not.
@@ -406,6 +415,7 @@
}
if ((style & SWT.CENTER) != 0) newBits |= OS.SS_CENTER;
if ((style & SWT.RIGHT) != 0) newBits |= OS.SS_RIGHT;
+ if ((style & SWT.TRIM_FILL) != 0) newBits |= OS.SS_OWNERDRAW; // if glass is turned on, text-only labels need to be owner-drawn as well
if (oldBits != newBits) OS.SetWindowLong (handle, OS.GWL_STYLE, newBits);
}
string = Display.withCrLf (string);
@@ -527,6 +537,11 @@
return result;
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ // Label widgets are owner-drawn, so this is a no-op
+ return null; // return null so that wmDrawChild gets invoked
+}
+
LRESULT wmColorChild (int /*long*/ wParam, int /*long*/ lParam) {
/*
* Bug in Windows. For some reason, the HBRUSH that
@@ -636,7 +651,7 @@
int height = struct.bottom - struct.top;
if (width != 0 && height != 0) {
boolean drawImage = image != null;
- boolean drawText = IMAGE_AND_TEXT && text.length () != 0;
+ boolean drawText = text.length () != 0 && (image == null || IMAGE_AND_TEXT);
int margin = drawText && drawImage ? MARGIN : 0;
int imageWidth = 0, imageHeight = 0;
if (drawImage) {
@@ -686,7 +701,13 @@
rect.right += rect.left;
rect.top = Math.max (0, (height - textHeight) / 2);
rect.bottom += rect.top;
- OS.DrawText (struct.hDC, buffer, -1, rect, flags);
+ if ((style & SWT.TRIM_FILL) == 0) {
+ OS.DrawText (struct.hDC, buffer, -1, rect, flags);
+ } else {
+ int /*long*/ hFont = OS.SendMessage(this.handle, OS.WM_GETFONT, 0, 0);
+ int color = 0x000000;
+ drawBufferredText(struct.hDC, buffer, rect, hFont, color, flags);
+ }
}
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java
index caa5188..b755b99 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Link.java
@@ -154,7 +154,7 @@
int /*long*/ callWindowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
if (handle == 0) return 0;
- if (LinkProc != 0) {
+ if (LinkProc != 0 && !getBufferredPaint()) {
/*
* Feature in Windows. By convention, native Windows controls
* check for a non-NULL wParam, assume that it is an HDC and
@@ -179,7 +179,7 @@
if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
int width, height;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
int /*long*/ hDC = OS.GetDC (handle);
int /*long*/ newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
int /*long*/ oldFont = OS.SelectObject (hDC, newFont);
@@ -229,7 +229,7 @@
void createHandle () {
super.createHandle ();
state |= THEME_BACKGROUND;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
layout = new TextLayout (display);
if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (4, 10)) {
linkColor = Color.win32_new (display, OS.GetSysColor (OS.COLOR_HOTLIGHT));
@@ -248,7 +248,7 @@
void createWidget () {
super.createWidget ();
text = "";
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if ((style & SWT.MIRRORED) != 0) {
layout.setOrientation (SWT.RIGHT_TO_LEFT);
}
@@ -256,6 +256,43 @@
}
}
+void drawBufferredTextRun(int /*long*/ targetDC, String parsedText, int runStart, int runEnd, int /*long*/ hFont) {
+ if (runStart >= runEnd)
+ return;
+
+ int color = 0x000000;
+ boolean underline = false;
+ TextStyle style = layout.getStyle(runStart);
+ if (style != null) {
+ if (style.foreground != null) {
+ color = style.foreground.handle;
+ }
+ underline = style.underline;
+ }
+
+ if (underline) {
+ LOGFONT logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW () : new LOGFONTA ();
+ OS.GetObject(hFont, LOGFONT.sizeof, logFont);
+ logFont.lfUnderline = 0x01;
+ hFont = OS.CreateFontIndirect(logFont);
+ }
+
+ Rectangle bounds = layout.getBounds(runStart, runEnd-1);
+ String runText = parsedText.substring(runStart, runEnd);
+ TCHAR runBuffer = new TCHAR (getCodePage (), runText, true);
+
+ RECT drawRect = new RECT();
+ drawRect.left = bounds.x;
+ drawRect.top = bounds.y;
+ drawRect.right = bounds.x + bounds.width;
+ drawRect.bottom = bounds.y + bounds.height;
+ drawBufferredText(targetDC, runBuffer, drawRect, hFont, color, 0);
+
+ if (underline) {
+ OS.DeleteObject(hFont);
+ }
+}
+
void drawWidget (GC gc, RECT rect) {
drawBackground (gc.handle, rect);
int selStart = selection.x;
@@ -288,7 +325,7 @@
}
void enableWidget (boolean enabled) {
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
LITEM item = new LITEM ();
item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
item.stateMask = OS.LIS_ENABLED;
@@ -363,6 +400,14 @@
});
}
+boolean getBufferredPaint() {
+ Shell shell = getShell ();
+ if ((shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0) {
+ return true;
+ }
+ return false;
+}
+
String getNameText () {
return getText ();
}
@@ -421,7 +466,7 @@
char mnemonic = parsedText.charAt(mnemonics[i]);
if (uckey == Character.toUpperCase (mnemonic)) {
if (!setFocus ()) return false;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
LITEM item = new LITEM ();
item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
@@ -695,7 +740,7 @@
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
if (string.equals (text)) return;
text = string;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
boolean enabled = OS.IsWindowEnabled (handle);
/*
* Bug in Windows. For some reason, when SetWindowText()
@@ -744,17 +789,17 @@
}
TCHAR windowClass () {
- return OS.COMCTL32_MAJOR >= 6 ? LinkClass : display.windowClass;
+ return OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint() ? LinkClass : display.windowClass;
}
int /*long*/ windowProc () {
- return LinkProc != 0 ? LinkProc : display.windowProc;
+ return LinkProc != 0 && !getBufferredPaint() ? LinkProc : display.windowProc;
}
LRESULT WM_CHAR (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_CHAR (wParam, lParam);
if (result != null) return result;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if (focusIndex == -1) return result;
switch ((int)/*64*/wParam) {
case ' ':
@@ -802,7 +847,7 @@
if (result != null) return result;
int index, count;
int /*long*/ code = 0;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
LITEM item = new LITEM ();
item.mask = OS.LIF_ITEMINDEX | OS.LIF_STATE;
item.stateMask = OS.LIS_FOCUSED;
@@ -844,7 +889,7 @@
LRESULT WM_KEYDOWN (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_KEYDOWN (wParam, lParam);
if (result != null) return result;
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
switch ((int)/*64*/wParam) {
case OS.VK_SPACE:
case OS.VK_RETURN:
@@ -863,14 +908,14 @@
LRESULT WM_KILLFOCUS (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_KILLFOCUS (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) redraw ();
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) redraw ();
return result;
}
LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_LBUTTONDOWN (wParam, lParam);
if (result == LRESULT.ZERO) return result;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if (focusIndex != -1) setFocus ();
int x = OS.GET_X_LPARAM (lParam);
int y = OS.GET_Y_LPARAM (lParam);
@@ -908,7 +953,7 @@
LRESULT WM_LBUTTONUP (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_LBUTTONUP (wParam, lParam);
if (result == LRESULT.ZERO) return result;
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
if (mouseDownIndex == -1) return result;
int x = OS.GET_X_LPARAM (lParam);
int y = OS.GET_Y_LPARAM (lParam);
@@ -936,14 +981,14 @@
* 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);
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) return new LRESULT (OS.HTCLIENT);
return result;
}
LRESULT WM_MOUSEMOVE (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_MOUSEMOVE (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
int x = OS.GET_X_LPARAM (lParam);
int y = OS.GET_Y_LPARAM (lParam);
if (OS.GetKeyState (OS.VK_LBUTTON) < 0) {
@@ -1000,7 +1045,7 @@
LRESULT WM_PRINTCLIENT (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_PRINTCLIENT (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
RECT rect = new RECT ();
OS.GetClientRect (handle, rect);
GCData data = new GCData ();
@@ -1015,12 +1060,12 @@
LRESULT WM_SETFOCUS (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_SETFOCUS (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) redraw ();
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) redraw ();
return result;
}
LRESULT WM_SETFONT (int /*long*/ wParam, int /*long*/ lParam) {
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
layout.setFont (Font.win32_new (display, wParam));
}
if (lParam != 0) OS.InvalidateRect (handle, null, true);
@@ -1029,7 +1074,7 @@
LRESULT WM_SIZE (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.WM_SIZE (wParam, lParam);
- if (OS.COMCTL32_MAJOR < 6) {
+ if (OS.COMCTL32_MAJOR < 6 || getBufferredPaint()) {
RECT rect = new RECT ();
OS.GetClientRect (handle, rect);
layout.setWidth (rect.right > 0 ? rect.right : -1);
@@ -1038,6 +1083,75 @@
return result;
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ int /*long*/ paintDC = OS.BeginPaint (hWnd, ps);
+
+ RECT rect = new RECT();
+ OS.GetClientRect(hWnd, rect);
+
+ BP_PAINTPARAMS params = new BP_PAINTPARAMS();
+ params.cbSize = BP_PAINTPARAMS.sizeof;
+ params.dwFlags = OS.BPPF_ERASE;
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(paintDC, rect, OS.BPBF_TOPDOWNDIB, params, hdcBuffered);
+
+ if (hdcBuffered[0] != 0) {
+ String parsedText = parse (text);
+ int /*long*/ hFont = OS.SendMessage(this.handle, OS.WM_GETFONT, 0, 0);
+ int /*long*/ prevFont = OS.SelectObject(hdcBuffered[0], hFont);
+
+ int [] styleOffsets = layout.getRanges();
+ int [] lineOffsets = layout.getLineOffsets();
+ for (int i=1; i<styleOffsets.length; i+=2) {
+ styleOffsets[i]++; // every other offset in incremented by 1
+ }
+
+ int nextLine = 1;
+ for (int i=0; i<=styleOffsets.length; i++) {
+ int runStart = (i > 0) ? styleOffsets [i-1] : 0;
+ int runEnd = (i < styleOffsets.length) ? styleOffsets[i] : parsedText.length();
+
+ // skip leading whitespace characters since the lineOffsets from TextLayout have already done likewise
+ while(runStart < runEnd && Character.isWhitespace(parsedText.charAt(runStart))) {
+ runStart++;
+ }
+
+ // see if we have exceeeded the extents of the current line, and if so draw the truncated text run
+ if (nextLine < lineOffsets.length && lineOffsets[nextLine] < runEnd) {
+ int truncated = lineOffsets[nextLine];
+ drawBufferredTextRun(hdcBuffered[0], parsedText, runStart, truncated, hFont);
+
+ // move to the beginning of the next line
+ runStart = lineOffsets[nextLine];
+ nextLine++;
+ }
+
+ drawBufferredTextRun(hdcBuffered[0], parsedText, runStart, runEnd, hFont);
+ }
+
+ if (hasFocus () && focusIndex != -1) {
+ Rectangle [] rects = getRectangles (focusIndex);
+ for (int i = 0; i < rects.length; i++) {
+ Rectangle rectangle = rects [i];
+ RECT focusRect = new RECT();
+ focusRect.left = rectangle.x;
+ focusRect.top = rectangle.y;
+ focusRect.right = rectangle.x + rectangle.width;
+ focusRect.bottom = rectangle.y + rectangle.height;
+
+ OS.DrawFocusRect (hdcBuffered[0], focusRect);
+ }
+ }
+
+ OS.SelectObject(hdcBuffered[0], prevFont);
+ OS.EndBufferedPaint(hBufferedPaint, true);
+ }
+
+ OS.EndPaint (handle, ps);
+ return LRESULT.ZERO;
+}
+
LRESULT wmColorChild (int /*long*/ wParam, int /*long*/ lParam) {
LRESULT result = super.wmColorChild (wParam, lParam);
/*
@@ -1045,7 +1159,7 @@
* not gray out the non-link portion of the text. The fix
* is to set the text color to the system gray color.
*/
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
if (!OS.IsWindowEnabled (handle)) {
OS.SetTextColor (wParam, OS.GetSysColor (OS.COLOR_GRAYTEXT));
if (result == null) {
@@ -1060,7 +1174,7 @@
}
LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
- if (OS.COMCTL32_MAJOR >= 6) {
+ if (OS.COMCTL32_MAJOR >= 6 && !getBufferredPaint()) {
switch (hdr.code) {
case OS.NM_RETURN:
case OS.NM_CLICK:
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ProgressBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ProgressBar.java
index d2bf5f0..c39f900 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ProgressBar.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ProgressBar.java
@@ -146,6 +146,11 @@
return OS.GetSysColor (OS.COLOR_HIGHLIGHT);
}
+boolean getBufferredPaint () {
+ Shell shell = getShell ();
+ return (shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0;
+}
+
/**
* Returns the maximum value which the receiver will allow.
*
@@ -449,4 +454,34 @@
return result;
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ int /*long*/ paintDC = 0;
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ paintDC = OS.BeginPaint (hWnd, ps);
+
+ RECT rect = new RECT();
+ OS.GetClientRect (hWnd, rect);
+
+ // set up the buffered device context - the alpha will be set to 100%, making the device context entirely opaque
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint (paintDC, rect, OS.BPBF_TOPDOWNDIB, null, hdcBuffered);
+
+ if (hdcBuffered [0] != 0) {
+ // ask the ProgressBar control to render itself into the buffered device context, entirely opaquely
+ OS.SendMessage (handle, OS.WM_PRINTCLIENT, hdcBuffered[0], OS.PRF_CLIENT);
+ OS.BufferedPaintSetAlpha (hBufferedPaint, rect, (byte)0xFF);
+
+ // round off the corners by drawing them as transparent single pixels
+ OS.SetPixel (hdcBuffered [0], 0, 0, 0x00);
+ OS.SetPixel (hdcBuffered [0], 0, rect.bottom-1, 0x00);
+ OS.SetPixel (hdcBuffered [0], rect.right-1, 0, 0x00);
+ OS.SetPixel (hdcBuffered [0], rect.right-1, rect.bottom-1, 0x00);
+
+ OS.EndBufferedPaint (hBufferedPaint, true);
+ }
+
+ OS.EndPaint (handle, ps);
+ return LRESULT.ZERO;
+}
+
}
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 eb6a6ac..b4e3090 100644
--- 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
@@ -145,6 +145,7 @@
OS.GetClassInfo (0, DialogClass, lpWndClass);
DialogProc = lpWndClass.lpfnWndProc;
}
+ static final String GLASS_MARGINS = "GlassMargins"; //$NON-NLS-1$
/**
* Constructs a new instance of this class. This is equivalent
@@ -518,6 +519,20 @@
setLocation (x, y);
}
+void checkAero () {
+ if ((style & SWT.TRIM_FILL) != 0) {
+ if (OS.WIN32_VERSION < OS.VERSION (6, 0)) {
+ style &= ~SWT.TRIM_FILL;
+ } else {
+ boolean [] pfEnabled = new boolean [1];
+ OS.DwmIsCompositionEnabled (pfEnabled);
+ if (!pfEnabled[0]) {
+ style &= ~SWT.TRIM_FILL;
+ }
+ }
+ }
+}
+
/**
* Requests that the window manager close the receiver in
* the same way it would be closed when the user clicks on
@@ -619,6 +634,13 @@
psai.cbSize = SHACTIVATEINFO.sizeof;
}
}
+
+ if ((style & SWT.TRIM_FILL) != 0) {
+ MARGINS margin = new MARGINS ();
+ margin.cxLeftWidth = margin.cxRightWidth = margin.cyTopHeight = margin.cyBottomHeight = -1;
+ OS.DwmExtendFrameIntoClientArea (handle, margin);
+ }
+
if (OS.IsDBLocale) {
hIMC = OS.ImmCreateContext ();
if (hIMC != 0) OS.ImmAssociateContext (handle, hIMC);
@@ -1499,6 +1521,15 @@
super.setBounds (x, y, width, height, flags, false);
}
+public void setData (String key, Object value) {
+ super.setData (key, value);
+ if (key.equals (GLASS_MARGINS)) {
+ if (value != null && value instanceof MARGINS) {
+ OS.DwmExtendFrameIntoClientArea (handle, (MARGINS) value);
+ }
+ }
+}
+
public void setEnabled (boolean enabled) {
checkWidget ();
if (((state & DISABLED) == 0) == enabled) return;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
index d91cfd0..61b165e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
@@ -56,7 +56,7 @@
*/
public class Text extends Scrollable {
int tabs, oldStart, oldEnd;
- boolean doubleClick, ignoreModify, ignoreVerify, ignoreCharacter, allowPasswordChar;
+ boolean doubleClick, ignoreModify, ignoreVerify, ignoreCharacter, ignoreColorChild, allowPasswordChar;
String message;
/**
@@ -662,6 +662,11 @@
return super.getBorderWidth ();
}
+boolean getBufferredPaint () {
+ Shell shell = getShell ();
+ return (shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0;
+}
+
/**
* Returns the line number of the caret.
* <p>
@@ -2490,6 +2495,35 @@
return wmClipboard (OS.WM_UNDO, wParam, lParam);
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ int /*long*/ paintDC = 0;
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ paintDC = OS.BeginPaint (hWnd, ps);
+
+ RECT rect = new RECT();
+ OS.GetClientRect (hWnd, rect);
+
+ // set up the buffered device context - the alpha will be set to 100%, making the device context entirely opaque
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint (paintDC, rect, OS.BPBF_TOPDOWNDIB, null, hdcBuffered);
+
+ if (hdcBuffered[0] != 0) {
+ // ask the Edit control to render itself into the buffered device context; note that this will result in
+ // the Edit control issuing a WM_CTLCOLOREDIT message and we need to set the 'bPrintingClient' flag to prevent
+ // a perpetual paint sequence from being triggered
+ ignoreColorChild = true;
+ OS.SendMessage (handle, OS.WM_PRINTCLIENT, hdcBuffered [0], OS.PRF_CLIENT);
+ ignoreColorChild = false;
+
+ // entirely opaque
+ OS.BufferedPaintSetAlpha (hBufferedPaint, rect, (byte)0xFF);
+ OS.EndBufferedPaint (hBufferedPaint, true);
+ }
+
+ OS.EndPaint (handle, ps);
+ return LRESULT.ZERO;
+}
+
LRESULT wmClipboard (int msg, int /*long*/ wParam, int /*long*/ lParam) {
if ((style & SWT.READ_ONLY) != 0) return null;
if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return null;
@@ -2588,6 +2622,16 @@
}
}
}
+
+ // a WM_CTLCOLOREDIT message is issued by the Win32 Edit control whenever it's about to be redrawn; the
+ // Control#windowProc routes that message into here, and if glass is turned on we invalidate the window to
+ // trigger a glass-aware repaint of the control
+ if (!ignoreColorChild && getBufferredPaint ()) {
+ RECT lpRect = new RECT ();
+ OS.GetClientRect (handle, lpRect);
+ OS.InvalidateRect (handle, lpRect, false);
+ }
+
return super.wmColorChild (wParam, lParam);
}
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 9cb33cf..e873d6c 100644
--- 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
@@ -478,6 +478,11 @@
}
}
+boolean getBufferredPaint () {
+ Shell shell = getShell ();
+ return (shell.style & SWT.TRIM_FILL) != 0 && (style & SWT.TRIM_FILL) != 0;
+}
+
ImageList getDisabledImageList () {
return disabledImageList;
}
@@ -1493,6 +1498,11 @@
return result;
}
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ // toolbar items are owner-draw during buffered painting
+ return null;
+}
+
LRESULT wmCommandChild (int /*long*/ wParam, int /*long*/ lParam) {
ToolItem child = items [OS.LOWORD (wParam)];
if (child == null) return null;
@@ -1531,6 +1541,14 @@
// }
switch (nmcd.dwDrawStage) {
case OS.CDDS_PREERASE: {
+ if (getBufferredPaint ()) {
+ // if buffered painting is on, erase the background the Aero/Glass way
+ RECT rect = new RECT ();
+ OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
+ drawBackground (nmcd.hdc, rect);
+ return new LRESULT (OS.CDRF_SKIPDEFAULT);
+ }
+
/*
* Bug in Windows. When a tool bar does not have the style
* TBSTYLE_FLAT, the rectangle to be erased in CDDS_PREERASE
@@ -1546,6 +1564,25 @@
}
return new LRESULT (OS.CDRF_SKIPDEFAULT);
}
+ case OS.CDDS_PREPAINT: {
+ if (getBufferredPaint ()) {
+ // this will trigger the CDDS_ITEMPREPAINT notifications so that we can draw each
+ // ToolItem individually
+ return new LRESULT (OS.CDRF_NOTIFYITEMDRAW);
+ }
+ break;
+ }
+ case OS.CDDS_ITEMPREPAINT: {
+ if (getBufferredPaint ()) {
+ // each ToolItem knows how to draw itself in an Aero/Glass friendly manner
+ ToolItem childItem = items [(int)/*64*/nmcd.dwItemSpec];
+ if (childItem != null) {
+ childItem.wmBufferedPaint (handle, wParam, lParam);
+ }
+ return new LRESULT (OS.CDRF_SKIPDEFAULT);
+ }
+ break;
+ }
}
break;
case OS.TBN_HOTITEMCHANGE:
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
index c8caddb..3bb6c11 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
@@ -46,6 +46,9 @@
int id;
short cx;
+ // added to support the owner-draw operations performed in an Aero/Glass environment
+ static final int OWNERDRAW_MARGIN = 4;
+
/**
* Constructs a new instance of this class given its parent
* (which must be a <code>ToolBar</code>) and a style value
@@ -220,6 +223,37 @@
releaseHandle ();
}
+/*
+ * Draws the outline of the ToolItem. This will make the ToolItem appear as pressed, checked, hot or normal depending
+ * on the UI state of the toolbar item.
+ * @param hDC - device context to paint in
+ * @param nmcd - the NMCUSTOMDRAW structure passed into owner-draw toolbar items
+ */
+void drawItemOutline (int /*long*/ hDC, NMCUSTOMDRAW nmcd) {
+ RECT rectClient = new RECT ();
+ OS.SetRect (rectClient, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
+
+ // setup the theme parameters
+ int /*long*/ hTheme = display.hToolbarTheme ();
+ int btnState = getButtonState (nmcd);
+
+ // draw the button outline, depending on if it's a regular button or a drop-down button
+ if ((style & SWT.DROP_DOWN) != 0) {
+ // drop-down button: left half is a button with a right edge that is not rounded
+ int dropDownWidth = OS.GetSystemMetrics (OS.SM_CXVSCROLL);
+ rectClient.right -= dropDownWidth;
+ OS.DrawThemeBackground (hTheme, hDC, OS.TP_SPLITBUTTON, btnState, rectClient, null);
+
+ // drop-down button: right half is where the arrow is drawn
+ rectClient.left = rectClient.right;
+ rectClient.right += dropDownWidth;
+ OS.DrawThemeBackground (hTheme, hDC, OS.TP_SPLITBUTTONDROPDOWN, btnState, rectClient, null);
+ } else {
+ // regular button
+ OS.DrawThemeBackground (hTheme, hDC, OS.TP_BUTTON, btnState, rectClient, null);
+ }
+}
+
/**
* Returns a rectangle describing the receiver's size and location
* relative to its parent.
@@ -242,6 +276,24 @@
return new Rectangle (rect.left, rect.top, width, height);
}
+int getButtonState (NMCUSTOMDRAW nmcd) {
+ int btnState = OS.TS_NORMAL;
+
+ // translate the button state depending on the incoming item state
+ if ((nmcd.uItemState & OS.CDIS_HOT) != 0 && (nmcd.uItemState & OS.CDIS_CHECKED) != 0) {
+ btnState = OS.TS_HOTCHECKED;
+ } else if ((nmcd.uItemState & OS.CDIS_HOT) != 0 && (nmcd.uItemState & OS.CDIS_SELECTED) != 0) {
+ btnState = OS.TS_PRESSED;
+ } else if ((nmcd.uItemState & OS.CDIS_HOT) != 0) {
+ btnState = OS.TS_HOT;
+ } else if ((nmcd.uItemState & OS.CDIS_SELECTED) != 0) {
+ btnState = OS.TS_PRESSED;
+ } else if ((nmcd.uItemState & OS.CDIS_CHECKED) != 0) {
+ btnState = OS.TS_CHECKED;
+ }
+ return btnState;
+}
+
/**
* Returns the control that is used to fill the bounds of
* the item when the item is a <code>SEPARATOR</code>.
@@ -1008,6 +1060,115 @@
return OS.BTNS_BUTTON;
}
+/*
+ * Owner-draw painting of the ToolItem. Used in a shell where Aero/Glass painting has been turned on.
+ */
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ // cast the lParam into a NMCUSTOMDRAW structure
+ NMCUSTOMDRAW nmcd = new NMCUSTOMDRAW ();
+ OS.MoveMemory (nmcd, lParam, NMCUSTOMDRAW.sizeof);
+ int /*long*/ hDC = nmcd.hdc;
+ RECT rectClient = new RECT ();
+ OS.SetRect (rectClient, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
+
+ // setup the constants that are used during drawing
+ final boolean drawImage = image != null;
+ final boolean drawText = text.length () != 0;
+ final boolean drawTextBelow = (parent.style & SWT.RIGHT) == 0;
+ final boolean drawDepressed = getButtonState(nmcd) == OS.TS_HOTCHECKED || getButtonState(nmcd) == OS.TS_CHECKED || getButtonState(nmcd) == OS.TS_PRESSED;
+ final int margin = drawText && drawImage && !drawTextBelow ? OWNERDRAW_MARGIN : 0;
+ final int width = rectClient.right - rectClient.left;
+ final int height = rectClient.bottom - rectClient.top;
+ final TCHAR textBuffer = new TCHAR (parent.getCodePage (), text, true);
+
+ // determine the image width and height
+ int imageWidth = 0, imageHeight = 0;
+ if (drawImage) {
+ Rectangle imageRect = image.getBounds ();
+ imageWidth = imageRect.width;
+ imageHeight = imageRect.height;
+ }
+
+ // determine the text width and height
+ int textWidth = 0, textHeight = 0, flags = 0;
+ if (drawText) {
+ RECT rect2 = 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;
+ rect2.right = Math.max (0, width - imageWidth - margin);
+ }
+ OS.DrawText (hDC, textBuffer, -1, rect2, flags);
+ textWidth = rect2.right - rect2.left;
+ textHeight = rect2.bottom - rect2.top;
+ }
+
+ // calculate the image (x,y) coordinate
+ int x = rectClient.left;
+ int y = rectClient.top;
+ if (drawTextBelow) {
+ x += Math.max (0, (width - imageWidth) / 2);
+ y += Math.max (0, (height - imageHeight - textHeight) / 2);
+ } else if ((style & SWT.CENTER) != 0) {
+ x += Math.max (0, (width - imageWidth - textWidth - margin) / 2);
+ y += Math.max (0, (height - imageHeight) / 2);
+ } else if ((style & SWT.RIGHT) != 0) {
+ x += width - imageWidth - textWidth - margin;
+ y += Math.max (0, (height - imageHeight) / 2);
+ } else {
+ x += margin;
+ y += Math.max (0, (height - imageHeight) / 2);
+ }
+ if (drawDepressed) {
+ x++;
+ y--;
+ }
+
+ // draw the image, if needed
+ if (drawImage) {
+ GCData data = new GCData();
+ data.device = display;
+ GC gc = GC.win32_new (hDC, data);
+ Image image = getEnabled () ? this.image : (disabledImage != null) ? disabledImage : this.image;
+ gc.drawImage (image, x, y);
+ gc.dispose ();
+ }
+
+ // calculate the text (x,y) coordinate
+ if (drawTextBelow) {
+ x = rectClient.left + OWNERDRAW_MARGIN;
+ y = height - textHeight - OWNERDRAW_MARGIN;
+ } else {
+ x += imageWidth + OWNERDRAW_MARGIN;
+ y = rectClient.top + Math.max (0, (height - textHeight) / 2);
+ }
+ if (drawDepressed) {
+ x++;
+ y--;
+ }
+
+ // draw the text, if needed
+ if (drawText) {
+ flags &= ~OS.DT_CALCRECT;
+ rectClient.left = x;
+ rectClient.right += rectClient.left;
+ rectClient.top = y;
+ rectClient.bottom += rectClient.top;
+
+ int color = 0x000000;
+ int /*long*/ hFont = OS.SendMessage(parent.handle, OS.WM_GETFONT, 0, 0);
+ drawBufferredText(hDC, textBuffer, rectClient, hFont, color, flags);
+ }
+
+ // draw the outline of the tool item
+ drawItemOutline(hDC, nmcd);
+
+ return LRESULT.ZERO;
+}
+
LRESULT wmCommandChild (int /*long*/ wParam, int /*long*/ lParam) {
if ((style & SWT.RADIO) != 0) {
if ((parent.getStyle () & SWT.NO_RADIO_GROUP) == 0) {
@@ -1017,5 +1178,4 @@
sendSelectionEvent (SWT.Selection);
return null;
}
-
-}
+}
\ No newline at end of file
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 65ceaa5..66d1d8c 100644
--- 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
@@ -456,6 +456,39 @@
return OS.DragDetect (hwnd, pt);
}
+void drawBufferredText (int /*long*/ targetDC, TCHAR textBuffer, RECT rect, int /*long*/ hFont, int color, int dwFlags) {
+ // set up the buffered device context - the background is painted entirely black and its alpha
+ // is set to zero, resulting in a device context that is 100% transparent (if nothing is drawn to this DC,
+ // the glass background will just render through)
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(targetDC, rect, OS.BPBF_TOPDOWNDIB, null, hdcBuffered);
+ OS.PatBlt (hdcBuffered [0], 0, 0, rect.right /* - rect.left */, rect.bottom /* - rect.top */, OS.BLACKNESS);
+ OS.BufferedPaintSetAlpha (hBufferedPaint, rect, (byte)0x00);
+
+ // setup the DTTOPTS structure for calling into DrawThemeTextEx - note how we call getThemeGlowSize()
+ // to apply a glow around the text we are drawing to enhance readability of the text against a glass background
+ DTTOPTS dttOpts = new DTTOPTS();
+ dttOpts.dwSize = DTTOPTS.sizeof;
+ dttOpts.dwFlags = OS.DTT_COMPOSITED | OS.DTT_GLOWSIZE | OS.DTT_TEXTCOLOR;
+ dttOpts.crText = color;
+ dttOpts.iGlowSize = getThemeGlowSize ();
+
+ OS.SetTextColor(hdcBuffered[0], color);
+ if (hFont != 0) {
+ hFont = OS.SelectObject(hdcBuffered[0], hFont);
+ }
+
+ // draw the text using the special DrawThemeTextEx call
+ int /*long*/ hTheme = display.hControlPanelStyleTheme();
+ OS.DrawThemeTextEx(hTheme, hdcBuffered[0], 0, 0, textBuffer.chars, textBuffer.length(), dwFlags, rect, dttOpts);
+
+ if (hFont != 0) {
+ OS.SelectObject(hdcBuffered[0], hFont);
+ }
+ OS.EndBufferedPaint(hBufferedPaint, true);
+
+}
+
/**
* Does whatever widget specific cleanup is required, and then
* uses the code in <code>SWTError.error</code> to handle the error.
@@ -641,6 +674,13 @@
return ""; //$NON-NLS-1$
}
+int getThemeGlowSize () {
+ int /*long*/ hTheme = display.hCompositedWindowTheme();
+ int [] glowSize = new int[1];
+ OS.GetThemeInt(hTheme, 0, 0, OS.TMT_TEXTGLOWSIZE, glowSize);
+ return glowSize[0] > 0 ? glowSize[0] : 12;
+}
+
/**
* Returns the receiver's style information.
* <p>
@@ -2222,6 +2262,53 @@
return null;
}
+LRESULT wmBufferedPaint (int /*long*/ hwnd, int /*long*/ wParam, int /*long*/ lParam) {
+ PAINTSTRUCT ps = new PAINTSTRUCT ();
+ int /*long*/ result = 0;
+ int /*long*/ hDC = OS.BeginPaint (hwnd, ps);
+ int width = ps.right - ps.left;
+ int height = ps.bottom - ps.top;
+ if (width != 0 && height != 0) {
+ RECT prcTarget = new RECT ();
+ OS.SetRect (prcTarget, ps.left, ps.top, ps.right, ps.bottom);
+ int /*long*/ [] phdc = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint (hDC, prcTarget, OS.BPBF_TOPDOWNDIB, null, phdc);
+ result = callWindowProc (hwnd, OS.WM_PAINT, phdc [0], lParam);
+ if (hooks (SWT.Paint) || filters (SWT.Paint)) {
+ //badness
+ GCData data = new GCData ();
+ data.device = display;
+ data.foreground = ((Control)this).getForegroundPixel ();
+ Control control = ((Control)this).findBackgroundControl ();
+ if (control == null) control = (Control)this;
+ data.background = control.getBackgroundPixel ();
+ data.font = Font.win32_new(display, OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0));
+ data.uiState = (int)/*64*/OS.SendMessage (hwnd, OS.WM_QUERYUISTATE, 0, 0);
+ //what about the clipping ?
+ GC gc = GC.win32_new (phdc [0], data);
+ if (gc != null) {
+ OS.HideCaret (hwnd);
+ Event event = new Event ();
+ event.gc = gc;
+ event.x = ps.left;
+ event.y = ps.top;
+ event.width = width;
+ event.height = height;
+ sendEvent (SWT.Paint, event);
+ // widget could be disposed at this point
+ event.gc = null;
+ gc.dispose ();
+ OS.ShowCaret (hwnd);
+ }
+ }
+ OS.BufferedPaintSetAlpha (hBufferedPaint, prcTarget, (byte) 255);
+ OS.EndBufferedPaint (hBufferedPaint, true);
+ }
+ OS.EndPaint (hDC, ps);
+ if (result == 0) return LRESULT.ZERO;
+ return new LRESULT (result);
+}
+
LRESULT wmPaint (int /*long*/ hwnd, int /*long*/ wParam, int /*long*/ lParam) {
/* Exit early - don't draw the background */