diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2020-07-06 16:07:05 +1000 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2020-07-06 21:30:49 +1000 |
commit | 2e0773ed3169889f6246271ef6fffe6f8ce16f89 (patch) | |
tree | 564c823112bc29dec6bbf394b7358547d4d1de59 | |
parent | a44cba1e241d0aa7d5c64595e9e7c95d0f06cced (diff) | |
download | wix-2e0773ed3169889f6246271ef6fffe6f8ce16f89.tar.gz wix-2e0773ed3169889f6246271ef6fffe6f8ce16f89.tar.bz2 wix-2e0773ed3169889f6246271ef6fffe6f8ce16f89.zip |
Scale the x/y/width/height of theme controls according to the DPI.
-rw-r--r-- | src/dutil/inc/thmutil.h | 5 | ||||
-rw-r--r-- | src/dutil/thmutil.cpp | 107 |
2 files changed, 87 insertions, 25 deletions
diff --git a/src/dutil/inc/thmutil.h b/src/dutil/inc/thmutil.h index 52de755f..e65d0646 100644 --- a/src/dutil/inc/thmutil.h +++ b/src/dutil/inc/thmutil.h | |||
@@ -143,6 +143,10 @@ struct THEME_CONTROL | |||
143 | LPWSTR sczText; | 143 | LPWSTR sczText; |
144 | LPWSTR sczTooltip; | 144 | LPWSTR sczTooltip; |
145 | LPWSTR sczNote; // optional text for command link | 145 | LPWSTR sczNote; // optional text for command link |
146 | int nDefaultDpiX; | ||
147 | int nDefaultDpiY; | ||
148 | int nDefaultDpiHeight; | ||
149 | int nDefaultDpiWidth; | ||
146 | int nX; | 150 | int nX; |
147 | int nY; | 151 | int nY; |
148 | int nHeight; | 152 | int nHeight; |
@@ -250,6 +254,7 @@ struct THEME | |||
250 | WORD wId; | 254 | WORD wId; |
251 | 255 | ||
252 | BOOL fAutoResize; | 256 | BOOL fAutoResize; |
257 | BOOL fForceResize; | ||
253 | 258 | ||
254 | DWORD dwStyle; | 259 | DWORD dwStyle; |
255 | DWORD dwFontId; | 260 | DWORD dwFontId; |
diff --git a/src/dutil/thmutil.cpp b/src/dutil/thmutil.cpp index 4cc149c9..8ff73939 100644 --- a/src/dutil/thmutil.cpp +++ b/src/dutil/thmutil.cpp | |||
@@ -313,8 +313,8 @@ static const THEME_CONTROL* FindControlFromHWnd( | |||
313 | __in_opt const THEME_CONTROL* pParentControl = NULL | 313 | __in_opt const THEME_CONTROL* pParentControl = NULL |
314 | ); | 314 | ); |
315 | static void GetControlDimensions( | 315 | static void GetControlDimensions( |
316 | __in const RECT* prcParent, | ||
317 | __in const THEME_CONTROL* pControl, | 316 | __in const THEME_CONTROL* pControl, |
317 | __in const RECT* prcParent, | ||
318 | __out int* piWidth, | 318 | __out int* piWidth, |
319 | __out int* piHeight, | 319 | __out int* piHeight, |
320 | __out int* piX, | 320 | __out int* piX, |
@@ -364,6 +364,15 @@ static void ScaleTheme( | |||
364 | __in int x, | 364 | __in int x, |
365 | __in int y | 365 | __in int y |
366 | ); | 366 | ); |
367 | static void ScaleControls( | ||
368 | __in DWORD cControls, | ||
369 | __in THEME_CONTROL* rgControls, | ||
370 | __in UINT nDpi | ||
371 | ); | ||
372 | static void ScaleControl( | ||
373 | __in THEME_CONTROL* pControl, | ||
374 | __in UINT nDpi | ||
375 | ); | ||
367 | static void GetControls( | 376 | static void GetControls( |
368 | __in THEME* pTheme, | 377 | __in THEME* pTheme, |
369 | __in_opt THEME_CONTROL* pParentControl, | 378 | __in_opt THEME_CONTROL* pParentControl, |
@@ -885,8 +894,9 @@ extern "C" LRESULT CALLBACK ThemeDefWindowProc( | |||
885 | break; | 894 | break; |
886 | 895 | ||
887 | case WM_SIZE: | 896 | case WM_SIZE: |
888 | if (pTheme->fAutoResize) | 897 | if (pTheme->fAutoResize || pTheme->fForceResize) |
889 | { | 898 | { |
899 | pTheme->fForceResize = FALSE; | ||
890 | ::GetClientRect(pTheme->hwndParent, &rcParent); | 900 | ::GetClientRect(pTheme->hwndParent, &rcParent); |
891 | ResizeControls(pTheme->cControls, pTheme->rgControls, &rcParent); | 901 | ResizeControls(pTheme->cControls, pTheme->rgControls, &rcParent); |
892 | return 0; | 902 | return 0; |
@@ -2540,10 +2550,10 @@ static HRESULT ParseControls( | |||
2540 | 2550 | ||
2541 | if (fBillboardSizing) | 2551 | if (fBillboardSizing) |
2542 | { | 2552 | { |
2543 | pControl->nX = 0; | 2553 | pControl->nX = pControl->nDefaultDpiX = 0; |
2544 | pControl->nY = 0; | 2554 | pControl->nY = pControl->nDefaultDpiY = 0; |
2545 | pControl->nWidth = -0; | 2555 | pControl->nWidth = pControl->nDefaultDpiWidth = 0; |
2546 | pControl->nHeight = 0; | 2556 | pControl->nHeight = pControl->nDefaultDpiHeight = 0; |
2547 | } | 2557 | } |
2548 | 2558 | ||
2549 | if (pPage) | 2559 | if (pPage) |
@@ -2616,33 +2626,41 @@ static HRESULT ParseControl( | |||
2616 | 2626 | ||
2617 | if (!fSkipDimensions) | 2627 | if (!fSkipDimensions) |
2618 | { | 2628 | { |
2619 | hr = XmlGetAttributeNumber(pixn, L"X", reinterpret_cast<DWORD*>(&pControl->nX)); | 2629 | hr = XmlGetAttributeNumber(pixn, L"X", &dwValue); |
2620 | if (S_FALSE == hr) | 2630 | if (S_FALSE == hr) |
2621 | { | 2631 | { |
2622 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2632 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); |
2623 | } | 2633 | } |
2624 | ThmExitOnFailure(hr, "Failed to find control X attribute."); | 2634 | ThmExitOnFailure(hr, "Failed to find control X attribute."); |
2625 | 2635 | ||
2626 | hr = XmlGetAttributeNumber(pixn, L"Y", reinterpret_cast<DWORD*>(&pControl->nY)); | 2636 | pControl->nX = pControl->nDefaultDpiX = dwValue; |
2637 | |||
2638 | hr = XmlGetAttributeNumber(pixn, L"Y", &dwValue); | ||
2627 | if (S_FALSE == hr) | 2639 | if (S_FALSE == hr) |
2628 | { | 2640 | { |
2629 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2641 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); |
2630 | } | 2642 | } |
2631 | ThmExitOnFailure(hr, "Failed to find control Y attribute."); | 2643 | ThmExitOnFailure(hr, "Failed to find control Y attribute."); |
2632 | 2644 | ||
2633 | hr = XmlGetAttributeNumber(pixn, L"Height", reinterpret_cast<DWORD*>(&pControl->nHeight)); | 2645 | pControl->nY = pControl->nDefaultDpiY = dwValue; |
2646 | |||
2647 | hr = XmlGetAttributeNumber(pixn, L"Height", &dwValue); | ||
2634 | if (S_FALSE == hr) | 2648 | if (S_FALSE == hr) |
2635 | { | 2649 | { |
2636 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2650 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); |
2637 | } | 2651 | } |
2638 | ThmExitOnFailure(hr, "Failed to find control Height attribute."); | 2652 | ThmExitOnFailure(hr, "Failed to find control Height attribute."); |
2639 | 2653 | ||
2640 | hr = XmlGetAttributeNumber(pixn, L"Width", reinterpret_cast<DWORD*>(&pControl->nWidth)); | 2654 | pControl->nHeight = pControl->nDefaultDpiHeight = dwValue; |
2655 | |||
2656 | hr = XmlGetAttributeNumber(pixn, L"Width", &dwValue); | ||
2641 | if (S_FALSE == hr) | 2657 | if (S_FALSE == hr) |
2642 | { | 2658 | { |
2643 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 2659 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); |
2644 | } | 2660 | } |
2645 | ThmExitOnFailure(hr, "Failed to find control Width attribute."); | 2661 | ThmExitOnFailure(hr, "Failed to find control Width attribute."); |
2662 | |||
2663 | pControl->nWidth = pControl->nDefaultDpiWidth = dwValue; | ||
2646 | } | 2664 | } |
2647 | 2665 | ||
2648 | // Parse the optional background resource image. | 2666 | // Parse the optional background resource image. |
@@ -4203,6 +4221,8 @@ static BOOL OnDpiChanged( | |||
4203 | ExitFunction(); | 4221 | ExitFunction(); |
4204 | } | 4222 | } |
4205 | 4223 | ||
4224 | |||
4225 | pTheme->fForceResize = !pTheme->fAutoResize; | ||
4206 | ScaleTheme(pTheme, nDpi, pRect->left, pRect->top); | 4226 | ScaleTheme(pTheme, nDpi, pRect->left, pRect->top); |
4207 | 4227 | ||
4208 | LExit: | 4228 | LExit: |
@@ -4319,18 +4339,18 @@ static const THEME_CONTROL* FindControlFromHWnd( | |||
4319 | } | 4339 | } |
4320 | 4340 | ||
4321 | static void GetControlDimensions( | 4341 | static void GetControlDimensions( |
4322 | __in const RECT* prcParent, | ||
4323 | __in const THEME_CONTROL* pControl, | 4342 | __in const THEME_CONTROL* pControl, |
4343 | __in const RECT* prcParent, | ||
4324 | __out int* piWidth, | 4344 | __out int* piWidth, |
4325 | __out int* piHeight, | 4345 | __out int* piHeight, |
4326 | __out int* piX, | 4346 | __out int* piX, |
4327 | __out int* piY | 4347 | __out int* piY |
4328 | ) | 4348 | ) |
4329 | { | 4349 | { |
4330 | *piWidth = pControl->nWidth < 1 ? pControl->nX < 0 ? prcParent->right + pControl->nWidth : prcParent->right + pControl->nWidth - pControl->nX : pControl->nWidth; | 4350 | *piWidth = pControl->nWidth + (0 < pControl->nWidth ? 0 : prcParent->right - max(0, pControl->nX)); |
4331 | *piHeight = pControl->nHeight < 1 ? pControl->nY < 0 ? prcParent->bottom + pControl->nHeight : prcParent->bottom + pControl->nHeight - pControl->nY : pControl->nHeight; | 4351 | *piHeight = pControl->nHeight + (0 < pControl->nHeight ? 0 : prcParent->bottom - max(0, pControl->nY)); |
4332 | *piX = pControl->nX < 0 ? prcParent->right + pControl->nX - *piWidth : pControl->nX; | 4352 | *piX = pControl->nX + (-1 < pControl->nX ? 0 : prcParent->right - *piWidth); |
4333 | *piY = pControl->nY < 0 ? prcParent->bottom + pControl->nY - *piHeight : pControl->nY; | 4353 | *piY = pControl->nY + (-1 < pControl->nY ? 0 : prcParent->bottom - *piHeight); |
4334 | } | 4354 | } |
4335 | 4355 | ||
4336 | static HRESULT SizeListViewColumns( | 4356 | static HRESULT SizeListViewColumns( |
@@ -4752,6 +4772,10 @@ static HRESULT LoadControls( | |||
4752 | DWORD cControls = 0; | 4772 | DWORD cControls = 0; |
4753 | THEME_CONTROL* rgControls = NULL; | 4773 | THEME_CONTROL* rgControls = NULL; |
4754 | HWND hwndParent = pParentControl ? pParentControl->hWnd : pTheme->hwndParent; | 4774 | HWND hwndParent = pParentControl ? pParentControl->hWnd : pTheme->hwndParent; |
4775 | int w = 0; | ||
4776 | int h = 0; | ||
4777 | int x = 0; | ||
4778 | int y = 0; | ||
4755 | 4779 | ||
4756 | GetControls(pTheme, pParentControl, cControls, rgControls); | 4780 | GetControls(pTheme, pParentControl, cControls, rgControls); |
4757 | ::GetClientRect(hwndParent, &rcParent); | 4781 | ::GetClientRect(hwndParent, &rcParent); |
@@ -4910,8 +4934,7 @@ static HRESULT LoadControls( | |||
4910 | 4934 | ||
4911 | pControl->wId = wControlId; | 4935 | pControl->wId = wControlId; |
4912 | 4936 | ||
4913 | int w, h, x, y; | 4937 | GetControlDimensions(pControl, &rcParent, &w, &h, &x, &y); |
4914 | GetControlDimensions(&rcParent, pControl, &w, &h, &x, &y); | ||
4915 | 4938 | ||
4916 | BOOL fVisible = pControl->dwStyle & WS_VISIBLE; | 4939 | BOOL fVisible = pControl->dwStyle & WS_VISIBLE; |
4917 | BOOL fDisabled = pControl->dwStyle & WS_DISABLED; | 4940 | BOOL fDisabled = pControl->dwStyle & WS_DISABLED; |
@@ -5198,22 +5221,22 @@ static HRESULT LocalizeControl( | |||
5198 | 5221 | ||
5199 | if (LOC_CONTROL_NOT_SET != pLocControl->nX) | 5222 | if (LOC_CONTROL_NOT_SET != pLocControl->nX) |
5200 | { | 5223 | { |
5201 | pControl->nX = pLocControl->nX; | 5224 | pControl->nDefaultDpiX = pLocControl->nX; |
5202 | } | 5225 | } |
5203 | 5226 | ||
5204 | if (LOC_CONTROL_NOT_SET != pLocControl->nY) | 5227 | if (LOC_CONTROL_NOT_SET != pLocControl->nY) |
5205 | { | 5228 | { |
5206 | pControl->nY = pLocControl->nY; | 5229 | pControl->nDefaultDpiY = pLocControl->nY; |
5207 | } | 5230 | } |
5208 | 5231 | ||
5209 | if (LOC_CONTROL_NOT_SET != pLocControl->nWidth) | 5232 | if (LOC_CONTROL_NOT_SET != pLocControl->nWidth) |
5210 | { | 5233 | { |
5211 | pControl->nWidth = pLocControl->nWidth; | 5234 | pControl->nDefaultDpiWidth = pLocControl->nWidth; |
5212 | } | 5235 | } |
5213 | 5236 | ||
5214 | if (LOC_CONTROL_NOT_SET != pLocControl->nHeight) | 5237 | if (LOC_CONTROL_NOT_SET != pLocControl->nHeight) |
5215 | { | 5238 | { |
5216 | pControl->nHeight = pLocControl->nHeight; | 5239 | pControl->nDefaultDpiHeight = pLocControl->nHeight; |
5217 | } | 5240 | } |
5218 | 5241 | ||
5219 | if (pLocControl->wzText && *pLocControl->wzText) | 5242 | if (pLocControl->wzText && *pLocControl->wzText) |
@@ -5304,10 +5327,14 @@ static void ResizeControl( | |||
5304 | __in const RECT* prcParent | 5327 | __in const RECT* prcParent |
5305 | ) | 5328 | ) |
5306 | { | 5329 | { |
5307 | int w, h, x, y; | 5330 | int w = 0; |
5331 | int h = 0; | ||
5332 | int x = 0; | ||
5333 | int y = 0; | ||
5334 | RECT rcControl = { }; | ||
5308 | 5335 | ||
5309 | GetControlDimensions(prcParent, pControl, &w, &h, &x, &y); | 5336 | GetControlDimensions(pControl, prcParent, &w, &h, &x, &y); |
5310 | ::MoveWindow(pControl->hWnd, x, y, w, h, TRUE); | 5337 | ::SetWindowPos(pControl->hWnd, NULL, x, y, w, h, SWP_NOACTIVATE | SWP_NOZORDER); |
5311 | 5338 | ||
5312 | #ifdef DEBUG | 5339 | #ifdef DEBUG |
5313 | if (THEME_CONTROL_TYPE_BUTTON == pControl->type) | 5340 | if (THEME_CONTROL_TYPE_BUTTON == pControl->type) |
@@ -5333,7 +5360,6 @@ static void ResizeControl( | |||
5333 | 5360 | ||
5334 | if (pControl->cControls) | 5361 | if (pControl->cControls) |
5335 | { | 5362 | { |
5336 | RECT rcControl = { }; | ||
5337 | ::GetClientRect(pControl->hWnd, &rcControl); | 5363 | ::GetClientRect(pControl->hWnd, &rcControl); |
5338 | ResizeControls(pControl->cControls, pControl->rgControls, &rcControl); | 5364 | ResizeControls(pControl->cControls, pControl->rgControls, &rcControl); |
5339 | } | 5365 | } |
@@ -5353,9 +5379,40 @@ static void ScaleTheme( | |||
5353 | pTheme->nMinimumHeight = DpiuScaleValue(pTheme->nDefaultDpiMinimumHeight, pTheme->nDpi); | 5379 | pTheme->nMinimumHeight = DpiuScaleValue(pTheme->nDefaultDpiMinimumHeight, pTheme->nDpi); |
5354 | pTheme->nMinimumWidth = DpiuScaleValue(pTheme->nDefaultDpiMinimumWidth, pTheme->nDpi); | 5380 | pTheme->nMinimumWidth = DpiuScaleValue(pTheme->nDefaultDpiMinimumWidth, pTheme->nDpi); |
5355 | 5381 | ||
5382 | ScaleControls(pTheme->cControls, pTheme->rgControls, pTheme->nDpi); | ||
5383 | |||
5356 | ::SetWindowPos(pTheme->hwndParent, NULL, x, y, pTheme->nWidth, pTheme->nHeight, SWP_NOACTIVATE | SWP_NOZORDER); | 5384 | ::SetWindowPos(pTheme->hwndParent, NULL, x, y, pTheme->nWidth, pTheme->nHeight, SWP_NOACTIVATE | SWP_NOZORDER); |
5357 | } | 5385 | } |
5358 | 5386 | ||
5387 | static void ScaleControls( | ||
5388 | __in DWORD cControls, | ||
5389 | __in THEME_CONTROL* rgControls, | ||
5390 | __in UINT nDpi | ||
5391 | ) | ||
5392 | { | ||
5393 | for (DWORD i = 0; i < cControls; ++i) | ||
5394 | { | ||
5395 | THEME_CONTROL* pControl = rgControls + i; | ||
5396 | ScaleControl(pControl, nDpi); | ||
5397 | } | ||
5398 | } | ||
5399 | |||
5400 | static void ScaleControl( | ||
5401 | __in THEME_CONTROL* pControl, | ||
5402 | __in UINT nDpi | ||
5403 | ) | ||
5404 | { | ||
5405 | pControl->nWidth = DpiuScaleValue(pControl->nDefaultDpiWidth, nDpi); | ||
5406 | pControl->nHeight = DpiuScaleValue(pControl->nDefaultDpiHeight, nDpi); | ||
5407 | pControl->nX = DpiuScaleValue(pControl->nDefaultDpiX, nDpi); | ||
5408 | pControl->nY = DpiuScaleValue(pControl->nDefaultDpiY, nDpi); | ||
5409 | |||
5410 | if (pControl->cControls) | ||
5411 | { | ||
5412 | ScaleControls(pControl->cControls, pControl->rgControls, nDpi); | ||
5413 | } | ||
5414 | } | ||
5415 | |||
5359 | static void UnloadControls( | 5416 | static void UnloadControls( |
5360 | __in DWORD cControls, | 5417 | __in DWORD cControls, |
5361 | __in THEME_CONTROL* rgControls | 5418 | __in THEME_CONTROL* rgControls |