diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2019-01-03 23:57:56 +0100 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2019-01-03 23:57:56 +0100 |
| commit | 9c385f9a366da308d2a37ad5deda5d40f9285abb (patch) | |
| tree | 578f6739c8e99f61c0b8747502d8e133e585a7d0 /alf/alfcombobox.cpp | |
| parent | cd7b608f0517c1100f79b4a3ec654e4178373506 (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.cpp | 46 |
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; |
