diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-04-23 15:07:21 +0200 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-04-23 15:07:21 +0200 |
| commit | 51daba89072cb66fe5e43015484a554555a40499 (patch) | |
| tree | 372502daebee3c3f3b2cfa68047e03f164f3d95c | |
| parent | d17d8f49777d802b56aa332077afbfa83af691e1 (diff) | |
changed DPI handling: dpi is now pushed into every control and saved there
| -rw-r--r-- | alf/alf.cpp | 18 | ||||
| -rw-r--r-- | alf/alf.h | 17 | ||||
| -rw-r--r-- | alf/alfbutton.cpp | 12 | ||||
| -rw-r--r-- | alf/alfcombobox.cpp | 153 | ||||
| -rw-r--r-- | alf/alflabel.cpp | 28 | ||||
| -rw-r--r-- | alf/alflayout.cpp | 48 | ||||
| -rw-r--r-- | alf/alflayout.h | 1 | ||||
| -rw-r--r-- | alf/alfnotebook.cpp | 18 | ||||
| -rw-r--r-- | alf/alfpanel.cpp | 2 | ||||
| -rw-r--r-- | alf/alfwindow.cpp | 56 |
10 files changed, 232 insertions, 121 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp index deffd1a..30a998c 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -174,16 +174,24 @@ ALF_GetModalResult(HWND win) } int -ALF_CentipointsToPixels(HWND win, int cptValue) +ALF_CentipointsToPixels(int cptValue, int dpi) { - return (int)SendMessage(win, ALF_WM_CENTIPOINTTOPX, (WPARAM)cptValue, 0); + return MulDiv(cptValue, dpi, 7200); +} + +int +ALF_GetDpi(HWND window) +{ + return (int)SendMessage(window, ALF_WM_GETDPI, 0, 0); } void ALF_ResizeWindow(HWND win, int cptWidth, int cptHeight) { - int pxwidth = ALF_CentipointsToPixels(win, cptWidth); - int pxheight = ALF_CentipointsToPixels(win, cptHeight); + int dpi = ALF_GetDpi(win); + + int pxwidth = ALF_CentipointsToPixels(cptWidth, dpi); + int pxheight = ALF_CentipointsToPixels(cptHeight, dpi); ALF_ResizeWindowPx(win, pxwidth, pxheight); } @@ -408,7 +416,7 @@ ALF_ShouldMessageBubble(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) if (!GetParent(hwnd)) return FALSE; - return msg == ALF_WM_CENTIPOINTTOPX + return msg == ALF_WM_GETDPI || msg == WM_COMMAND || msg == WM_NOTIFY || msg == WM_MEASUREITEM || msg == WM_DRAWITEM || msg == WM_CTLCOLORBTN || msg == WM_CTLCOLOREDIT @@ -8,12 +8,6 @@ extern "C" { #endif typedef struct { - UINT dpi; - LOGFONT lfMessageFont; - HFONT hMessageFont; -} ALFWindowFonts; - -typedef struct { void (*create)(void * /*closure*/, HWND /*window*/); void (*destroy)(void * /*closure*/, HWND /*window*/); BOOL (*close)(void * /*closure*/, HWND /*window*/); @@ -48,6 +42,7 @@ typedef struct { #define ALF_LAYOUT_INHERITBGCOLOR 0x80 #define ALF_LAYOUT_TRANSPARENTBG 0x100 #define ALF_LAYOUT_SENDBGCHANGE 0x200 +#define ALF_LAYOUT_SENDDPICHANGE 0x400 // label style flags @@ -76,7 +71,7 @@ typedef struct { #define ALF_WM_REMOVEWIDGET (ALF_WM__BASE + 6) #define ALF_WM_SETMODALRESULT (ALF_WM__BASE + 7) #define ALF_WM_GETMODALRESULT (ALF_WM__BASE + 8) -#define ALF_WM_CENTIPOINTTOPX (ALF_WM__BASE + 9) +#define ALF_WM_GETDPI (ALF_WM__BASE + 9) #define ALF_WM_SETFOCUS (ALF_WM__BASE + 10) #define ALF_WM_BACKGROUNDCHANGE (ALF_WM__BASE + 11) #define ALF_WM_APPLYSIZE (ALF_WM__BASE + 12) @@ -106,6 +101,7 @@ typedef struct { #define ALF_WM_LYT_SETROWFLAGS (ALF_WM__BASE + 36) #define ALF_WM_GETTEXTCOLOR (ALF_WM__BASE + 37) #define ALF_WM_SETTEXTCOLOR (ALF_WM__BASE + 38) +#define ALF_WM_DPICHANGE (ALF_WM__BASE + 39) #define ALF_WM_LBL_GETSTYLE (ALF_WM__BASE + 201) #define ALF_WM_LBL_SETSTYLE (ALF_WM__BASE + 202) @@ -173,7 +169,10 @@ BOOL ALF_PreTranslateMessage(HWND hwnd, MSG *message); int -ALF_CentipointsToPixels(HWND win, int cptValue); +ALF_CentipointsToPixels(int cptValue, int dpi); + +int +ALF_GetDpi(HWND hwnd); LRESULT ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); @@ -208,7 +207,7 @@ ALF_InvalidateLayout(HWND win); void ALF_InvalidateBackground(HWND win); -// Recalculates the window's DPI and all fonts and applies them to child widgets. +// Recalculates the window's fonts and applies them to child widgets. // ALF does this automatically on a DPI or settings change so you shouldn't have // to call ALF_UpdateFonts(). void diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp index ddf607d..579fdce 100644 --- a/alf/alfbutton.cpp +++ b/alf/alfbutton.cpp @@ -19,6 +19,7 @@ typedef struct { UINT itemStateCurrent; DWORD uxDefaultAnimationDuration; BOOL uxIsDefaultAnimating; + int dpi; } ALFButtonPriv; static void CALLBACK @@ -294,9 +295,9 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT ALF_Free(textbuf); int xpadding = ALF_Compat_GetSystemMetricsForDpi(SM_CXEDGE, - (UINT)ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 2 + 6; + (UINT)priv->dpi) * 2 + 6; int ypadding = ALF_Compat_GetSystemMetricsForDpi(SM_CYEDGE, - (UINT)ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 2 + 4; + (UINT)priv->dpi) * 2 + 4; SIZE *pSize = (SIZE*)(void*)lParam; if (pSize->cx < r.right - r.left + xpadding) { @@ -473,6 +474,10 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT ALF_InvalidateLayout(GetParent(hwnd)); } else if (uMsg == WM_SETFONT) { ALF_InvalidateLayout(GetParent(hwnd)); + } else if (uMsg == ALF_WM_DPICHANGE) { + priv->dpi = (int)lParam; + ALF_InvalidateLayout(GetParent(hwnd)); + return TRUE; } return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); @@ -494,12 +499,13 @@ ALF_AddButton(HWND win, WORD id, int x, int y, const TCHAR *text) ALFButtonPriv *priv = ALF_New(ALFButtonPriv, 1); priv->uxStateCurrent = -1; priv->uxStatePrev = -1; + priv->dpi = 96; ALF_Compat_SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, (DWORD_PTR)priv); SendMessage(hwndButton, WM_THEMECHANGED, 0, 0); - ALF_AddWidget(win, x, y, hwndButton, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); + ALF_AddWidget(win, x, y, hwndButton, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_SENDDPICHANGE); return hwndButton; } diff --git a/alf/alfcombobox.cpp b/alf/alfcombobox.cpp index 6d3af5e..994806e 100644 --- a/alf/alfcombobox.cpp +++ b/alf/alfcombobox.cpp @@ -17,6 +17,38 @@ typedef struct { DWORD comboStyle; } ALFComboCreateParams; +typedef struct { + HWND hwndChild; + int dpi; +} ALFComboPriv; + +static ALFComboPriv * +ALF_Combo_InitializePriv(HWND hwnd, ALFComboCreateParams *params) +{ + ALFComboPriv *priv = ALF_New(ALFComboPriv, 1); + priv->dpi = 96; + + DWORD comboStyle = params->comboStyle | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS; + + priv->hwndChild = CreateWindowEx(0, + TEXT("COMBOBOX"), + TEXT(""), + 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), + ALF_HINSTANCE, + NULL); + + return priv; +} + +static void +ALF_Combo_FreePriv(ALFComboPriv *priv) +{ + ALF_Free(priv); +} + static int ALF__ComboItemHeight(HWND hwnd) { @@ -48,83 +80,80 @@ ALF__ComboItemHeight(HWND hwnd) static LRESULT CALLBACK ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - HWND hwndChild = (HWND)GetWindowLongPtr(hwnd, 0); + ALFComboPriv *priv = (ALFComboPriv *)GetWindowLongPtr(hwnd, 0); if (uMsg == WM_CREATE) { ALFComboCreateParams *params = (ALFComboCreateParams*)((CREATESTRUCT*)lParam)->lpCreateParams; - DWORD comboStyle = params->comboStyle | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS; - - HWND hwndCombo = CreateWindowEx(0, - TEXT("COMBOBOX"), - TEXT(""), - 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, - NULL); - - SetWindowLongPtr(hwnd, 0, (LONG_PTR)hwndCombo); + + priv = ALF_Combo_InitializePriv(hwnd, params); + SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv); + } + + if (uMsg == WM_DESTROY) { + ALF_Combo_FreePriv(priv); + priv = NULL; + SetWindowLongPtr(hwnd, 0, 0); } - if (uMsg == WM_ENABLE && hwndChild) { - EnableWindow(hwndChild, (BOOL)wParam); + + if (uMsg == WM_ENABLE && priv) { + EnableWindow(priv->hwndChild, (BOOL)wParam); return 0; } - if (uMsg == WM_SETTEXT && hwndChild) { - SetWindowText(hwndChild, (TCHAR*)lParam); + if (uMsg == WM_SETTEXT && priv) { + SetWindowText(priv->hwndChild, (TCHAR*)lParam); ALF_InvalidateLayout(GetParent(hwnd)); } - if (uMsg == WM_GETTEXTLENGTH && hwndChild) { - return (LRESULT)GetWindowTextLength(hwndChild); + if (uMsg == WM_GETTEXTLENGTH && priv) { + return (LRESULT)GetWindowTextLength(priv->hwndChild); } - if (uMsg == WM_GETTEXT && hwndChild) { - return GetWindowText(hwndChild, (TCHAR*)lParam, (int)wParam); + if (uMsg == WM_GETTEXT && priv) { + return GetWindowText(priv->hwndChild, (TCHAR*)lParam, (int)wParam); } - if (uMsg == WM_SETFONT && hwndChild) { - SendMessage(hwndChild, WM_SETFONT, wParam, lParam); - SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)ALF__ComboItemHeight(hwnd)); + if (uMsg == WM_SETFONT && priv) { + SendMessage(priv->hwndChild, WM_SETFONT, wParam, lParam); + SendMessage(priv->hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)ALF__ComboItemHeight(hwnd)); ALF_InvalidateLayout(GetParent(hwnd)); return 0; } - if (uMsg == WM_GETFONT && hwndChild) { - return SendMessage(hwndChild, WM_GETFONT, wParam, lParam); + if (uMsg == WM_GETFONT && priv) { + return SendMessage(priv->hwndChild, WM_GETFONT, wParam, lParam); } - if (uMsg == ALF_CB_GETSTYLE && hwndChild) { - return GetWindowLong(hwndChild, GWL_STYLE); + if (uMsg == ALF_CB_GETSTYLE && priv) { + return GetWindowLong(priv->hwndChild, GWL_STYLE); } - if ((uMsg == ALF_CB_FINDSTRINGEXACT || uMsg == CB_FINDSTRINGEXACT) && hwndChild) { - return SendMessage(hwndChild, CB_FINDSTRINGEXACT, wParam, lParam); + if ((uMsg == ALF_CB_FINDSTRINGEXACT || uMsg == CB_FINDSTRINGEXACT) && priv) { + return SendMessage(priv->hwndChild, CB_FINDSTRINGEXACT, wParam, lParam); } - if ((uMsg == ALF_CB_ADDSTRING || uMsg == CB_ADDSTRING) && hwndChild) { - return SendMessage(hwndChild, CB_ADDSTRING, wParam, lParam); + if ((uMsg == ALF_CB_ADDSTRING || uMsg == CB_ADDSTRING) && priv) { + return SendMessage(priv->hwndChild, CB_ADDSTRING, wParam, lParam); } - if ((uMsg == ALF_CB_INSERTSTRING || uMsg == CB_INSERTSTRING) && hwndChild) { - return SendMessage(hwndChild, CB_INSERTSTRING, wParam, lParam); + if ((uMsg == ALF_CB_INSERTSTRING || uMsg == CB_INSERTSTRING) && priv) { + return SendMessage(priv->hwndChild, CB_INSERTSTRING, wParam, lParam); } - if ((uMsg == ALF_CB_DELETESTRING || uMsg == CB_DELETESTRING) && hwndChild) { - return SendMessage(hwndChild, CB_DELETESTRING, wParam, lParam); + if ((uMsg == ALF_CB_DELETESTRING || uMsg == CB_DELETESTRING) && priv) { + return SendMessage(priv->hwndChild, CB_DELETESTRING, wParam, lParam); } - if ((uMsg == ALF_CB_GETCURSEL || uMsg == CB_GETCURSEL) && hwndChild) { - return SendMessage(hwndChild, CB_GETCURSEL, wParam, lParam); + if ((uMsg == ALF_CB_GETCURSEL || uMsg == CB_GETCURSEL) && priv) { + return SendMessage(priv->hwndChild, CB_GETCURSEL, wParam, lParam); } - if ((uMsg == ALF_CB_SETCURSEL || uMsg == CB_SETCURSEL) && hwndChild) { - LRESULT curSel = SendMessage(hwndChild, CB_GETCURSEL, 0, 0); + if ((uMsg == ALF_CB_SETCURSEL || uMsg == CB_SETCURSEL) && priv) { + LRESULT curSel = SendMessage(priv->hwndChild, CB_GETCURSEL, 0, 0); if ((WPARAM)curSel != wParam) { - LRESULT newSel = SendMessage(hwndChild, CB_SETCURSEL, wParam, 0); - SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(GetWindowLong(hwndChild, GWL_ID), CBN_SELCHANGE), (LPARAM)hwndChild); + LRESULT newSel = SendMessage(priv->hwndChild, CB_SETCURSEL, wParam, 0); + SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(GetWindowLong(priv->hwndChild, GWL_ID), CBN_SELCHANGE), (LPARAM)priv->hwndChild); return newSel; } } - if ((uMsg == ALF_CB_GETLBTEXTLEN || uMsg == CB_GETLBTEXTLEN) && hwndChild) { - return SendMessage(hwndChild, CB_GETLBTEXTLEN, wParam, lParam); + if ((uMsg == ALF_CB_GETLBTEXTLEN || uMsg == CB_GETLBTEXTLEN) && priv) { + return SendMessage(priv->hwndChild, CB_GETLBTEXTLEN, wParam, lParam); } - if ((uMsg == ALF_CB_GETLBTEXT || uMsg == CB_GETLBTEXT) && hwndChild) { - return SendMessage(hwndChild, CB_GETLBTEXT, wParam, lParam); + if ((uMsg == ALF_CB_GETLBTEXT || uMsg == CB_GETLBTEXT) && priv) { + return SendMessage(priv->hwndChild, CB_GETLBTEXT, wParam, lParam); } - if (uMsg == WM_COMMAND && (HWND)lParam == hwndChild) { + if (uMsg == WM_COMMAND && priv && (HWND)lParam == priv->hwndChild) { // 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); @@ -143,12 +172,12 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (GetTextMetrics(hDc, &tm)) { SIZE *ps = (SIZE*)lParam; if (!ps->cx) { - ps->cx = ALF_CentipointsToPixels(GetParent(hwnd), 12000); + ps->cx = ALF_CentipointsToPixels(12000, priv->dpi); } if (!ps->cy) { ps->cy = tm.tmHeight + 2*ALF_Compat_GetSystemMetricsForDpi( - SM_CYEDGE, (UINT)ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + SM_CYEDGE, (UINT)priv->dpi) + 4 /* padding internal to the edit control */; } } @@ -225,30 +254,36 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TRUE; } - if (uMsg == WM_WINDOWPOSCHANGED && hwndChild) { + if (uMsg == WM_WINDOWPOSCHANGED && priv) { WINDOWPOS *pos = (WINDOWPOS *)lParam; if (!(pos->flags & SWP_NOSIZE)) { // 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 - LRESULT sel = SendMessage(hwndChild, CB_GETEDITSEL, 0, 0); - SendMessage(hwndChild, CB_SETEDITSEL, 0, -1); + LRESULT sel = SendMessage(priv->hwndChild, CB_GETEDITSEL, 0, 0); + SendMessage(priv->hwndChild, CB_SETEDITSEL, 0, -1); // SWP_NOCOPYBITS because NT 3.51 doesn't properly repaint the drop-down button - SetWindowPos(hwndChild, NULL, 0, 0, pos->cx, 200, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS); - SendMessage(hwndChild, CB_SETEDITSEL, 0, (LPARAM)sel); + SetWindowPos(priv->hwndChild, NULL, 0, 0, pos->cx, 200, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS); + SendMessage(priv->hwndChild, CB_SETEDITSEL, 0, (LPARAM)sel); int heightOffset = 0; if (ALF_Compat_IsMinWindowsVersion(4, 0)) { heightOffset = - 2*ALF_Compat_GetSystemMetricsForDpi( - SM_CYEDGE, (UINT)ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + SM_CYEDGE, (UINT)priv->dpi) - 2; } - SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)-1, pos->cy + heightOffset); - SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)ALF__ComboItemHeight(hwnd)); + SendMessage(priv->hwndChild, CB_SETITEMHEIGHT, (WPARAM)-1, pos->cy + heightOffset); + SendMessage(priv->hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)ALF__ComboItemHeight(hwnd)); } } + if (uMsg == ALF_WM_DPICHANGE && priv) { + priv->dpi = (int)lParam; + ALF_InvalidateLayout(GetParent(hwnd)); + return TRUE; + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); } @@ -295,7 +330,7 @@ ALF_InternalAddComboBox(HWND win, WORD id, int x, int y, DWORD style, const TCHA if (defaultText) SetWindowText(hwndCombo, defaultText); - ALF_AddWidget(win, x, y, hwndCombo, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); + ALF_AddWidget(win, x, y, hwndCombo, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_SENDDPICHANGE); return hwndCombo; } diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp index 37f1e83..13c86ae 100644 --- a/alf/alflabel.cpp +++ b/alf/alflabel.cpp @@ -7,27 +7,32 @@ typedef struct { HFONT font; ALFColor bgcolor; ALFColor textcolor; + int dpi; } ALFLabelPriv; TCHAR *_alf_labelClass; static int -ALF__LabelTopPadding(HWND hwnd) +ALF__LabelTopPadding(HWND hwnd, ALFLabelPriv *priv) { + (void)hwnd; + // some pixels on top to align with the edit control // see also: alfedit.cpp return ALF_Compat_GetSystemMetricsForDpi( - SM_CYEDGE, (UINT)ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + SM_CYEDGE, (UINT)priv->dpi) + (!ALF_Compat_IsMinWindowsVersion(4, 0) ? 2 : 1) /* internal padding in edit control */; } static int -ALF__LabelLeftPadding(HWND hwnd, HDC hdc) +ALF__LabelLeftPadding(HWND hwnd, HDC hdc, ALFLabelPriv *priv) { + (void)hwnd; + // some pixels on the left to align with the edit control // see also: alfedit.cpp int p = ALF_Compat_GetSystemMetricsForDpi( - SM_CXEDGE, (UINT)ALF_CentipointsToPixels(GetParent(hwnd), 7200)); + SM_CXEDGE, (UINT)priv->dpi); p += 1; @@ -98,9 +103,9 @@ ALF_Label_Paint(HWND hwnd, ALFLabelPriv *priv, HDC hdc, RECT *r) } if ((priv->style & ALF_LABEL_HALIGN_MASK) == ALF_LABEL_ALIGN_LEFT_LIKE_EDIT) - rc.left += ALF__LabelLeftPadding(hwnd, hdc); + rc.left += ALF__LabelLeftPadding(hwnd, hdc, priv); if ((priv->style & ALF_LABEL_VALIGN_MASK) == ALF_LABEL_ALIGN_TOP_LIKE_EDIT) - rc.top += ALF__LabelTopPadding(hwnd); + rc.top += ALF__LabelTopPadding(hwnd, priv); TCHAR *text = ALF_Text(hwnd); @@ -160,12 +165,12 @@ ALF_Label_CalculateSize(HWND hwnd, ALFLabelPriv *priv, SIZE *pSize) if (pSize->cx == 0) { pSize->cx = r.right - r.left; if ((priv->style & ALF_LABEL_HALIGN_MASK) == ALF_LABEL_ALIGN_LEFT_LIKE_EDIT) - pSize->cx += ALF__LabelLeftPadding(hwnd, hdcLabel); + pSize->cx += ALF__LabelLeftPadding(hwnd, hdcLabel, priv); } if (pSize->cy == 0) { pSize->cy = r.bottom - r.top; if ((priv->style & ALF_LABEL_VALIGN_MASK) == ALF_LABEL_ALIGN_TOP_LIKE_EDIT) - pSize->cy += ALF__LabelTopPadding(hwnd); + pSize->cy += ALF__LabelTopPadding(hwnd, priv); } SelectFont(hdcLabel, oldFont); @@ -275,6 +280,10 @@ ALF__LabelWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TRUE; } else if (uMsg == ALF_WM_GETTEXTCOLOR) { return (LRESULT)priv->textcolor; + } else if (uMsg == ALF_WM_DPICHANGE) { + priv->dpi = (int)lParam; + ALF_InvalidateLayout(GetParent(hwnd)); + return TRUE; } else if (uMsg == WM_DESTROY) { ALF_Free(priv); SetWindowLongPtr(hwnd, 0, 0); @@ -299,9 +308,10 @@ ALF_AddLabel(HWND win, WORD id, int x, int y, const TCHAR *text) priv->style = ALF_LABEL_ALIGN_LEFT | ALF_LABEL_ALIGN_TOP_LIKE_EDIT; priv->bgcolor = ALF_COLOR_SYS(COLOR_BTNFACE); priv->textcolor = ALF_COLOR_SYS(COLOR_BTNTEXT); + priv->dpi = 96; SetWindowLongPtr(hwndLabel, 0, (LONG_PTR)priv); - ALF_AddWidget(win, x, y, hwndLabel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE); + ALF_AddWidget(win, x, y, hwndLabel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE | ALF_LAYOUT_SENDDPICHANGE); return hwndLabel; } diff --git a/alf/alflayout.cpp b/alf/alflayout.cpp index 5c1ad55..15b8f5d 100644 --- a/alf/alflayout.cpp +++ b/alf/alflayout.cpp @@ -76,6 +76,7 @@ ALF_Layout_Init(ALFLayout *layout) layout->rows = ALF_New(ALFLayoutRowOrColumn, (SIZE_T)layout->nRows); layout->nColumns = 1; layout->columns = ALF_New(ALFLayoutRowOrColumn, (SIZE_T)layout->nColumns); + layout->dpi = 96; } void @@ -127,6 +128,20 @@ ALF_Layout_ForwardBgColor(ALFLayout *layout, HWND window, WPARAM wparam, LPARAM } static void +ALF_Layout_ForwardDpiChange(ALFLayout *layout, HWND window, WPARAM wparam, LPARAM lparam) +{ + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, i) { + if (i->flags & ALF_LAYOUT_SENDDPICHANGE) { + SendMessage(i->hwnd, ALF_WM_DPICHANGE, wparam, lparam); + } + + if (i->flags & ALF_LAYOUT_SIZE_EDIT) { + ALF_Layout_Invalidate(layout, window); + } + } +} + +static void ALF_Layout_HandleBackgroundChange(ALFLayout *layout, HWND window) { (void)window; @@ -162,7 +177,7 @@ ALF_Layout_EnsureColumnExists(ALFLayout *layout, int colno) static void ALF_Layout_CalcEditSize(HWND hwndWindow, ALFLayout *layout, HWND hwndEdit, SIZE *ps) { - (void)layout; + (void)hwndWindow; HDC hDc = GetDC(hwndEdit); HFONT font = (HFONT)SendMessage(hwndEdit, WM_GETFONT, 0, 0); @@ -174,12 +189,12 @@ ALF_Layout_CalcEditSize(HWND hwndWindow, ALFLayout *layout, HWND hwndEdit, SIZE if (GetTextMetrics(hDc, &tm)) { if (!ps->cx) { - ps->cx = ALF_CentipointsToPixels(hwndWindow, 12000); + ps->cx = ALF_CentipointsToPixels(12000, layout->dpi); } if (!ps->cy) { ps->cy = tm.tmHeight + 2*ALF_Compat_GetSystemMetricsForDpi( - SM_CYEDGE, (UINT)ALF_CentipointsToPixels(hwndWindow, 7200)) + SM_CYEDGE, (UINT)layout->dpi) + 4 /* padding internal to the edit control */; } } @@ -196,8 +211,8 @@ ALF_Layout_CalcMinWidgetSize(ALFLayout *layout, ALFWidgetPriv *c, HWND window, S s->cx = c->width; s->cy = c->height; } else { - s->cx = ALF_CentipointsToPixels(window, c->width); - s->cy = ALF_CentipointsToPixels(window, c->height); + s->cx = ALF_CentipointsToPixels(c->width, layout->dpi); + s->cy = ALF_CentipointsToPixels(c->height, layout->dpi); } switch (c->flags & ALF_LAYOUT_SIZETYPE_MASK) { @@ -224,7 +239,7 @@ ALF_Layout_CalcSizes(ALFLayout* layout, HWND window) if (layout->columns[i].requestedFlags & ALF_LAYOUT_SIZE_PX) { layout->columns[i].calculatedMinWidth = layout->columns[i].requestedMinWidth; } else { - layout->columns[i].calculatedMinWidth = ALF_CentipointsToPixels(window, layout->columns[i].requestedMinWidth); + layout->columns[i].calculatedMinWidth = ALF_CentipointsToPixels(layout->columns[i].requestedMinWidth, layout->dpi); } layout->columns[i].calculatedExpandNumerator = layout->columns[i].requestedExpandNumerator; @@ -239,7 +254,7 @@ ALF_Layout_CalcSizes(ALFLayout* layout, HWND window) if (layout->rows[i].requestedFlags & ALF_LAYOUT_SIZE_PX) { layout->rows[i].calculatedMinWidth = layout->rows[i].requestedMinWidth; } else { - layout->rows[i].calculatedMinWidth = ALF_CentipointsToPixels(window, layout->rows[i].requestedMinWidth); + layout->rows[i].calculatedMinWidth = ALF_CentipointsToPixels(layout->rows[i].requestedMinWidth, layout->dpi); } layout->rows[i].calculatedExpandNumerator = layout->rows[i].requestedExpandNumerator; layout->rowExpandDenominator += layout->rows[i].requestedExpandNumerator; @@ -447,6 +462,9 @@ ALF_Layout_AddWidget(ALFLayout* layout, HWND window, const ALFAddWidgetParams* p if (w->flags & ALF_LAYOUT_INHERITBGCOLOR) { SendMessage(w->hwnd, ALF_WM_SETBGCOLOR, 0, (LPARAM)ALF_BackgroundColor(window)); } + if (w->flags & ALF_LAYOUT_SENDDPICHANGE) { + SendMessage(w->hwnd, ALF_WM_DPICHANGE, 0, (LPARAM)layout->dpi); + } ALF_ListInsert(layout->widgets.prev, &w->list); @@ -602,6 +620,8 @@ ALF_Layout_SetWidgetFlags(ALFLayout *layout, HWND window, HWND needle, DWORD fla ALF_Layout_ForwardFontToWidget(layout, window, w, (HFONT)SendMessage(window, WM_GETFONT, 0, 0), 0); if (flags & ALF_LAYOUT_INHERITBGCOLOR) SendMessage(w->hwnd, ALF_WM_SETBGCOLOR, 0, (LPARAM)ALF_BackgroundColor(window)); + if (flags & ALF_LAYOUT_SENDDPICHANGE) + SendMessage(w->hwnd, ALF_WM_DPICHANGE, 0, (LPARAM)layout->dpi); ALF_Layout_Invalidate(layout, window); @@ -792,6 +812,20 @@ ALF_Layout_HandleMessage(ALFLayout *layout, HWND hwnd, UINT msg, WPARAM wparam, return TRUE; } + if (msg == ALF_WM_DPICHANGE) { + int dpi = (int)lparam; + if (dpi != layout->dpi) { + layout->dpi = dpi; + ALF_Layout_ForwardDpiChange(layout, hwnd, wparam, lparam); + ALF_Layout_Invalidate(layout, hwnd); + } + return TRUE; + } + + if (msg == ALF_WM_GETDPI) { + return (LRESULT)layout->dpi; + } + if (msg == ALF_WM_INVALIDATELAYOUT) { ALF_Layout_Invalidate(layout, hwnd); return TRUE; diff --git a/alf/alflayout.h b/alf/alflayout.h index ce2350f..4d97eb5 100644 --- a/alf/alflayout.h +++ b/alf/alflayout.h @@ -53,6 +53,7 @@ typedef struct { int biggestColumnNo; int biggestRowNo; DWORD layoutValididityFlags; + int dpi; } ALFLayout; void diff --git a/alf/alfnotebook.cpp b/alf/alfnotebook.cpp index 501b072..6ffbe5d 100644 --- a/alf/alfnotebook.cpp +++ b/alf/alfnotebook.cpp @@ -17,6 +17,7 @@ typedef struct { HTHEME hTheme; ALFColor themeTabBgColor; DWORD flags; + int dpi; } ALFNotebookPriv; typedef struct { @@ -137,6 +138,16 @@ ALF_Notebook_PropagateFontToPages(HWND hwndNotebook, ALFNotebookPriv *priv, HFON } static void +ALF_Notebook_PropagateDpiChange(HWND hwndNotebook, ALFNotebookPriv *priv, WPARAM wparam, LPARAM lparam) +{ + int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl); + for (int i = 0; i < n; ++i) { + HWND hwndPanel = ALF_NotebookTabPanel(hwndNotebook, i); + SendMessage(hwndPanel, ALF_WM_DPICHANGE, wparam, lparam); + } +} + +static void ALF_Notebook_InternalHandleThemeChange(HWND hwndNotebook, ALFNotebookPriv *priv) { ALF_Compat_CloseThemeData(priv->hTheme); @@ -172,6 +183,7 @@ ALF_Notebook_InternalAddTab(HWND notebook, ALFNotebookPriv *priv, const TCHAR *t SetWindowPos(hwndPanel, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOOWNERZORDER); SendMessage(hwndPanel, WM_SETFONT, (WPARAM)SendMessage(priv->hwndTabCtrl, WM_GETFONT, 0, 0), 0); + SendMessage(hwndPanel, ALF_WM_DPICHANGE, 0, (LPARAM)priv->dpi); ALF_Notebook_SetSingleTabBackground(notebook, priv, hwndPanel); @@ -458,6 +470,10 @@ ALF__NotebookWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return (LRESULT)ALF_Notebook_GetWidgetFlags(hwnd, priv, (HWND)wParam); } else if (uMsg == ALF_WM_LYT_SETWDGTFLAGS) { return (LRESULT)ALF_Notebook_SetWidgetFlags(hwnd, priv, (HWND)wParam, (DWORD)lParam); + } else if (uMsg == ALF_WM_DPICHANGE) { + priv->dpi = (int)lParam; + ALF_Notebook_PropagateDpiChange(hwnd, priv, wParam, lParam); + return TRUE; } return DefWindowProc(hwnd, uMsg, wParam, lParam); @@ -499,7 +515,7 @@ ALF_AddNotebook(HWND parent, WORD id, int x, int y) ALF_HINSTANCE, NULL); - ALF_AddWidget(parent, x, y, hwndNtbk, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); + ALF_AddWidget(parent, x, y, hwndNtbk, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_SENDDPICHANGE); return hwndNtbk; } diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp index 7e109bb..663dbd0 100644 --- a/alf/alfpanel.cpp +++ b/alf/alfpanel.cpp @@ -210,7 +210,7 @@ ALF_AddPanel(HWND parent, WORD id, int x, int y) { HWND hwndPanel = ALF_CreatePanelWindow(parent, id); - ALF_AddWidget(parent, x, y, hwndPanel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE); + ALF_AddWidget(parent, x, y, hwndPanel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE | ALF_LAYOUT_SENDDPICHANGE); return hwndPanel; } diff --git a/alf/alfwindow.cpp b/alf/alfwindow.cpp index c11fede..d372ebc 100644 --- a/alf/alfwindow.cpp +++ b/alf/alfwindow.cpp @@ -3,12 +3,12 @@ typedef struct { ALFWindowVTable *vtbl; void *closure; - ALFWindowFonts fonts; int modalResult; ALFLayout layout; WORD defid; HWND hwndFocus; HFONT font; + HFONT hMessageFont; ALFColor bgcolor; } ALFWindowPriv; @@ -30,8 +30,8 @@ ALF_DestroyWindowPriv(ALFWindowPriv *priv) ALF_Layout_Clear(&priv->layout); - if (priv->fonts.hMessageFont) - DeleteObject(priv->fonts.hMessageFont); + if (priv->hMessageFont) + DeleteObject(priv->hMessageFont); ALF_Free(priv); } @@ -39,39 +39,34 @@ ALF_DestroyWindowPriv(ALFWindowPriv *priv) static void ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) { - priv->fonts.dpi = ALF_Compat_GetDpiForWindow(win); - // XXX: SystemParametersInfoForDpi is Unicode-only and needs Vista+ NONCLIENTMETRICS, ALF_NONCLIENTMETRICSW_VISTA ncm; ZeroMemory(&ncm, sizeof(ncm)); ncm.cbSize = sizeof(ncm); - if (ALF_Compat_SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) { + LOGFONT lfMessageFont; + ZeroMemory(&lfMessageFont, sizeof(lfMessageFont)); + + if (ALF_Compat_SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, (UINT)priv->layout.dpi)) { #ifdef UNICODE - priv->fonts.lfMessageFont = ncm.lfMessageFont; + lfMessageFont = ncm.lfMessageFont; #else - ALF_Compat_LogFontWtoA(&ncm.lfMessageFont, &priv->fonts.lfMessageFont); + ALF_Compat_LogFontWtoA(&ncm.lfMessageFont, &lfMessageFont); #endif } else { // FIXME! fallback to default font, 8pt MS Shell Dlg - ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont)); + ZeroMemory(&lfMessageFont, sizeof(lfMessageFont)); - priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, (int)priv->fonts.dpi, 72); - lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg")); + lfMessageFont.lfHeight = -MulDiv(8, priv->layout.dpi, 72); + lstrcpy(lfMessageFont.lfFaceName, TEXT("MS Shell Dlg")); } - if (priv->fonts.hMessageFont) { - DeleteObject(priv->fonts.hMessageFont); + if (priv->hMessageFont) { + DeleteObject(priv->hMessageFont); } - priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont); - - SendMessage(win, WM_SETFONT, (WPARAM)priv->fonts.hMessageFont, (LPARAM)1); -} + priv->hMessageFont = CreateFontIndirect(&lfMessageFont); -static int -ALF_CentipointsToPxPriv(ALFWindowPriv *priv, int cptValue) -{ - return MulDiv(cptValue, (int)priv->fonts.dpi, 7200); + SendMessage(win, WM_SETFONT, (WPARAM)priv->hMessageFont, (LPARAM)1); } static void @@ -173,8 +168,8 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) return 0; } - if (msg == ALF_WM_CENTIPOINTTOPX) { - return (LRESULT)ALF_CentipointsToPxPriv(priv, (int)wparam); + if (msg == ALF_WM_GETDPI) { + return (LRESULT)priv->layout.dpi; } if (msg == ALF_WM_SETFOCUS) { @@ -327,7 +322,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) (DWORD)GetWindowLong(hwnd, GWL_STYLE), GetMenu(hwnd) != NULL, (DWORD)GetWindowLong(hwnd, GWL_EXSTYLE), - priv->fonts.dpi)) { + (UINT)priv->layout.dpi)) { MINMAXINFO *i = (MINMAXINFO *)lparam; i->ptMinTrackSize.x = tmp.right - tmp.left; i->ptMinTrackSize.y = tmp.bottom - tmp.top; @@ -336,7 +331,9 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } if (msg == WM_CREATE) { - ALF_UpdateFontsPriv(hwnd, priv); + int dpi = (int)ALF_Compat_GetDpiForWindow(hwnd); + SendMessage(hwnd, ALF_WM_DPICHANGE, 0, (LPARAM)dpi); // will also update fonts + if (priv->vtbl->create) { priv->vtbl->create(priv->closure, hwnd); } @@ -366,8 +363,9 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } if (msg == WM_DPICHANGED) { - ALF_UpdateFontsPriv(hwnd, priv); - ALF_Layout_Invalidate(&priv->layout, hwnd); + int dpi = LOWORD(wparam); + SendMessage(hwnd, ALF_WM_DPICHANGE, 0, (LPARAM)dpi); // will also update fonts and invalidate layout + RECT *r = (RECT*)lparam; SetWindowPos(hwnd, NULL, r->left, r->top, r->right-r->left, r->bottom-r->top, SWP_NOACTIVATE|SWP_NOZORDER); } @@ -428,6 +426,10 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } } + if (msg == ALF_WM_DPICHANGE) { + ALF_UpdateFontsPriv(hwnd, priv); + } + return ret; } |
