summaryrefslogtreecommitdiff
path: root/alf
diff options
context:
space:
mode:
Diffstat (limited to 'alf')
-rw-r--r--alf/alf.cpp21
-rw-r--r--alf/alf.h4
-rw-r--r--alf/alfbutton.cpp30
-rw-r--r--alf/alfcompat.cpp61
-rw-r--r--alf/alfedit.cpp19
-rw-r--r--alf/alflabel.cpp26
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);
diff --git a/alf/alf.h b/alf/alf.h
index d56afa5..d21a295 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -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);