aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-07-06 16:07:05 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-07-06 21:30:49 +1000
commit2e0773ed3169889f6246271ef6fffe6f8ce16f89 (patch)
tree564c823112bc29dec6bbf394b7358547d4d1de59
parenta44cba1e241d0aa7d5c64595e9e7c95d0f06cced (diff)
downloadwix-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.h5
-rw-r--r--src/dutil/thmutil.cpp107
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 );
315static void GetControlDimensions( 315static 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 );
367static void ScaleControls(
368 __in DWORD cControls,
369 __in THEME_CONTROL* rgControls,
370 __in UINT nDpi
371 );
372static void ScaleControl(
373 __in THEME_CONTROL* pControl,
374 __in UINT nDpi
375 );
367static void GetControls( 376static 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
4208LExit: 4228LExit:
@@ -4319,18 +4339,18 @@ static const THEME_CONTROL* FindControlFromHWnd(
4319} 4339}
4320 4340
4321static void GetControlDimensions( 4341static 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
4336static HRESULT SizeListViewColumns( 4356static 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
5387static 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
5400static 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
5359static void UnloadControls( 5416static void UnloadControls(
5360 __in DWORD cControls, 5417 __in DWORD cControls,
5361 __in THEME_CONTROL* rgControls 5418 __in THEME_CONTROL* rgControls