From 9c385f9a366da308d2a37ad5deda5d40f9285abb Mon Sep 17 00:00:00 2001 From: Jonas Kümmerlin Date: Thu, 3 Jan 2019 23:57:56 +0100 Subject: 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. --- alf/alfcombobox.cpp | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'alf/alfcombobox.cpp') 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; -- cgit v1.2.3