diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2018-12-27 22:54:55 +0100 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2018-12-27 23:01:28 +0100 |
| commit | a5f3ea9ac12fccbc9faf3f152d4dfbe7f263268e (patch) | |
| tree | 7e66ed4d7cb7e4b4ae56d8b562ff08121bf43026 /alf | |
| parent | b0b0e97aa5a06b22768bb9c9ea5e8caf383d78a4 (diff) | |
make label, edit and button text line up perfectly
Diffstat (limited to 'alf')
| -rw-r--r-- | alf/alf.cpp | 21 | ||||
| -rw-r--r-- | alf/alf.h | 4 | ||||
| -rw-r--r-- | alf/alfbutton.cpp | 30 | ||||
| -rw-r--r-- | alf/alfcompat.cpp | 61 | ||||
| -rw-r--r-- | alf/alfedit.cpp | 19 | ||||
| -rw-r--r-- | alf/alflabel.cpp | 26 |
6 files changed, 136 insertions, 25 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp index 3bcde5b..2ec33ca 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -249,13 +249,20 @@ ALF_ApplyLayout(HWND hwnd, ALFWindowPriv *win) int margintop = ALF_CentipointsToPxPriv(win, c->cptMarginTop); int marginbottom = ALF_CentipointsToPxPriv(win, c->cptMarginBottom); - hdwp = DeferWindowPos(hdwp, - c->hwnd, 0, - win->layout.columns[c->x].allocatedPosition + marginleft, - win->layout.rows[c->y].allocatedPosition + margintop, - win->layout.columns[c->x].allocatedWidth - marginleft - marginright, - win->layout.rows[c->y].allocatedWidth - margintop - marginbottom, - SWP_NOACTIVATE | SWP_NOZORDER); + RECT r = { 0,0,0,0 }; + r.left = win->layout.columns[c->x].allocatedPosition + marginleft; + r.right = r.left + win->layout.columns[c->x].allocatedWidth - marginleft - marginright; + r.top = win->layout.rows[c->y].allocatedPosition + margintop; + r.bottom = r.top + win->layout.rows[c->y].allocatedWidth - margintop - marginbottom; + + if (c->flags & ALF_APPLYSIZE) { + hdwp = (HDWP)SendMessage(c->hwnd, ALF_WM_APPLYSIZE, (WPARAM)hdwp, (LPARAM)&r); + } else { + hdwp = DeferWindowPos(hdwp, + c->hwnd, 0, + r.left, r.top, r.right - r.left, r.bottom - r.top, + SWP_NOACTIVATE | SWP_NOZORDER); + } } EndDeferWindowPos(hdwp); @@ -29,6 +29,7 @@ typedef struct { #define ALF_HEXPAND 0x02 #define ALF_VEXPAND 0x04 #define ALF_MESSAGEFONT 0x08 +#define ALF_APPLYSIZE 0x10 // messages #define ALF_WM__BASE 0x2800 @@ -43,6 +44,7 @@ typedef struct { #define ALF_WM_CENTIPOINTTOPX (ALF_WM__BASE + 9) #define ALF_WM_SETFOCUS (ALF_WM__BASE + 10) #define ALF_WM_GETAPPLICATION (ALF_WM__BASE + 11) +#define ALF_WM_APPLYSIZE (ALF_WM__BASE + 12) typedef struct { const WCHAR *className; @@ -72,6 +74,8 @@ typedef struct { LRESULT (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); } ALFCompatFunctions; typedef struct ALFAppPriv *ALFAPP; diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp index 079da75..b32831a 100644 --- a/alf/alfbutton.cpp +++ b/alf/alfbutton.cpp @@ -32,15 +32,17 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT HeapFree(GetProcessHeap(), 0, textbuf); - // TODO: calculate from system metrics - int padding = ALF_CentipointsToPixels(GetParent(hwnd), 525); + int xpadding = app->compatFn->GetSystemMetricsForDpi(SM_CXEDGE, + ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 3; + int ypadding = app->compatFn->GetSystemMetricsForDpi(SM_CYEDGE, + ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 3; SIZE *pSize = (SIZE*)(void*)lParam; - if (pSize->cx < r.right - r.left + padding) { - pSize->cx = r.right - r.left + padding; + if (pSize->cx < r.right - r.left + xpadding) { + pSize->cx = r.right - r.left + xpadding; } - if (pSize->cy < r.bottom - r.top + padding) { - pSize->cy = r.bottom - r.top + padding; + if (pSize->cy < r.bottom - r.top + ypadding) { + pSize->cy = r.bottom - r.top + ypadding; } if (pSize->cx < pSize->cy) { pSize->cx = pSize->cy; @@ -50,6 +52,21 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT SelectFont(hdc, oldFont); ReleaseDC(hwnd, hdc); + } else if (uMsg == WM_NCCALCSIZE) { + /* HACK: a themed button contains a 1px margin. An unthemed button + * does not, so we add one by shrinking the client area */ + RECT *r = (RECT *)lParam; + + int retval = app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); + + if (!app->compatFn->IsAppThemed()) { + r->top += 1; + r->bottom -= 1; + } + + return retval; + } else if (uMsg == WM_THEMECHANGED) { + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); } return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); @@ -71,6 +88,7 @@ ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) ALFAPP app = ALF_ApplicationFromWindow(win); app->compatFn->SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, (DWORD_PTR)app); + SetWindowPos(hwndButton, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); ALFAddWidgetParams p; ZeroMemory(&p, sizeof(p)); diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp index 452b9bc..3ffc9f9 100644 --- a/alf/alfcompat.cpp +++ b/alf/alfcompat.cpp @@ -1,21 +1,74 @@ #include "alfpriv.h" +#include <shlwapi.h> + +static +DWORD ALF_DllGetVersion(const char *dll) +{ + HMODULE hDll = GetModuleHandleA(dll); + + if (hDll) { + DLLGETVERSIONPROC pDllGetVersion; + pDllGetVersion = (DLLGETVERSIONPROC)(void*)GetProcAddress(hDll, "DllGetVersion"); + + if (pDllGetVersion) { + DLLVERSIONINFO dvi; + HRESULT hr; + + ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + + hr = (*pDllGetVersion)(&dvi); + + if (SUCCEEDED(hr)) { + return MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + } + } + } + return 0; +} + +static int WINAPI +fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi) +{ + (void)dpi; + return GetSystemMetrics(nIndex); +} + +static BOOL WINAPI +fallbackIsAppThemed(void) +{ + return FALSE; +} + ALFCompatFunctions * ALF_CreateCompatFuncTable(void) { ALFCompatFunctions *compatfn = (ALFCompatFunctions*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(ALFCompatFunctions)); -#define COMPAT(dll, entrypoint, ordinal) \ +#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); - COMPAT(comctl32.dll, DefSubclassProc, 413); - COMPAT(comctl32.dll, RemoveWindowSubclass, 412); + COMPAT(comctl32.dll, SetWindowSubclass, 410, NULL); + COMPAT(comctl32.dll, DefSubclassProc, 413, NULL); + COMPAT(comctl32.dll, RemoveWindowSubclass, 412, NULL); + COMPAT(user32.dll, GetSystemMetricsForDpi, 0, fallbackGetSystemMetricsForDpi); + + // 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; + } #undef COMPAT diff --git a/alf/alfedit.cpp b/alf/alfedit.cpp index 65f14c8..df902e9 100644 --- a/alf/alfedit.cpp +++ b/alf/alfedit.cpp @@ -26,7 +26,10 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P } if (!ps->cy) { - ps->cy = tm.tmHeight + 6; // FIXME! use system metrics + ps->cy = tm.tmHeight + 2*app->compatFn->GetSystemMetricsForDpi( + SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + + 2 /* padding internal to the edit control */ + + 2 /* external padding to line up with themed button */; } } @@ -35,6 +38,14 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P ReleaseDC(hwnd, hDc); return 0; + } else if (uMsg == ALF_WM_APPLYSIZE) { + RECT *p = (RECT *)lParam; + + return (LRESULT)DeferWindowPos((HDWP)wParam, + hwnd, NULL, + p->left, p->top + 1, + p->right - p->left, p->bottom - p->top - 2, + SWP_NOZORDER|SWP_NOACTIVATE); } return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); @@ -56,7 +67,7 @@ ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) ALFAPP app = ALF_ApplicationFromWindow(win); app->compatFn->SetWindowSubclass(hwndEdit, ALF__EditSubclassProc, 0, (DWORD_PTR)app); - SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED); + SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_FRAMECHANGED); ALFAddWidgetParams p; ZeroMemory(&p, sizeof(p)); @@ -65,9 +76,7 @@ ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) p.y = y; p.width = 0; p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT; - p.margins[0] = 75; // TODO: pixel-perfect margin from system metrics - p.margins[2] = 75; + p.flags = ALF_QUERYSIZE | ALF_APPLYSIZE | ALF_MESSAGEFONT; ALF_AddWidgetEx(win, &p); diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp index e9ae550..7402ecd 100644 --- a/alf/alflabel.cpp +++ b/alf/alflabel.cpp @@ -2,6 +2,17 @@ /* LABEL */ +static +int ALF__LabelTopPadding(HWND hwnd, ALFAPP app) +{ + // some pixels on top to align with the edit control + // see also: alfedit.cpp + return app->compatFn->GetSystemMetricsForDpi( + SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + + 1 /* internal padding in edit control */ + + 1 /* external padding around edit control */; +} + static LRESULT CALLBACK ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { @@ -41,12 +52,22 @@ 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; + pSize->cy = r.bottom - r.top + ALF__LabelTopPadding(hwnd, app); if (font) SelectFont(hdcLabel, oldFont); ReleaseDC(hwnd, hdcLabel); + } else if (uMsg == ALF_WM_APPLYSIZE) { + RECT *p = (RECT *)lParam; + + int topPadding = ALF__LabelTopPadding(hwnd, app); + + return (LRESULT)DeferWindowPos((HDWP)wParam, + hwnd, NULL, + p->left, p->top + topPadding, + p->right - p->left, p->bottom - p->top - topPadding, + SWP_NOZORDER|SWP_NOACTIVATE); } return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam); @@ -74,8 +95,7 @@ ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) p.y = y; p.width = 0; p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT; - p.margins[0] = 300; // TODO: pixel perfect margins from system metrics + p.flags = ALF_QUERYSIZE | ALF_APPLYSIZE | ALF_MESSAGEFONT; ALF_AddWidgetEx(win, &p); |
