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 |
