summaryrefslogtreecommitdiff
path: root/alf/alfcombobox.cpp
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2019-01-03 23:57:56 +0100
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2019-01-03 23:57:56 +0100
commit9c385f9a366da308d2a37ad5deda5d40f9285abb (patch)
tree578f6739c8e99f61c0b8747502d8e133e585a7d0 /alf/alfcombobox.cpp
parentcd7b608f0517c1100f79b4a3ec654e4178373506 (diff)
extend compatibility to Win95 RTM, NT3.1 and Win32s
Only NT3.51 actually works mostly right, all others suffer from various kinds of breakage. Running a 3.1-compatible binary on newer windows enables some kind of compatibility mode with bizarro background brushes and weirdly sized combo boxes. Going forward, I'm committed to keep NT3.51 running as long as Win95RTM is supported. The future of NT3.1 and Win32s support is uncertain.
Diffstat (limited to 'alf/alfcombobox.cpp')
-rw-r--r--alf/alfcombobox.cpp46
1 files changed, 32 insertions, 14 deletions
diff --git a/alf/alfcombobox.cpp b/alf/alfcombobox.cpp
index 3007a20..8afdace 100644
--- a/alf/alfcombobox.cpp
+++ b/alf/alfcombobox.cpp
@@ -42,11 +42,15 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg == WM_CREATE) {
ALFComboCreateParams *params = (ALFComboCreateParams*)((CREATESTRUCT*)lParam)->lpCreateParams;
+ DWORD comboStyle = params->comboStyle;
+ if (LOBYTE(LOWORD(GetVersion())) >= 4)
+ comboStyle |= CBS_OWNERDRAWFIXED | CBS_HASSTRINGS;
+
HWND hwndCombo = CreateWindowEx(0,
TEXT("COMBOBOX"),
TEXT(""),
- WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | params->comboStyle,
- 0, 0, 0, 200 /* FIXME needed for commctl32 v5, what is the best value here? */,
+ WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | comboStyle,
+ 0, 0, 100, 200 /* FIXME needed for commctl32 v5, what is the best value here? */,
hwnd,
(HMENU) GetWindowLongPtrW(hwnd, GWLP_ID),
((CREATESTRUCT*)lParam)->hInstance,
@@ -121,7 +125,9 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
if (uMsg == WM_COMMAND && (HWND)lParam == hwndChild) {
- return SendMessage(GetParent(hwnd), WM_COMMAND, wParam, (LPARAM)hwnd);
+ // XXX: for whatever reason, Win95 (and only win95 - doesn't happen on NT)
+ // sends a wrong ID value in WPARAM. We fix it by replacing it with our own id.
+ return SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID), HIWORD(wParam)), (LPARAM)hwnd);
}
if (uMsg == ALF_WM_QUERYSIZE) {
@@ -218,15 +224,22 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg == WM_WINDOWPOSCHANGED && hwndChild) {
WINDOWPOS *pos = (WINDOWPOS *)lParam;
if (!(pos->flags & SWP_NOSIZE)) {
- RECT r;
- GetWindowRect(hwndChild, &r);
- SetWindowPos(hwndChild, NULL, 0, 1, pos->cx, r.bottom - r.top, SWP_NOZORDER|SWP_NOACTIVATE);
-
- SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)-1, pos->cy - 8);
-
- int h = ALF__ComboItemHeight(hwnd);
- if (h)
- SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, h);
+ // XXX: When resizing the combo box, it will improperly draw a selection.
+ // this appears to be a well-known bug that is still not fixed, even in Win10.
+ // workaround based on https://stackoverflow.com/questions/49603893/how-to-deal-with-invalidly-painted-combobox-control-in-win32-winapi
+ DWORD sel = SendMessage(hwndChild, CB_GETEDITSEL, 0, 0);
+ SendMessage(hwndChild, CB_SETEDITSEL, 0, -1);
+ // SWP_NOCOPYBITS because NT 3.51 doesn't properly repaint the drop-down button
+ SetWindowPos(hwndChild, NULL, 0, 1, pos->cx, 200, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
+ SendMessage(hwndChild, CB_SETEDITSEL, 0, (LPARAM)sel);
+
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)-1, pos->cy - 8);
+
+ int h = ALF__ComboItemHeight(hwnd);
+ if (h)
+ SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, h);
+ }
}
}
@@ -241,11 +254,16 @@ ALF_RegisterComboClass(ALFAPP app)
ZeroMemory(&cls, sizeof(cls));
TCHAR classNameBuf[256];
- ALF_BuildRandomClassName(TEXT("ALFComboBox."), classNameBuf);
+ ALF_BuildRandomClassName(app, TEXT("ALFComboBox."), classNameBuf);
cls.hInstance = app->hInstance;
cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
- cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ } else {
+ // NT 3.x has white dialog backgrounds
+ cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ }
cls.lpszClassName = classNameBuf;
cls.cbWndExtra = sizeof(void*)*2;
cls.lpfnWndProc = ALF__ComboWindowProc;