diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2020-07-06 19:22:37 +1000 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2020-07-06 21:30:49 +1000 |
commit | 219964095a1f4678d8c8e7ae2685c52392161ca2 (patch) | |
tree | 2eff04c6a6bfebbc05b667a3bd1fa5ebf04edf6d | |
parent | abeba64d77336b3fbf9aafe9ecc66b779c1e5d02 (diff) | |
download | wix-219964095a1f4678d8c8e7ae2685c52392161ca2.tar.gz wix-219964095a1f4678d8c8e7ae2685c52392161ca2.tar.bz2 wix-219964095a1f4678d8c8e7ae2685c52392161ca2.zip |
WIXFEAT:4906 Make Window's Height and Width refer to its client area.
-rw-r--r-- | src/dutil/dpiutil.cpp | 26 | ||||
-rw-r--r-- | src/dutil/inc/dpiutil.h | 21 | ||||
-rw-r--r-- | src/dutil/inc/thmutil.h | 2 | ||||
-rw-r--r-- | src/dutil/thmutil.cpp | 59 | ||||
-rw-r--r-- | src/dutil/xsd/thmutil.xsd | 4 |
5 files changed, 99 insertions, 13 deletions
diff --git a/src/dutil/dpiutil.cpp b/src/dutil/dpiutil.cpp index a27ee8c5..02a9580c 100644 --- a/src/dutil/dpiutil.cpp +++ b/src/dutil/dpiutil.cpp | |||
@@ -15,6 +15,7 @@ | |||
15 | #define DpiuExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_DPIUTIL, p, x, s, __VA_ARGS__) | 15 | #define DpiuExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_DPIUTIL, p, x, s, __VA_ARGS__) |
16 | #define DpiuExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_DPIUTIL, e, x, s, __VA_ARGS__) | 16 | #define DpiuExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_DPIUTIL, e, x, s, __VA_ARGS__) |
17 | 17 | ||
18 | static PFN_ADJUSTWINDOWRECTEXFORDPI vpfnAdjustWindowRectExForDpi = NULL; | ||
18 | static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL; | 19 | static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL; |
19 | static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL; | 20 | static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL; |
20 | 21 | ||
@@ -37,6 +38,7 @@ DAPI_(void) DpiuInitialize() | |||
37 | if (SUCCEEDED(hr)) | 38 | if (SUCCEEDED(hr)) |
38 | { | 39 | { |
39 | // Ignore failures. | 40 | // Ignore failures. |
41 | vpfnAdjustWindowRectExForDpi = reinterpret_cast<PFN_ADJUSTWINDOWRECTEXFORDPI>(::GetProcAddress(vhUser32Dll, "AdjustWindowRectExForDpi")); | ||
40 | vpfnGetDpiForWindow = reinterpret_cast<PFN_GETDPIFORWINDOW>(::GetProcAddress(vhUser32Dll, "GetDpiForWindow")); | 42 | vpfnGetDpiForWindow = reinterpret_cast<PFN_GETDPIFORWINDOW>(::GetProcAddress(vhUser32Dll, "GetDpiForWindow")); |
41 | } | 43 | } |
42 | 44 | ||
@@ -57,11 +59,35 @@ DAPI_(void) DpiuUninitialize() | |||
57 | 59 | ||
58 | vhShcoreDll = NULL; | 60 | vhShcoreDll = NULL; |
59 | vhUser32Dll = NULL; | 61 | vhUser32Dll = NULL; |
62 | vpfnAdjustWindowRectExForDpi = NULL; | ||
60 | vpfnGetDpiForMonitor = NULL; | 63 | vpfnGetDpiForMonitor = NULL; |
61 | vpfnGetDpiForWindow = NULL; | 64 | vpfnGetDpiForWindow = NULL; |
62 | vfDpiuInitialized = FALSE; | 65 | vfDpiuInitialized = FALSE; |
63 | } | 66 | } |
64 | 67 | ||
68 | DAPI_(void) DpiuAdjustWindowRect( | ||
69 | __in RECT* pWindowRect, | ||
70 | __in DWORD dwStyle, | ||
71 | __in BOOL fMenu, | ||
72 | __in DWORD dwExStyle, | ||
73 | __in UINT nDpi | ||
74 | ) | ||
75 | { | ||
76 | if (WS_SYSMENU & dwStyle) | ||
77 | { | ||
78 | dwStyle |= WS_CAPTION; // WS_CAPTION is required with WS_SYSMENU, AdjustWindowRect* won't work properly when it's not specified. | ||
79 | } | ||
80 | |||
81 | if (vpfnAdjustWindowRectExForDpi) | ||
82 | { | ||
83 | vpfnAdjustWindowRectExForDpi(pWindowRect, dwStyle, fMenu, dwExStyle, nDpi); | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | ::AdjustWindowRectEx(pWindowRect, dwStyle, fMenu, dwExStyle); | ||
88 | } | ||
89 | } | ||
90 | |||
65 | DAPI_(HRESULT) DpiuGetMonitorContextFromPoint( | 91 | DAPI_(HRESULT) DpiuGetMonitorContextFromPoint( |
66 | __in const POINT* pt, | 92 | __in const POINT* pt, |
67 | __out DPIU_MONITOR_CONTEXT** ppMonitorContext | 93 | __out DPIU_MONITOR_CONTEXT** ppMonitorContext |
diff --git a/src/dutil/inc/dpiutil.h b/src/dutil/inc/dpiutil.h index 8c61ab19..4ea689c5 100644 --- a/src/dutil/inc/dpiutil.h +++ b/src/dutil/inc/dpiutil.h | |||
@@ -25,6 +25,13 @@ typedef struct _DPIU_WINDOW_CONTEXT | |||
25 | UINT nDpi; | 25 | UINT nDpi; |
26 | } DPIU_WINDOW_CONTEXT; | 26 | } DPIU_WINDOW_CONTEXT; |
27 | 27 | ||
28 | typedef BOOL (APIENTRY* PFN_ADJUSTWINDOWRECTEXFORDPI)( | ||
29 | __in LPRECT lpRect, | ||
30 | __in DWORD dwStyle, | ||
31 | __in BOOL bMenu, | ||
32 | __in DWORD dwExStyle, | ||
33 | __in UINT dpi | ||
34 | ); | ||
28 | typedef HRESULT (APIENTRY *PFN_GETDPIFORMONITOR)( | 35 | typedef HRESULT (APIENTRY *PFN_GETDPIFORMONITOR)( |
29 | __in HMONITOR hmonitor, | 36 | __in HMONITOR hmonitor, |
30 | __in MONITOR_DPI_TYPE dpiType, | 37 | __in MONITOR_DPI_TYPE dpiType, |
@@ -39,6 +46,20 @@ void DAPI DpiuInitialize(); | |||
39 | void DAPI DpiuUninitialize(); | 46 | void DAPI DpiuUninitialize(); |
40 | 47 | ||
41 | /******************************************************************** | 48 | /******************************************************************** |
49 | DpiuAdjustWindowRect - calculate the required size of the window rectangle, | ||
50 | based on the desired size of the client rectangle | ||
51 | and the provided DPI. | ||
52 | |||
53 | *******************************************************************/ | ||
54 | void DAPI DpiuAdjustWindowRect( | ||
55 | __in RECT* pWindowRect, | ||
56 | __in DWORD dwStyle, | ||
57 | __in BOOL fMenu, | ||
58 | __in DWORD dwExStyle, | ||
59 | __in UINT nDpi | ||
60 | ); | ||
61 | |||
62 | /******************************************************************** | ||
42 | DpiuGetMonitorContextFromPoint - get the DPI context of the monitor from the given point. | 63 | DpiuGetMonitorContextFromPoint - get the DPI context of the monitor from the given point. |
43 | 64 | ||
44 | *******************************************************************/ | 65 | *******************************************************************/ |
diff --git a/src/dutil/inc/thmutil.h b/src/dutil/inc/thmutil.h index 1ba5db35..00fa1381 100644 --- a/src/dutil/inc/thmutil.h +++ b/src/dutil/inc/thmutil.h | |||
@@ -289,6 +289,8 @@ struct THEME | |||
289 | int nMinimumHeight; | 289 | int nMinimumHeight; |
290 | int nWidth; | 290 | int nWidth; |
291 | int nMinimumWidth; | 291 | int nMinimumWidth; |
292 | int nWindowHeight; | ||
293 | int nWindowWidth; | ||
292 | int nSourceX; | 294 | int nSourceX; |
293 | int nSourceY; | 295 | int nSourceY; |
294 | UINT uStringId; | 296 | UINT uStringId; |
diff --git a/src/dutil/thmutil.cpp b/src/dutil/thmutil.cpp index a1b101e8..75b0e4a0 100644 --- a/src/dutil/thmutil.cpp +++ b/src/dutil/thmutil.cpp | |||
@@ -367,12 +367,21 @@ static void ResizeControl( | |||
367 | __in THEME_CONTROL* pControl, | 367 | __in THEME_CONTROL* pControl, |
368 | __in const RECT* prcParent | 368 | __in const RECT* prcParent |
369 | ); | 369 | ); |
370 | static void ScaleTheme( | 370 | static void ScaleThemeFromWindow( |
371 | __in THEME* pTheme, | 371 | __in THEME* pTheme, |
372 | __in UINT nDpi, | 372 | __in UINT nDpi, |
373 | __in int x, | 373 | __in int x, |
374 | __in int y | 374 | __in int y |
375 | ); | 375 | ); |
376 | static void ScaleTheme( | ||
377 | __in THEME* pTheme, | ||
378 | __in UINT nDpi, | ||
379 | __in int x, | ||
380 | __in int y, | ||
381 | __in DWORD dwStyle, | ||
382 | __in BOOL fMenu, | ||
383 | __in DWORD dwExStyle | ||
384 | ); | ||
376 | static void ScaleControls( | 385 | static void ScaleControls( |
377 | __in THEME* pTheme, | 386 | __in THEME* pTheme, |
378 | __in DWORD cControls, | 387 | __in DWORD cControls, |
@@ -611,6 +620,7 @@ DAPI_(HRESULT) ThemeCreateParentWindow( | |||
611 | DPIU_MONITOR_CONTEXT* pMonitorContext = NULL; | 620 | DPIU_MONITOR_CONTEXT* pMonitorContext = NULL; |
612 | POINT pt = { }; | 621 | POINT pt = { }; |
613 | RECT* pMonitorRect = NULL; | 622 | RECT* pMonitorRect = NULL; |
623 | HMENU hMenu = NULL; | ||
614 | HWND hWnd = NULL; | 624 | HWND hWnd = NULL; |
615 | 625 | ||
616 | if (pTheme->hwndParent) | 626 | if (pTheme->hwndParent) |
@@ -628,11 +638,11 @@ DAPI_(HRESULT) ThemeCreateParentWindow( | |||
628 | pMonitorRect = &pMonitorContext->mi.rcWork; | 638 | pMonitorRect = &pMonitorContext->mi.rcWork; |
629 | if (pMonitorContext->nDpi != pTheme->nDpi) | 639 | if (pMonitorContext->nDpi != pTheme->nDpi) |
630 | { | 640 | { |
631 | ScaleTheme(pTheme, pMonitorContext->nDpi, pMonitorRect->left, pMonitorRect->top); | 641 | ScaleTheme(pTheme, pMonitorContext->nDpi, pMonitorRect->left, pMonitorRect->top, dwStyle, NULL != hMenu, dwExStyle); |
632 | } | 642 | } |
633 | 643 | ||
634 | x = pMonitorRect->left + (pMonitorRect->right - pMonitorRect->left - pTheme->nWidth) / 2; | 644 | x = pMonitorRect->left + (pMonitorRect->right - pMonitorRect->left - pTheme->nWindowWidth) / 2; |
635 | y = pMonitorRect->top + (pMonitorRect->bottom - pMonitorRect->top - pTheme->nHeight) / 2; | 645 | y = pMonitorRect->top + (pMonitorRect->bottom - pMonitorRect->top - pTheme->nWindowHeight) / 2; |
636 | } | 646 | } |
637 | else | 647 | else |
638 | { | 648 | { |
@@ -641,7 +651,7 @@ DAPI_(HRESULT) ThemeCreateParentWindow( | |||
641 | } | 651 | } |
642 | } | 652 | } |
643 | 653 | ||
644 | hWnd = ::CreateWindowExW(dwExStyle, szClassName, szWindowName, dwStyle, x, y, pTheme->nWidth, pTheme->nHeight, hwndParent, NULL, hInstance, lpParam); | 654 | hWnd = ::CreateWindowExW(dwExStyle, szClassName, szWindowName, dwStyle, x, y, pTheme->nWindowWidth, pTheme->nWindowHeight, hwndParent, hMenu, hInstance, lpParam); |
645 | ThmExitOnNullWithLastError(hWnd, hr, "Failed to create theme parent window."); | 655 | ThmExitOnNullWithLastError(hWnd, hr, "Failed to create theme parent window."); |
646 | ThmExitOnNull(pTheme->hwndParent, hr, E_INVALIDSTATE, "Theme parent window is not set, make sure ThemeDefWindowProc is called for WM_NCCREATE."); | 656 | ThmExitOnNull(pTheme->hwndParent, hr, E_INVALIDSTATE, "Theme parent window is not set, make sure ThemeDefWindowProc is called for WM_NCCREATE."); |
647 | AssertSz(hWnd == pTheme->hwndParent, "Theme parent window does not equal newly created window."); | 657 | AssertSz(hWnd == pTheme->hwndParent, "Theme parent window does not equal newly created window."); |
@@ -1909,7 +1919,7 @@ static HRESULT ParseWindow( | |||
1909 | } | 1919 | } |
1910 | ThmExitOnFailure(hr, "Failed to get window Width attribute."); | 1920 | ThmExitOnFailure(hr, "Failed to get window Width attribute."); |
1911 | 1921 | ||
1912 | pTheme->nWidth = pTheme->nDefaultDpiWidth = dwValue; | 1922 | pTheme->nWidth = pTheme->nDefaultDpiWidth = pTheme->nWindowWidth = dwValue; |
1913 | 1923 | ||
1914 | hr = XmlGetAttributeNumber(pixn, L"Height", &dwValue); | 1924 | hr = XmlGetAttributeNumber(pixn, L"Height", &dwValue); |
1915 | if (S_FALSE == hr) | 1925 | if (S_FALSE == hr) |
@@ -1919,7 +1929,7 @@ static HRESULT ParseWindow( | |||
1919 | } | 1929 | } |
1920 | ThmExitOnFailure(hr, "Failed to get window Height attribute."); | 1930 | ThmExitOnFailure(hr, "Failed to get window Height attribute."); |
1921 | 1931 | ||
1922 | pTheme->nHeight = pTheme->nDefaultDpiHeight = dwValue; | 1932 | pTheme->nHeight = pTheme->nDefaultDpiHeight = pTheme->nWindowHeight = dwValue; |
1923 | 1933 | ||
1924 | hr = XmlGetAttributeNumber(pixn, L"MinimumWidth", &dwValue); | 1934 | hr = XmlGetAttributeNumber(pixn, L"MinimumWidth", &dwValue); |
1925 | if (S_FALSE == hr) | 1935 | if (S_FALSE == hr) |
@@ -4338,7 +4348,7 @@ static BOOL OnDpiChanged( | |||
4338 | 4348 | ||
4339 | 4349 | ||
4340 | pTheme->fForceResize = !pTheme->fAutoResize; | 4350 | pTheme->fForceResize = !pTheme->fAutoResize; |
4341 | ScaleTheme(pTheme, nDpi, pRect->left, pRect->top); | 4351 | ScaleThemeFromWindow(pTheme, nDpi, pRect->left, pRect->top); |
4342 | 4352 | ||
4343 | LExit: | 4353 | LExit: |
4344 | return !fIgnored; | 4354 | return !fIgnored; |
@@ -4359,7 +4369,7 @@ static void OnNcCreate( | |||
4359 | 4369 | ||
4360 | if (windowContext.nDpi != pTheme->nDpi) | 4370 | if (windowContext.nDpi != pTheme->nDpi) |
4361 | { | 4371 | { |
4362 | ScaleTheme(pTheme, windowContext.nDpi, pCreateStruct->x, pCreateStruct->y); | 4372 | ScaleTheme(pTheme, windowContext.nDpi, pCreateStruct->x, pCreateStruct->y, pCreateStruct->style, NULL != pCreateStruct->hMenu, pCreateStruct->dwExStyle); |
4363 | } | 4373 | } |
4364 | } | 4374 | } |
4365 | 4375 | ||
@@ -5484,13 +5494,32 @@ static void ResizeControl( | |||
5484 | } | 5494 | } |
5485 | } | 5495 | } |
5486 | 5496 | ||
5487 | static void ScaleTheme( | 5497 | static void ScaleThemeFromWindow( |
5488 | __in THEME* pTheme, | 5498 | __in THEME* pTheme, |
5489 | __in UINT nDpi, | 5499 | __in UINT nDpi, |
5490 | __in int x, | 5500 | __in int x, |
5491 | __in int y | 5501 | __in int y |
5492 | ) | 5502 | ) |
5493 | { | 5503 | { |
5504 | DWORD dwStyle = GetWindowStyle(pTheme->hwndParent); | ||
5505 | BOOL fMenu = NULL != ::GetMenu(pTheme->hwndParent); | ||
5506 | DWORD dwExStyle = GetWindowExStyle(pTheme->hwndParent); | ||
5507 | |||
5508 | ScaleTheme(pTheme, nDpi, x, y, dwStyle, fMenu, dwExStyle); | ||
5509 | } | ||
5510 | |||
5511 | static void ScaleTheme( | ||
5512 | __in THEME* pTheme, | ||
5513 | __in UINT nDpi, | ||
5514 | __in int x, | ||
5515 | __in int y, | ||
5516 | __in DWORD dwStyle, | ||
5517 | __in BOOL fMenu, | ||
5518 | __in DWORD dwExStyle | ||
5519 | ) | ||
5520 | { | ||
5521 | RECT rect = { }; | ||
5522 | |||
5494 | pTheme->nDpi = nDpi; | 5523 | pTheme->nDpi = nDpi; |
5495 | 5524 | ||
5496 | pTheme->nHeight = DpiuScaleValue(pTheme->nDefaultDpiHeight, pTheme->nDpi); | 5525 | pTheme->nHeight = DpiuScaleValue(pTheme->nDefaultDpiHeight, pTheme->nDpi); |
@@ -5498,11 +5527,19 @@ static void ScaleTheme( | |||
5498 | pTheme->nMinimumHeight = DpiuScaleValue(pTheme->nDefaultDpiMinimumHeight, pTheme->nDpi); | 5527 | pTheme->nMinimumHeight = DpiuScaleValue(pTheme->nDefaultDpiMinimumHeight, pTheme->nDpi); |
5499 | pTheme->nMinimumWidth = DpiuScaleValue(pTheme->nDefaultDpiMinimumWidth, pTheme->nDpi); | 5528 | pTheme->nMinimumWidth = DpiuScaleValue(pTheme->nDefaultDpiMinimumWidth, pTheme->nDpi); |
5500 | 5529 | ||
5530 | rect.left = x; | ||
5531 | rect.top = y; | ||
5532 | rect.right = x + pTheme->nWidth; | ||
5533 | rect.bottom = y + pTheme->nHeight; | ||
5534 | DpiuAdjustWindowRect(&rect, dwStyle, fMenu, dwExStyle, pTheme->nDpi); | ||
5535 | pTheme->nWindowWidth = rect.right - rect.left; | ||
5536 | pTheme->nWindowHeight = rect.bottom - rect.top; | ||
5537 | |||
5501 | ScaleControls(pTheme, pTheme->cControls, pTheme->rgControls, pTheme->nDpi); | 5538 | ScaleControls(pTheme, pTheme->cControls, pTheme->rgControls, pTheme->nDpi); |
5502 | 5539 | ||
5503 | if (pTheme->hwndParent) | 5540 | if (pTheme->hwndParent) |
5504 | { | 5541 | { |
5505 | ::SetWindowPos(pTheme->hwndParent, NULL, x, y, pTheme->nWidth, pTheme->nHeight, SWP_NOACTIVATE | SWP_NOZORDER); | 5542 | ::SetWindowPos(pTheme->hwndParent, NULL, x, y, pTheme->nWindowWidth, pTheme->nWindowHeight, SWP_NOACTIVATE | SWP_NOZORDER); |
5506 | } | 5543 | } |
5507 | } | 5544 | } |
5508 | 5545 | ||
diff --git a/src/dutil/xsd/thmutil.xsd b/src/dutil/xsd/thmutil.xsd index ccf951c0..46c20e4a 100644 --- a/src/dutil/xsd/thmutil.xsd +++ b/src/dutil/xsd/thmutil.xsd | |||
@@ -165,7 +165,7 @@ | |||
165 | </xs:attribute> | 165 | </xs:attribute> |
166 | <xs:attribute name="Height" type="xs:positiveInteger" use="required"> | 166 | <xs:attribute name="Height" type="xs:positiveInteger" use="required"> |
167 | <xs:annotation> | 167 | <xs:annotation> |
168 | <xs:documentation>Height of the window.</xs:documentation> | 168 | <xs:documentation>Height of the window's client area.</xs:documentation> |
169 | </xs:annotation> | 169 | </xs:annotation> |
170 | </xs:attribute> | 170 | </xs:attribute> |
171 | <xs:attribute name="HexStyle" type="xs:hexBinary"> | 171 | <xs:attribute name="HexStyle" type="xs:hexBinary"> |
@@ -219,7 +219,7 @@ | |||
219 | </xs:attribute> | 219 | </xs:attribute> |
220 | <xs:attribute name="Width" type="xs:positiveInteger" use="required"> | 220 | <xs:attribute name="Width" type="xs:positiveInteger" use="required"> |
221 | <xs:annotation> | 221 | <xs:annotation> |
222 | <xs:documentation>Width of the window.</xs:documentation> | 222 | <xs:documentation>Width of the window's client area.</xs:documentation> |
223 | </xs:annotation> | 223 | </xs:annotation> |
224 | </xs:attribute> | 224 | </xs:attribute> |
225 | </xs:complexType> | 225 | </xs:complexType> |