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 /src | |
| 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.
Diffstat (limited to 'src')
| -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> |
