aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-07-06 19:22:37 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-07-06 21:30:49 +1000
commit219964095a1f4678d8c8e7ae2685c52392161ca2 (patch)
tree2eff04c6a6bfebbc05b667a3bd1fa5ebf04edf6d
parentabeba64d77336b3fbf9aafe9ecc66b779c1e5d02 (diff)
downloadwix-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.cpp26
-rw-r--r--src/dutil/inc/dpiutil.h21
-rw-r--r--src/dutil/inc/thmutil.h2
-rw-r--r--src/dutil/thmutil.cpp59
-rw-r--r--src/dutil/xsd/thmutil.xsd4
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
18static PFN_ADJUSTWINDOWRECTEXFORDPI vpfnAdjustWindowRectExForDpi = NULL;
18static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL; 19static PFN_GETDPIFORMONITOR vpfnGetDpiForMonitor = NULL;
19static PFN_GETDPIFORWINDOW vpfnGetDpiForWindow = NULL; 20static 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
68DAPI_(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
65DAPI_(HRESULT) DpiuGetMonitorContextFromPoint( 91DAPI_(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
28typedef 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 );
28typedef HRESULT (APIENTRY *PFN_GETDPIFORMONITOR)( 35typedef 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();
39void DAPI DpiuUninitialize(); 46void 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*******************************************************************/
54void 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 );
370static void ScaleTheme( 370static 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 );
376static 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 );
376static void ScaleControls( 385static 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
4343LExit: 4353LExit:
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
5487static void ScaleTheme( 5497static 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
5511static 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>