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&lt;&lt;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 */