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/alf.cpp | 116 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 37 deletions(-) (limited to 'alf/alf.cpp') diff --git a/alf/alf.cpp b/alf/alf.cpp index 6936436..aef4167 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -1,6 +1,6 @@ #include "alfpriv.h" -#include +#include /* ALF App and Window */ @@ -62,26 +62,32 @@ ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) { priv->fonts.dpi = priv->app->compatFn->GetDpiForWindow(win); - // XXX: SystemParametersInfoForDpi needs the Vista+ NONCLIENTMETRICS, - // but we want to be able to build with WINVER = 0x0500 and PSDK2003 - ALF_NONCLIENTMETRICS_VISTA ncm; - ZeroMemory(&ncm, sizeof(ncm)); - ncm.cbSize = ALF_SizeOf_NONCLIENTMETRICS(); - - if (priv->app->compatFn->SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) { - priv->fonts.lfMessageFont = ncm.lfMessageFont; + if (LOBYTE(LOWORD(GetVersion())) < 4) { + // NT 3.x uses System font for everything, we copy that + priv->fonts.hMessageFont = (HFONT)GetStockObject(SYSTEM_FONT); + GetObject(priv->fonts.hMessageFont, sizeof(priv->fonts.lfMessageFont), &priv->fonts.lfMessageFont); } else { - // FIXME! fallback to default font, 8pt MS Shell Dlg - ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont)); + // XXX: SystemParametersInfoForDpi needs the Vista+ NONCLIENTMETRICS, + // but we want to be able to build with WINVER = 0x0500 and PSDK2003 + ALF_NONCLIENTMETRICS_VISTA ncm; + ZeroMemory(&ncm, sizeof(ncm)); + ncm.cbSize = ALF_SizeOf_NONCLIENTMETRICS(); + + if (priv->app->compatFn->SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) { + priv->fonts.lfMessageFont = ncm.lfMessageFont; + } else { + // FIXME! fallback to default font, 8pt MS Shell Dlg + ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont)); - priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, priv->fonts.dpi, 72); - lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg")); - } + priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, priv->fonts.dpi, 72); + lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg")); + } - if (priv->fonts.hMessageFont) { - DeleteObject(priv->fonts.hMessageFont); + if (priv->fonts.hMessageFont) { + DeleteObject(priv->fonts.hMessageFont); + } + priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont); } - priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont); ALF_FOR_LIST(ALFWidgetPriv, list, &priv->widgets, i) { ALF_UpdateFontForWidget(priv, i); @@ -249,6 +255,9 @@ ALF_ApplyLayout(HWND hwnd, ALFWindowPriv *win) HDWP hdwp = BeginDeferWindowPos(win->layout.occupiedColumnCount * win->layout.occupiedRowCount); ALF_FOR_LIST(ALFWidgetPriv, list, &win->widgets, c) { + if ((int)c->x >= win->layout.nColumns || (int)c->y >= win->layout.nRows) + continue; + int marginleft = ALF_CentipointsToPxPriv(win, c->cptMarginLeft); int marginright = ALF_CentipointsToPxPriv(win, c->cptMarginRight); int margintop = ALF_CentipointsToPxPriv(win, c->cptMarginTop); @@ -549,6 +558,23 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) return TRUE; } + if (msg == WM_CTLCOLORSTATIC) { + HDC hdcStatic = (HDC)wparam; + HWND hwndStatic = (HWND)lparam; + + // HACK! return correct label background for NT3.x and NT4/95 + // get rid of this once we fixed the label to draw on the parent control background + if (LOBYTE(LOWORD(GetVersion())) < 4) { + SetTextColor(hdcStatic, GetSysColor(IsWindowEnabled(hwndStatic) ? COLOR_WINDOWTEXT : COLOR_GRAYTEXT)); + SetBkColor(hdcStatic, GetSysColor(COLOR_WINDOW)); + return (LRESULT)GetSysColorBrush(COLOR_WINDOW); + } else { + SetTextColor(hdcStatic, GetSysColor(IsWindowEnabled(hwndStatic) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); + SetBkColor(hdcStatic, GetSysColor(COLOR_BTNFACE)); + return (LRESULT)GetSysColorBrush(COLOR_BTNFACE); + } + } + return DefWindowProc(hwnd, msg, wparam, lparam); } @@ -599,12 +625,7 @@ ALF_CreateApplication(HINSTANCE hInstance) ALFAPP app = (ALFAPP)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(struct ALFAppPriv)); app->hInstance = hInstance; - INITCOMMONCONTROLSEX icc; - ZeroMemory(&icc, sizeof(icc)); - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_WIN95_CLASSES; - - InitCommonControlsEx(&icc); + InitCommonControls(); app->compatFn = ALF_CreateCompatFuncTable(); ALF_RegisterComboClass(app); @@ -620,23 +641,39 @@ ALF_TeardownApplication(ALFAPP app) HeapFree(GetProcessHeap(), 0, app); } +static void +ALF_IntToHex(TCHAR *buf, unsigned long num, int chars) +{ + char letters[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + for (int i = 0; i < chars; ++i) { + buf[chars-i-1] = letters[(num >> (i*4)) & 0xf]; + } +} + +static void +ALF_UuidToString(const GUID *guid, TCHAR *buf) +{ + ALF_IntToHex(buf, guid->Data1, 8); + buf[8] = '-'; + ALF_IntToHex(buf + 9, guid->Data2, 4); + buf[13] = '-'; + ALF_IntToHex(buf + 14, guid->Data3, 4); + buf[18] = '-'; + for (int i = 0; i < 8; ++i) { + ALF_IntToHex(buf + 19 + 2*i, guid->Data4[i], 2); + } + buf[35] = 0; +} + void -ALF_BuildRandomClassName(const TCHAR *prefix, TCHAR *buf) +ALF_BuildRandomClassName(ALFAPP app, const TCHAR* prefix, TCHAR* buf) { UUID uuid; - UuidCreate(&uuid); - -#ifdef UNICODE - unsigned short *uuidstr = NULL; -#else - unsigned char *uuidstr = NULL; -#endif - UuidToString(&uuid, &uuidstr); + app->compatFn->UuidCreate(&uuid); lstrcpy(buf, prefix); - lstrcat(buf, (LPCTSTR)uuidstr); - - RpcStringFree(&uuidstr); + ALF_UuidToString(&uuid, &buf[lstrlen(buf)]); } LPTSTR @@ -651,13 +688,18 @@ ALF_RegisterWindowClass(ALFAPP app, const ALFWindowClassParams *params) ZeroMemory(classNameBuf, sizeof(classNameBuf)); classNamePtr = classNameBuf; - ALF_BuildRandomClassName(TEXT("ALFWindow."), classNameBuf); + ALF_BuildRandomClassName(app, TEXT("ALFWindow."), classNameBuf); } cls.style = params->classStyle; 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 = classNamePtr; cls.cbWndExtra = sizeof(void*); cls.cbClsExtra = sizeof(void*)*2; -- cgit v1.2.3