Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandr Miloslavskiy2018-11-06 10:26:35 +0000
committerNiraj Modi2018-11-15 11:10:56 +0000
commit2982c4163ff033b48acfa8f9135083028f1a0900 (patch)
tree92d7e43412c8bb65d3f50d803d5853bd95a66fe6
parent404282c8d749d625cedc905b6b7b3ba457ac6b7e (diff)
downloadeclipse.platform.swt-2982c4163ff033b48acfa8f9135083028f1a0900.tar.gz
eclipse.platform.swt-2982c4163ff033b48acfa8f9135083028f1a0900.tar.xz
eclipse.platform.swt-2982c4163ff033b48acfa8f9135083028f1a0900.zip
Bug 508634 - [Win32] READ_ONLY Combobox does not allow changing background or foreground color
Change internal undocumented state of combobox to draw in a better way Change-Id: I012a8a8fb4761ed9942d347780b0b9c7e1aca95d Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Combo.java70
1 files changed, 69 insertions, 1 deletions
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 cd8a14ed77..af22df8de4 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
@@ -67,6 +67,7 @@ public class Combo extends Composite {
String [] items = new String [0];
int[] segments;
int clearSegmentsCount = 0;
+ boolean stateFlagsUsable;
static final char LTR_MARK = '\u200e';
static final char RTL_MARK = '\u200f';
@@ -105,7 +106,11 @@ public class Combo extends Composite {
ComboProc = lpWndClass.lpfnWndProc;
}
-/**
+ /* Undocumented values. Remained the same at least between Win7 and Win10 */
+ static final int stateFlagsOffset = (C.PTR_SIZEOF == 8) ? 0x68 : 0x54;
+ static final int stateFlagsFirstPaint = 0x02000000;
+
+ /**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
* <p>
@@ -731,6 +736,8 @@ void createHandle () {
}
state &= ~(CANVAS | THEME_BACKGROUND);
+ stateFlagsUsable = stateFlagsTest();
+
/* Get the text and list window procs */
long /*int*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
if (hwndText != 0 && EditProc == 0) {
@@ -1519,6 +1526,37 @@ public void paste () {
OS.SendMessage (handle, OS.WM_PASTE, 0, 0);
}
+void stateFlagsAdd(int flags) {
+ final long /*int*/ tagCBoxPtr = OS.GetWindowLongPtr(handle, 0);
+ final long /*int*/ stateFlagsPtr = tagCBoxPtr + stateFlagsOffset;
+
+ int stateFlags[] = new int[1];
+ OS.MoveMemory(stateFlags, stateFlagsPtr, 4);
+ stateFlags[0] |= flags;
+ OS.MoveMemory(stateFlagsPtr, stateFlags, 4);
+}
+
+/*
+ * Verify that undocumented internal data is in expected location.
+ * The test is performed at creation time, when the value of state flags is predictable.
+ * For simplicity, only SWT.READ_ONLY combos are handled.
+ */
+boolean stateFlagsTest() {
+ final long /*int*/ tagCBoxPtr = OS.GetWindowLongPtr(handle, 0);
+ final long /*int*/ stateFlagsPtr = tagCBoxPtr + stateFlagsOffset;
+
+ int stateFlags[] = new int[1];
+ OS.MoveMemory(stateFlags, stateFlagsPtr, 4);
+
+ /*
+ * 0x00000002 is unknown
+ * 0x00002000 is set in WM_NCCREATE
+ * 0x00004000 means CBS_DROPDOWNLIST (SWT.READ_ONLY)
+ * 0x02000000 is set in WM_NCCREATE and reset after first WM_PAINT
+ */
+ return (stateFlags[0] == 0x02006002);
+}
+
@Override
void register () {
super.register ();
@@ -2770,6 +2808,36 @@ long /*int*/ windowProc (long /*int*/ hwnd, int msg, long /*int*/ wParam, long /
}
@Override
+LRESULT wmColorChild (long /*int*/ wParam, long /*int*/ lParam) {
+ LRESULT result = super.wmColorChild(wParam, lParam);
+
+ /*
+ * CBS_DROPDOWNLIST (SWT.READ_ONLY) comboboxes ignore results of WM_CTLCOLORxxx.
+ * This prevents SWT from setting custom background / text color.
+ * In Windows function 'comctl32!ComboBox_InternalUpdateEditWindow' there are two main branches:
+ * 'DrawThemeText' branch
+ * Ignores any SetTextColor / SetBkColor.
+ * Ignores brush returned from WM_CTLCOLORxxx.
+ * Keeps any background that was painted during WM_CTLCOLORxxx.
+ * 'ExtTextOut' branch
+ * Uses pre-selected SetTextColor / SetBkColor.
+ * Ignores brush returned from WM_CTLCOLORxxx.
+ * Overwrites background with color in SetBkColor.
+ * This undocumented hack forces combobox to use 'ExtTextOut' branch.
+ * The flag is reset after every WM_PAINT, so it's set in every WM_CTLCOLORxxx.
+ * Since 'ExtTextOut' always paints background, hack is not activated if not needed
+ * to avoid changes in visual appearance of comboboxes with default colors.
+ */
+ final boolean isReadonly = ((style & SWT.READ_ONLY) != 0);
+ final boolean isCustomColors = (result != null);
+ if (isReadonly && isCustomColors && stateFlagsUsable) {
+ stateFlagsAdd(stateFlagsFirstPaint);
+ }
+
+ return result;
+}
+
+@Override
LRESULT WM_CTLCOLOR (long /*int*/ wParam, long /*int*/ lParam) {
return wmColorChild (wParam, lParam);
}

Back to the top