diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2019-01-08 23:13:32 +0100 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2019-01-08 23:13:32 +0100 |
| commit | eb706aae8bf5659a8aae37db31f88c3b605b8b1f (patch) | |
| tree | df059ce548f6710aa30c32cef8a8ee9f3b4cc783 /alf | |
| parent | 6fb581e28e1ede9be7459533d9ca08679324652b (diff) | |
reingineer compat layer
not totally sure whether that's actually better
Diffstat (limited to 'alf')
| -rw-r--r-- | alf/alf.cpp | 51 | ||||
| -rw-r--r-- | alf/alfbutton.cpp | 16 | ||||
| -rw-r--r-- | alf/alfcombobox.cpp | 13 | ||||
| -rw-r--r-- | alf/alfcompat.cpp | 272 | ||||
| -rw-r--r-- | alf/alfcompat.h | 28 | ||||
| -rw-r--r-- | alf/alfedit.cpp | 12 | ||||
| -rw-r--r-- | alf/alflabel.cpp | 17 | ||||
| -rw-r--r-- | alf/alfpanel.cpp | 2 | ||||
| -rw-r--r-- | alf/alfpriv.h | 3 |
9 files changed, 256 insertions, 158 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp index 40b4156..64b4cc4 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -55,7 +55,7 @@ ALF_ApplyFontsPriv(HWND win, ALFWindowPriv *priv) void ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) { - priv->fonts.dpi = priv->app->compatFn->GetDpiForWindow(win); + priv->fonts.dpi = ALF_Compat_GetDpiForWindow(win); if (LOBYTE(LOWORD(GetVersion())) < 4) { // NT 3.x uses System font for everything, we copy that @@ -68,7 +68,7 @@ ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) ZeroMemory(&ncm, sizeof(ncm)); ncm.cbSize = ALF_SizeOf_NONCLIENTMETRICS(); - if (priv->app->compatFn->SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) { + if (ALF_Compat_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 @@ -202,7 +202,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) tmp.right = priv->layout.totalMinWidth; tmp.bottom = priv->layout.totalMinHeight; - if (priv->app->compatFn->AdjustWindowRectExForDpi( + if (ALF_Compat_AdjustWindowRectExForDpi( &tmp, GetWindowLong(hwnd, GWL_STYLE), GetMenu(hwnd) != NULL, @@ -341,7 +341,6 @@ ALF_CreateApplication(HINSTANCE hInstance) InitCommonControls(); - app->compatFn = ALF_CreateCompatFuncTable(); ALF_RegisterComboClass(app); ALF_RegisterPanelClass(app); @@ -353,43 +352,20 @@ ALF_TeardownApplication(ALFAPP app) { UnregisterClass(app->comboClass, app->hInstance); UnregisterClass(app->panelClass, app->hInstance); - HeapFree(GetProcessHeap(), 0, app->compatFn); 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(ALFAPP app, const TCHAR* prefix, TCHAR* buf) +ALF_BuildRandomClassName(const TCHAR* prefix, TCHAR* buf, DWORD cchBuf) { - UUID uuid; - app->compatFn->UuidCreate(&uuid); + LONG_PTR c1, c2; + ALF_UniqueCounterValue(&c1, &c2); + + DWORD_PTR params[] = { (DWORD_PTR)prefix, (DWORD_PTR)c1, (DWORD_PTR)c2 }; - lstrcpy(buf, prefix); - ALF_UuidToString(&uuid, &buf[lstrlen(buf)]); + FormatMessage(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, + TEXT("%1.%2!d!.%3!d!"), 0, 0, + buf, cchBuf, (va_list*)params); } LPTSTR @@ -404,7 +380,7 @@ ALF_RegisterWindowClass(ALFAPP app, const ALFWindowClassParams *params) ZeroMemory(classNameBuf, sizeof(classNameBuf)); classNamePtr = classNameBuf; - ALF_BuildRandomClassName(app, TEXT("ALFWindow."), classNameBuf); + ALF_BuildRandomClassName(TEXT("ALFWindow"), classNameBuf, 256); } cls.style = params->classStyle; @@ -419,7 +395,7 @@ ALF_RegisterWindowClass(ALFAPP app, const ALFWindowClassParams *params) cls.lpszClassName = classNamePtr; cls.cbWndExtra = sizeof(void*); cls.cbClsExtra = sizeof(void*)*2; - cls.lpfnWndProc = DefWindowProc; + cls.lpfnWndProc = ALF_WindowProc; ATOM classatom = RegisterClass(&cls); if (!classatom) @@ -432,7 +408,6 @@ ALF_RegisterWindowClass(ALFAPP app, const ALFWindowClassParams *params) HWND tmp = CreateWindowEx(0, MAKEINTATOM(classatom), TEXT("dummy"), 0, 0, 0, 0, 0, NULL, 0, app->hInstance, 0); SetClassLongPtr(tmp, 0, (LONG_PTR)pvtbl); SetClassLongPtr(tmp, sizeof(void*), (LONG_PTR)app); - SetClassLongPtr(tmp, GCLP_WNDPROC, (LONG_PTR)ALF_WindowProc); DestroyWindow(tmp); return MAKEINTATOM(classatom); diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp index 95e8e8d..b0458b2 100644 --- a/alf/alfbutton.cpp +++ b/alf/alfbutton.cpp @@ -7,8 +7,6 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT (void)uIdSubclass; (void)dwRefData; - ALFAPP app = (ALFAPP)dwRefData; - if (uMsg == ALF_WM_QUERYSIZE) { HDC hdc = GetDC(hwnd); HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); @@ -32,9 +30,9 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT HeapFree(GetProcessHeap(), 0, textbuf); - int xpadding = app->compatFn->GetSystemMetricsForDpi(SM_CXEDGE, + int xpadding = ALF_Compat_GetSystemMetricsForDpi(SM_CXEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 2 + 6; - int ypadding = app->compatFn->GetSystemMetricsForDpi(SM_CYEDGE, + int ypadding = ALF_Compat_GetSystemMetricsForDpi(SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 2 + 6; SIZE *pSize = (SIZE*)(void*)lParam; @@ -58,7 +56,7 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT RECT *p = (RECT *)lParam; - int padding = app->compatFn->IsAppThemed() ? 0 : 1; + int padding = ALF_Compat_IsAppThemed() ? 0 : 1; return (LRESULT)DeferWindowPos((HDWP)wParam, hwnd, NULL, @@ -66,10 +64,10 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT p->right - p->left, p->bottom - p->top - 2*padding, SWP_NOZORDER|SWP_NOACTIVATE); } else if (uMsg == WM_DESTROY) { - app->compatFn->RemoveWindowSubclass(hwnd, ALF__ButtonSubclassProc, 0); + ALF_Compat_RemoveWindowSubclass(hwnd, ALF__ButtonSubclassProc, 0); } - return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); + return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); } HWND @@ -85,9 +83,7 @@ ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE), NULL); - ALFAPP app = ALF_ApplicationFromWindow(win); - - app->compatFn->SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, (DWORD_PTR)app); + ALF_Compat_SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, 0); SetWindowPos(hwndButton, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); ALFWidgetLayoutParams p; diff --git a/alf/alfcombobox.cpp b/alf/alfcombobox.cpp index a6e846f..409d64f 100644 --- a/alf/alfcombobox.cpp +++ b/alf/alfcombobox.cpp @@ -44,8 +44,7 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) SetWindowLongPtr(hwnd, 0, (LONG_PTR)params->app); } - ALFAPP app = (ALFAPP)GetWindowLongPtr(hwnd, 0); - HWND hwndChild = (HWND)GetWindowLongPtr(hwnd, sizeof(void*)); + HWND hwndChild = (HWND)GetWindowLongPtr(hwnd, 0); if (uMsg == WM_CREATE) { ALFComboCreateParams *params = (ALFComboCreateParams*)((CREATESTRUCT*)lParam)->lpCreateParams; @@ -61,7 +60,7 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ((CREATESTRUCT*)lParam)->hInstance, NULL); - SetWindowLongPtr(hwnd, sizeof(void*), (LONG_PTR)hwndCombo); + SetWindowLongPtr(hwnd, 0, (LONG_PTR)hwndCombo); } if (uMsg == WM_ENABLE && hwndChild) { EnableWindow(hwndChild, (BOOL)wParam); @@ -152,7 +151,7 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } if (!ps->cy) { - ps->cy = tm.tmHeight + 2*app->compatFn->GetSystemMetricsForDpi( + ps->cy = tm.tmHeight + 2*ALF_Compat_GetSystemMetricsForDpi( SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + 4 /* padding internal to the edit control */ + 2 /* external padding to line up with themed button */; @@ -247,7 +246,7 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) DWORD heightOffset = 0; if (LOBYTE(LOWORD(GetVersion())) >= 4) { - heightOffset = - 2*app->compatFn->GetSystemMetricsForDpi( + heightOffset = - 2*ALF_Compat_GetSystemMetricsForDpi( SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) - 4; } else { @@ -274,7 +273,7 @@ ALF_RegisterComboClass(ALFAPP app) ZeroMemory(&cls, sizeof(cls)); TCHAR classNameBuf[256]; - ALF_BuildRandomClassName(app, TEXT("ALFComboBox."), classNameBuf); + ALF_BuildRandomClassName(TEXT("ALFComboBox"), classNameBuf, 256); cls.hInstance = app->hInstance; cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW); @@ -285,7 +284,7 @@ ALF_RegisterComboClass(ALFAPP app) cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); } cls.lpszClassName = classNameBuf; - cls.cbWndExtra = sizeof(void*)*2; + cls.cbWndExtra = sizeof(void*); cls.lpfnWndProc = ALF__ComboWindowProc; ATOM classatom = RegisterClass(&cls); diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp index 9a36d4d..aee27fb 100644 --- a/alf/alfcompat.cpp +++ b/alf/alfcompat.cpp @@ -2,6 +2,58 @@ #include <shlwapi.h> +#if defined(_MSC_VER) && defined(_M_IX86) + +# pragma warning(push) +# pragma warning(disable:4035) + + // HACK: inline assembly for MSVC 6 + // TODO: add version detection to use intrinsic on newer MSVC versions + + static inline LONG + ALF_Compat_InterlockedIncrement(LONG volatile *addend) + { + __asm { + mov eax,1 + mov edx,addend + lock xadd [edx],eax + } + } +# ifdef InterlockedIncrement +# undef InterlockedIncrement +# endif +# define InterlockedIncrement(d) ALF_Compat_InterlockedIncrement(d) + + static inline LONG + ALF_Compat_InterlockedCompareExchange(volatile LONG *destination, LONG exchange, LONG comparand) + { + __asm { + mov eax,comparand + mov ecx,exchange + mov edx,destination + lock cmpxchg [edx],ecx + } + } + +# ifdef InterlockedCompareExchange +# undef InterlockedCompareExchange +# endif +# define InterlockedCompareExchange(d,e,c) ALF_Compat_InterlockedCompareExchange(d,e,c) + + static inline PVOID + ALF_Compat_InterlockedCompareExchangePointer(PVOID volatile *destination, PVOID exchange, PVOID comparand) + { + return (void*)InterlockedCompareExchange((LONG volatile *)destination, (LONG)exchange, (LONG)comparand); + } + +# ifdef InterlockedCompareExchangePointer +# undef InterlockedCompareExchangePointer +# endif +# define InterlockedCompareExchangePointer(d,e,c) ALF_Compat_InterlockedCompareExchangePointer(d,e,c) + +# pragma warning(pop) +#endif + static DWORD ALF_DllGetVersion(const char *dll) { @@ -29,7 +81,7 @@ DWORD ALF_DllGetVersion(const char *dll) } static int WINAPI -fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi) +ALF_Compat_fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi) { (void)dpi; if (LOBYTE(LOWORD(GetVersion())) < 4) { @@ -44,13 +96,13 @@ fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi) } static BOOL WINAPI -fallbackIsAppThemed(void) +ALF_Compat_fallbackIsAppThemed(void) { return FALSE; } static UINT WINAPI -fallbackGetDpiForWindow(HWND win) +ALF_Compat_fallbackGetDpiForWindow(HWND win) { (void)win; @@ -70,7 +122,7 @@ fallbackGetDpiForWindow(HWND win) } static BOOL WINAPI -fallbackSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi) +ALF_Compat_fallbackSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi) { (void)dpi; @@ -78,7 +130,7 @@ fallbackSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, U } static BOOL WINAPI -fallbackAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi) +ALF_Compat_fallbackAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi) { (void)dpi; @@ -97,7 +149,7 @@ typedef struct { } ALFWindowSubclassData; static LRESULT CALLBACK -fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +ALF_Compat_fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); @@ -121,7 +173,7 @@ fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } static BOOL WINAPI -fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) +ALF_Compat_fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { ALFWindowSubclassData *data = (ALFWindowSubclassData *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ALFWindowSubclassData)); @@ -131,13 +183,13 @@ fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_P data->orig = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data); - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)fallbackSubclassProc); + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ALF_Compat_fallbackSubclassProc); return TRUE; } static LRESULT WINAPI -fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +ALF_Compat_fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); @@ -145,7 +197,7 @@ fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } static BOOL WINAPI -fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass) +ALF_Compat_fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass) { (void)pfnSubclass; (void)uIdSubclass; @@ -166,72 +218,158 @@ fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UIN return TRUE; } -ALFCompatFunctions * -ALF_CreateCompatFuncTable(void) -{ - ALFCompatFunctions *compatfn = (ALFCompatFunctions*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(ALFCompatFunctions)); - -#define COMPAT(dll, entrypoint, ordinal, fallback) \ - do { \ - FARPROC p = GetProcAddress(GetModuleHandleA(#dll), #entrypoint); \ - if (!p && ordinal) \ - p = GetProcAddress(GetModuleHandleA(#dll), (char*)ordinal); \ - CopyMemory(&compatfn->entrypoint, &p, sizeof(void*)); \ - \ - if (!compatfn->entrypoint) \ - compatfn->entrypoint = fallback; \ - } while (0) - - COMPAT(comctl32.dll, SetWindowSubclass, 410, fallbackSetWindowSubclass); - COMPAT(comctl32.dll, DefSubclassProc, 413, fallbackDefSubclassProc); - COMPAT(comctl32.dll, RemoveWindowSubclass, 412, fallbackRemoveWindowSubclass); - COMPAT(user32.dll, GetSystemMetricsForDpi, 0, fallbackGetSystemMetricsForDpi); - COMPAT(user32.dll, GetDpiForWindow, 0, fallbackGetDpiForWindow); - - // FIXME: SystemParametersInfoForDpi is Unicode-Only. - // Writing a wrapper function would have been The Right Way, but such a function - // is yet to be written. So the current practical recommendation is to make - // ANSI builds System DPI aware only. -#ifdef UNICODE - COMPAT(user32.dll, SystemParametersInfoForDpi, 0, fallbackSystemParametersInfoForDpi); -#else - compatfn->SystemParametersInfoForDpi = fallbackSystemParametersInfoForDpi; -#endif +long +ALF_GetAveCharWidth(HDC hdc) +{ + // see: HOWTO: Calculate Dialog Units When Not Using the System Font + + SIZE s; + GetTextExtentPoint32A(hdc, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &s); + + return (s.cx / 26 + 1) / 2; +} + +void +ALF_UniqueCounterValue(LONG_PTR *pCounterId, LONG_PTR *pCounterValue) +{ + static LONG counter = 0; + + LONG r = InterlockedIncrement(&counter); + *pCounterId = (LONG_PTR)&counter; + *pCounterValue = r; +} + +static BOOL WINAPI +ALF_Compat_loadIsAppThemed(void) +{ + HMODULE hUxTheme = GetModuleHandleA("uxtheme.dll"); + FARPROC p = GetProcAddress(hUxTheme, "IsAppThemed"); + + if (!p || ALF_DllGetVersion("comctl32.dll") < 0x60000) + p = (FARPROC)ALF_Compat_fallbackIsAppThemed; + + InterlockedCompareExchangePointer((void**)&ALF_Compat_IsAppThemed, (void*)p, (void*)ALF_Compat_loadIsAppThemed); + + return ALF_Compat_IsAppThemed(); +} + +static UINT WINAPI +ALF_Compat_loadGetDpiForWindow(HWND window) +{ + FARPROC p = GetProcAddress(GetModuleHandleA("user32.dll"), "GetDpiForWindow"); + + if (!p) + p = (FARPROC)(void*)ALF_Compat_fallbackGetDpiForWindow; + + InterlockedCompareExchangePointer((void**)&ALF_Compat_GetDpiForWindow, (void*)p, (void*)ALF_Compat_loadGetDpiForWindow); + + return ALF_Compat_GetDpiForWindow(window); +} + +static BOOL WINAPI +ALF_Compat_loadAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi) +{ + FARPROC p = GetProcAddress(GetModuleHandleA("user32.dll"), "AdjustWindowRectExForDpi"); + + if (!p) + p = (FARPROC)(void*)ALF_Compat_fallbackAdjustWindowRectExForDpi; + + InterlockedCompareExchangePointer((void**)&ALF_Compat_AdjustWindowRectExForDpi, (void*)p, (void*)ALF_Compat_loadAdjustWindowRectExForDpi); + + return ALF_Compat_AdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi); +} - COMPAT(user32.dll, AdjustWindowRectExForDpi, 0, fallbackAdjustWindowRectExForDpi); +static int WINAPI +ALF_Compat_loadGetSystemMetricsForDpi(int nIndex, UINT dpi) +{ + void *p = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetSystemMetricsForDpi"); + + if (!p) + p = (void*)ALF_Compat_fallbackGetSystemMetricsForDpi; + + InterlockedCompareExchangePointer((void**)&ALF_Compat_GetSystemMetricsForDpi, p, (void*)ALF_Compat_loadGetSystemMetricsForDpi); + + return ALF_Compat_GetSystemMetricsForDpi(nIndex, dpi); +} + +static BOOL WINAPI +ALF_Compat_loadSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) +{ + HMODULE comctl32 = GetModuleHandleA("comctl32.dll"); + + void *p = (void*)GetProcAddress(comctl32, "SetWindowSubclass"); + if (!p) { + p = (void*)GetProcAddress(comctl32, (char*)410); + if (!p) { + p = (void*)ALF_Compat_fallbackSetWindowSubclass; + } + } + + InterlockedCompareExchangePointer((void**)&ALF_Compat_SetWindowSubclass, p, (void*)ALF_Compat_loadSetWindowSubclass); + + return ALF_Compat_SetWindowSubclass(hwnd, pfnSubclass, uIdSubclass, dwRefData); +} + +static BOOL WINAPI +ALF_Compat_loadRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass) +{ + HMODULE comctl32 = GetModuleHandleA("comctl32.dll"); - // IsAppThemed would return TRUE even when we're linked against comctl32 v5 - if (ALF_DllGetVersion("comctl32.dll") >= 0x60000) { - LoadLibraryA("uxtheme.dll"); - COMPAT(uxtheme.dll, IsAppThemed, 0, fallbackIsAppThemed); - } else { - compatfn->IsAppThemed = fallbackIsAppThemed; + void *p = (void*)GetProcAddress(comctl32, "RemoveWindowSubclass"); + if (!p) { + p = (void*)GetProcAddress(comctl32, (char*)412); + if (!p) { + p = (void*)ALF_Compat_fallbackRemoveWindowSubclass; + } } -#undef COMPAT - - UINT oldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); // stop win32s from barking about rpcrt4 - HMODULE rpc = LoadLibraryA("rpcrt4.dll"); - if (rpc) { - // NT always has rpcrt4.dll - compatfn->UuidCreate = (ULONG(WINAPI*)(UUID*))(void*)GetProcAddress(rpc, "UuidCreate"); - } else { - // Win32s always has OLE32 - HMODULE ole32 = LoadLibraryA("ole32.dll"); - compatfn->UuidCreate = (ULONG(WINAPI*)(UUID*))(void*)GetProcAddress(ole32, "CoCreateGuid"); + InterlockedCompareExchangePointer((void**)&ALF_Compat_RemoveWindowSubclass, p, (void*)ALF_Compat_loadRemoveWindowSubclass); + + return ALF_Compat_RemoveWindowSubclass(hwnd, pfnSubclass, uIdSubclass); +} + +static LRESULT WINAPI +ALF_Compat_loadDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + HMODULE comctl32 = GetModuleHandleA("comctl32.dll"); + + void *p = (void*)GetProcAddress(comctl32, "DefSubclassProc"); + if (!p) { + p = (void*)GetProcAddress(comctl32, (char*)413); + if (!p) { + p = (void*)ALF_Compat_fallbackDefSubclassProc; + } } - SetErrorMode(oldErrorMode); - return compatfn; + InterlockedCompareExchangePointer((void**)&ALF_Compat_DefSubclassProc, p, (void*)ALF_Compat_loadDefSubclassProc); + + return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); } -long -ALF_GetAveCharWidth(HDC hdc) +static BOOL WINAPI +ALF_Compat_loadSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi) { - // see: HOWTO: Calculate Dialog Units When Not Using the System Font + void *p = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "SystemParametersInfoForDpi"); + if (!p) + p = (void*)ALF_Compat_fallbackSystemParametersInfoForDpi; - SIZE s; - GetTextExtentPoint32A(hdc, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &s); + InterlockedCompareExchangePointer((void**)&ALF_Compat_SystemParametersInfoForDpi, p, (void*)ALF_Compat_loadSystemParametersInfoForDpi); - return (s.cx / 26 + 1) / 2; + return ALF_Compat_SystemParametersInfoForDpi(uiAction, uiParam, pvParam, fWinIni, dpi); } + + +BOOL (WINAPI *ALF_Compat_IsAppThemed)(void) = ALF_Compat_loadIsAppThemed; +UINT (WINAPI *ALF_Compat_GetDpiForWindow)(HWND /*window*/) = ALF_Compat_loadGetDpiForWindow; +BOOL (WINAPI *ALF_Compat_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT) = ALF_Compat_loadAdjustWindowRectExForDpi; +int (WINAPI *ALF_Compat_GetSystemMetricsForDpi)(int, UINT) = ALF_Compat_loadGetSystemMetricsForDpi; +BOOL (WINAPI *ALF_Compat_SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR, DWORD_PTR) = ALF_Compat_loadSetWindowSubclass; +LRESULT (WINAPI *ALF_Compat_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM) = ALF_Compat_loadDefSubclassProc; +BOOL (WINAPI *ALF_Compat_RemoveWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR) = ALF_Compat_loadRemoveWindowSubclass; + +// FIXME! do Unicode properly for SystemParametersInfoForDpi +#ifdef UNICODE +BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT) = ALF_Compat_loadSystemParametersInfoForDpi; +#else +BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT) = ALF_Compat_fallbackSystemParametersInfoForDpi; +#endif diff --git a/alf/alfcompat.h b/alf/alfcompat.h index 98a2abc..b0a43ec 100644 --- a/alf/alfcompat.h +++ b/alf/alfcompat.h @@ -8,18 +8,6 @@ #endif typedef LRESULT (CALLBACK *ALF_COMPAT_SUBCLASSPROC)(HWND,UINT,WPARAM,LPARAM,UINT_PTR,DWORD_PTR); -typedef struct { - BOOL (WINAPI *SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR, DWORD_PTR); - LRESULT (WINAPI *DefSubclassProc)(HWND, UINT, WPARAM, LPARAM); - BOOL (WINAPI *RemoveWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR); - int (WINAPI *GetSystemMetricsForDpi)(int, UINT); - BOOL (WINAPI *IsAppThemed)(void); - UINT (WINAPI *GetDpiForWindow)(HWND); - BOOL (WINAPI *SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT); - BOOL (WINAPI *AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); - ULONG (WINAPI *UuidCreate)(UUID *); -} ALFCompatFunctions; - typedef struct { UINT cbSize; @@ -50,8 +38,18 @@ ALF_SizeOf_NONCLIENTMETRICS(void) } } -ALFCompatFunctions * -ALF_CreateCompatFuncTable(void); - long ALF_GetAveCharWidth(HDC hdc); + +void +ALF_UniqueCounterValue(LONG_PTR *pCounterId, LONG_PTR *pCounterValue); + + +extern BOOL (WINAPI *ALF_Compat_IsAppThemed)(void); +extern UINT (WINAPI *ALF_Compat_GetDpiForWindow)(HWND); +extern BOOL (WINAPI *ALF_Compat_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); +extern int (WINAPI *ALF_Compat_GetSystemMetricsForDpi)(int, UINT); +extern BOOL (WINAPI *ALF_Compat_SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR, DWORD_PTR); +extern LRESULT (WINAPI *ALF_Compat_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM); +extern BOOL (WINAPI *ALF_Compat_RemoveWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR); +extern BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT); diff --git a/alf/alfedit.cpp b/alf/alfedit.cpp index bbe36b8..1fde70d 100644 --- a/alf/alfedit.cpp +++ b/alf/alfedit.cpp @@ -7,8 +7,6 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P (void)uIdSubclass; (void)dwRefData; - ALFAPP app = (ALFAPP)dwRefData; - if (uMsg == ALF_WM_QUERYSIZE) { HDC hDc = GetDC(hwnd); HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); @@ -26,7 +24,7 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P } if (!ps->cy) { - ps->cy = tm.tmHeight + 2*app->compatFn->GetSystemMetricsForDpi( + ps->cy = tm.tmHeight + 2*ALF_Compat_GetSystemMetricsForDpi( SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + 4 /* padding internal to the edit control */ + 2 /* external padding to line up with themed button */; @@ -48,10 +46,10 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P p->right - p->left, p->bottom - p->top - 2, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS); } else if (uMsg == WM_DESTROY) { - app->compatFn->RemoveWindowSubclass(hwnd, ALF__EditSubclassProc, 0); + ALF_Compat_RemoveWindowSubclass(hwnd, ALF__EditSubclassProc, 0); } - return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); + return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); } HWND @@ -78,9 +76,7 @@ ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE), NULL); - ALFAPP app = ALF_ApplicationFromWindow(win); - - app->compatFn->SetWindowSubclass(hwndEdit, ALF__EditSubclassProc, 0, (DWORD_PTR)app); + ALF_Compat_SetWindowSubclass(hwndEdit, ALF__EditSubclassProc, 0, 0); SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_FRAMECHANGED); ALFWidgetLayoutParams p; diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp index 108c8d5..eb27fb1 100644 --- a/alf/alflabel.cpp +++ b/alf/alflabel.cpp @@ -3,11 +3,11 @@ /* LABEL */ static -int ALF__LabelTopPadding(HWND hwnd, ALFAPP app) +int ALF__LabelTopPadding(HWND hwnd) { // some pixels on top to align with the edit control // see also: alfedit.cpp - return app->compatFn->GetSystemMetricsForDpi( + return ALF_Compat_GetSystemMetricsForDpi( SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + ((LOBYTE(LOWORD(GetVersion())) < 4) ? 2 : 1) /* internal padding in edit control */ + 1 /* external padding around edit control */; @@ -19,8 +19,6 @@ ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_ (void)uIdSubclass; (void)dwRefData; - ALFAPP app = (ALFAPP)dwRefData; - if (uMsg == ALF_WM_QUERYSIZE) { HDC hdcLabel = GetDC(hwnd); HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); @@ -52,7 +50,7 @@ ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_ if (pSize->cx == 0) pSize->cx = r.right - r.left; if (pSize->cy == 0) - pSize->cy = r.bottom - r.top + ALF__LabelTopPadding(hwnd, app); + pSize->cy = r.bottom - r.top + ALF__LabelTopPadding(hwnd); if (font) SelectFont(hdcLabel, oldFont); @@ -61,7 +59,7 @@ ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_ } else if (uMsg == ALF_WM_APPLYSIZE) { RECT *p = (RECT *)lParam; - int topPadding = ALF__LabelTopPadding(hwnd, app); + int topPadding = ALF__LabelTopPadding(hwnd); return (LRESULT)DeferWindowPos((HDWP)wParam, hwnd, NULL, @@ -69,10 +67,10 @@ ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_ p->right - p->left, p->bottom - p->top - topPadding, SWP_NOZORDER|SWP_NOACTIVATE); } else if (uMsg == WM_DESTROY) { - app->compatFn->RemoveWindowSubclass(hwnd, ALF__LabelSubclassProc, 0); + ALF_Compat_RemoveWindowSubclass(hwnd, ALF__LabelSubclassProc, 0); } - return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); + return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); } HWND @@ -87,8 +85,7 @@ ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE), NULL); - ALFAPP app = ALF_ApplicationFromWindow(win); - app->compatFn->SetWindowSubclass(hwndLabel, ALF__LabelSubclassProc, 0, (DWORD_PTR)app); + ALF_Compat_SetWindowSubclass(hwndLabel, ALF__LabelSubclassProc, 0, 0); ALFWidgetLayoutParams p; ZeroMemory(&p, sizeof(p)); diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp index 74db788..070c286 100644 --- a/alf/alfpanel.cpp +++ b/alf/alfpanel.cpp @@ -59,7 +59,7 @@ ALF_RegisterPanelClass(ALFAPP app) ZeroMemory(&cls, sizeof(cls)); TCHAR classNameBuf[256]; - ALF_BuildRandomClassName(app, TEXT("ALFPanel."), classNameBuf); + ALF_BuildRandomClassName(TEXT("ALFPanel"), classNameBuf, 256); cls.hInstance = app->hInstance; cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW); diff --git a/alf/alfpriv.h b/alf/alfpriv.h index 8f28b59..ec7a447 100644 --- a/alf/alfpriv.h +++ b/alf/alfpriv.h @@ -30,7 +30,6 @@ typedef struct { struct ALFAppPriv { HINSTANCE hInstance; - ALFCompatFunctions *compatFn; TCHAR *comboClass; TCHAR *panelClass; }; @@ -51,7 +50,7 @@ void ALF_RegisterPanelClass(ALFAPP app); void -ALF_BuildRandomClassName(ALFAPP app, const TCHAR *prefix, TCHAR *buf); +ALF_BuildRandomClassName(const TCHAR *prefix, TCHAR *buf, DWORD cchBuf); BOOL ALF_ShouldMessageBubble(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); |
