diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2020-07-06 16:22:38 +1000 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2020-07-06 21:30:49 +1000 |
commit | abeba64d77336b3fbf9aafe9ecc66b779c1e5d02 (patch) | |
tree | 7af0a5f74071685cf22f75ec9ca6bd457227089e | |
parent | 00bd06f02cf168eb0752e1d0819969a528742ba7 (diff) | |
download | wix-abeba64d77336b3fbf9aafe9ecc66b779c1e5d02.tar.gz wix-abeba64d77336b3fbf9aafe9ecc66b779c1e5d02.tar.bz2 wix-abeba64d77336b3fbf9aafe9ecc66b779c1e5d02.zip |
Add ability for ThemeCreateParentWindow to center on the monitor.
-rw-r--r-- | src/dutil/dpiutil.cpp | 53 | ||||
-rw-r--r-- | src/dutil/inc/dpiutil.h | 15 | ||||
-rw-r--r-- | src/dutil/inc/thmutil.h | 7 | ||||
-rw-r--r-- | src/dutil/thmutil.cpp | 34 |
4 files changed, 108 insertions, 1 deletions
diff --git a/src/dutil/dpiutil.cpp b/src/dutil/dpiutil.cpp index edab8f01..a27ee8c5 100644 --- a/src/dutil/dpiutil.cpp +++ b/src/dutil/dpiutil.cpp | |||
@@ -62,6 +62,59 @@ DAPI_(void) DpiuUninitialize() | |||
62 | vfDpiuInitialized = FALSE; | 62 | vfDpiuInitialized = FALSE; |
63 | } | 63 | } |
64 | 64 | ||
65 | DAPI_(HRESULT) DpiuGetMonitorContextFromPoint( | ||
66 | __in const POINT* pt, | ||
67 | __out DPIU_MONITOR_CONTEXT** ppMonitorContext | ||
68 | ) | ||
69 | { | ||
70 | HRESULT hr = S_OK; | ||
71 | DPIU_MONITOR_CONTEXT* pMonitorContext = NULL; | ||
72 | HMONITOR hMonitor = NULL; | ||
73 | UINT dpiX = 0; | ||
74 | UINT dpiY = 0; | ||
75 | HDC hdc = NULL; | ||
76 | |||
77 | pMonitorContext = reinterpret_cast<DPIU_MONITOR_CONTEXT*>(MemAlloc(sizeof(DPIU_MONITOR_CONTEXT), TRUE)); | ||
78 | DpiuExitOnNull(pMonitorContext, hr, E_OUTOFMEMORY, "Failed to allocate memory for DpiuMonitorContext."); | ||
79 | |||
80 | hMonitor = ::MonitorFromPoint(*pt, MONITOR_DEFAULTTONEAREST); | ||
81 | DpiuExitOnNull(hMonitor, hr, E_FAIL, "Failed to get monitor from point."); | ||
82 | |||
83 | pMonitorContext->mi.cbSize = sizeof(pMonitorContext->mi); | ||
84 | if (!::GetMonitorInfoW(hMonitor, &pMonitorContext->mi)) | ||
85 | { | ||
86 | DpiuExitOnFailure(hr = E_OUTOFMEMORY, "Failed to get monitor info for point."); | ||
87 | } | ||
88 | |||
89 | if (vpfnGetDpiForMonitor) | ||
90 | { | ||
91 | hr = vpfnGetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); | ||
92 | DpiuExitOnFailure(hr, "Failed to get DPI for monitor."); | ||
93 | |||
94 | pMonitorContext->nDpi = dpiX; | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | hdc = ::CreateDCW(L"DISPLAY", pMonitorContext->mi.szDevice, NULL, NULL); | ||
99 | DpiuExitOnNull(hdc, hr, E_OUTOFMEMORY, "Failed to get device context for monitor."); | ||
100 | |||
101 | pMonitorContext->nDpi = ::GetDeviceCaps(hdc, LOGPIXELSX); | ||
102 | } | ||
103 | |||
104 | *ppMonitorContext = pMonitorContext; | ||
105 | pMonitorContext = NULL; | ||
106 | |||
107 | LExit: | ||
108 | if (hdc) | ||
109 | { | ||
110 | ::ReleaseDC(NULL, hdc); | ||
111 | } | ||
112 | |||
113 | MemFree(pMonitorContext); | ||
114 | |||
115 | return hr; | ||
116 | } | ||
117 | |||
65 | DAPI_(void) DpiuGetWindowContext( | 118 | DAPI_(void) DpiuGetWindowContext( |
66 | __in HWND hWnd, | 119 | __in HWND hWnd, |
67 | __in DPIU_WINDOW_CONTEXT* pWindowContext | 120 | __in DPIU_WINDOW_CONTEXT* pWindowContext |
diff --git a/src/dutil/inc/dpiutil.h b/src/dutil/inc/dpiutil.h index c6f73b02..8c61ab19 100644 --- a/src/dutil/inc/dpiutil.h +++ b/src/dutil/inc/dpiutil.h | |||
@@ -14,6 +14,12 @@ extern "C" { | |||
14 | #define USER_DEFAULT_SCREEN_DPI 96 | 14 | #define USER_DEFAULT_SCREEN_DPI 96 |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | typedef struct _DPIU_MONITOR_CONTEXT | ||
18 | { | ||
19 | UINT nDpi; | ||
20 | MONITORINFOEXW mi; | ||
21 | } DPIU_MONITOR_CONTEXT; | ||
22 | |||
17 | typedef struct _DPIU_WINDOW_CONTEXT | 23 | typedef struct _DPIU_WINDOW_CONTEXT |
18 | { | 24 | { |
19 | UINT nDpi; | 25 | UINT nDpi; |
@@ -33,6 +39,15 @@ void DAPI DpiuInitialize(); | |||
33 | void DAPI DpiuUninitialize(); | 39 | void DAPI DpiuUninitialize(); |
34 | 40 | ||
35 | /******************************************************************** | 41 | /******************************************************************** |
42 | DpiuGetMonitorContextFromPoint - get the DPI context of the monitor from the given point. | ||
43 | |||
44 | *******************************************************************/ | ||
45 | HRESULT DAPI DpiuGetMonitorContextFromPoint( | ||
46 | __in const POINT* pt, | ||
47 | __out DPIU_MONITOR_CONTEXT** ppMonitorContext | ||
48 | ); | ||
49 | |||
50 | /******************************************************************** | ||
36 | DpiuGetWindowContext - get the DPI context of the given window. | 51 | DpiuGetWindowContext - get the DPI context of the given window. |
37 | 52 | ||
38 | *******************************************************************/ | 53 | *******************************************************************/ |
diff --git a/src/dutil/inc/thmutil.h b/src/dutil/inc/thmutil.h index c75f9587..1ba5db35 100644 --- a/src/dutil/inc/thmutil.h +++ b/src/dutil/inc/thmutil.h | |||
@@ -81,6 +81,12 @@ typedef enum THEME_SHOW_PAGE_REASON | |||
81 | THEME_SHOW_PAGE_REASON_REFRESH, | 81 | THEME_SHOW_PAGE_REASON_REFRESH, |
82 | } THEME_SHOW_PAGE_REASON; | 82 | } THEME_SHOW_PAGE_REASON; |
83 | 83 | ||
84 | typedef enum THEME_WINDOW_INITIAL_POSITION | ||
85 | { | ||
86 | THEME_WINDOW_INITIAL_POSITION_DEFAULT, | ||
87 | THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES, | ||
88 | } THEME_WINDOW_INITIAL_POSITION; | ||
89 | |||
84 | 90 | ||
85 | struct THEME_COLUMN | 91 | struct THEME_COLUMN |
86 | { | 92 | { |
@@ -394,6 +400,7 @@ HRESULT DAPI ThemeCreateParentWindow( | |||
394 | __in_opt HWND hwndParent, | 400 | __in_opt HWND hwndParent, |
395 | __in_opt HINSTANCE hInstance, | 401 | __in_opt HINSTANCE hInstance, |
396 | __in_opt LPVOID lpParam, | 402 | __in_opt LPVOID lpParam, |
403 | __in THEME_WINDOW_INITIAL_POSITION initialPosition, | ||
397 | __out_opt HWND* phWnd | 404 | __out_opt HWND* phWnd |
398 | ); | 405 | ); |
399 | 406 | ||
diff --git a/src/dutil/thmutil.cpp b/src/dutil/thmutil.cpp index 4da489e4..a1b101e8 100644 --- a/src/dutil/thmutil.cpp +++ b/src/dutil/thmutil.cpp | |||
@@ -603,10 +603,14 @@ DAPI_(HRESULT) ThemeCreateParentWindow( | |||
603 | __in_opt HWND hwndParent, | 603 | __in_opt HWND hwndParent, |
604 | __in_opt HINSTANCE hInstance, | 604 | __in_opt HINSTANCE hInstance, |
605 | __in_opt LPVOID lpParam, | 605 | __in_opt LPVOID lpParam, |
606 | __in THEME_WINDOW_INITIAL_POSITION initialPosition, | ||
606 | __out_opt HWND* phWnd | 607 | __out_opt HWND* phWnd |
607 | ) | 608 | ) |
608 | { | 609 | { |
609 | HRESULT hr = S_OK; | 610 | HRESULT hr = S_OK; |
611 | DPIU_MONITOR_CONTEXT* pMonitorContext = NULL; | ||
612 | POINT pt = { }; | ||
613 | RECT* pMonitorRect = NULL; | ||
610 | HWND hWnd = NULL; | 614 | HWND hWnd = NULL; |
611 | 615 | ||
612 | if (pTheme->hwndParent) | 616 | if (pTheme->hwndParent) |
@@ -614,6 +618,29 @@ DAPI_(HRESULT) ThemeCreateParentWindow( | |||
614 | ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeCreateParentWindow called after the theme was loaded."); | 618 | ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeCreateParentWindow called after the theme was loaded."); |
615 | } | 619 | } |
616 | 620 | ||
621 | if (THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES == initialPosition) | ||
622 | { | ||
623 | pt.x = x; | ||
624 | pt.y = y; | ||
625 | hr = DpiuGetMonitorContextFromPoint(&pt, &pMonitorContext); | ||
626 | if (SUCCEEDED(hr)) | ||
627 | { | ||
628 | pMonitorRect = &pMonitorContext->mi.rcWork; | ||
629 | if (pMonitorContext->nDpi != pTheme->nDpi) | ||
630 | { | ||
631 | ScaleTheme(pTheme, pMonitorContext->nDpi, pMonitorRect->left, pMonitorRect->top); | ||
632 | } | ||
633 | |||
634 | x = pMonitorRect->left + (pMonitorRect->right - pMonitorRect->left - pTheme->nWidth) / 2; | ||
635 | y = pMonitorRect->top + (pMonitorRect->bottom - pMonitorRect->top - pTheme->nHeight) / 2; | ||
636 | } | ||
637 | else | ||
638 | { | ||
639 | x = CW_USEDEFAULT; | ||
640 | y = CW_USEDEFAULT; | ||
641 | } | ||
642 | } | ||
643 | |||
617 | hWnd = ::CreateWindowExW(dwExStyle, szClassName, szWindowName, dwStyle, x, y, pTheme->nWidth, pTheme->nHeight, hwndParent, NULL, hInstance, lpParam); | 644 | hWnd = ::CreateWindowExW(dwExStyle, szClassName, szWindowName, dwStyle, x, y, pTheme->nWidth, pTheme->nHeight, hwndParent, NULL, hInstance, lpParam); |
618 | ThmExitOnNullWithLastError(hWnd, hr, "Failed to create theme parent window."); | 645 | ThmExitOnNullWithLastError(hWnd, hr, "Failed to create theme parent window."); |
619 | ThmExitOnNull(pTheme->hwndParent, hr, E_INVALIDSTATE, "Theme parent window is not set, make sure ThemeDefWindowProc is called for WM_NCCREATE."); | 646 | ThmExitOnNull(pTheme->hwndParent, hr, E_INVALIDSTATE, "Theme parent window is not set, make sure ThemeDefWindowProc is called for WM_NCCREATE."); |
@@ -625,6 +652,8 @@ DAPI_(HRESULT) ThemeCreateParentWindow( | |||
625 | } | 652 | } |
626 | 653 | ||
627 | LExit: | 654 | LExit: |
655 | MemFree(pMonitorContext); | ||
656 | |||
628 | return hr; | 657 | return hr; |
629 | } | 658 | } |
630 | 659 | ||
@@ -5471,7 +5500,10 @@ static void ScaleTheme( | |||
5471 | 5500 | ||
5472 | ScaleControls(pTheme, pTheme->cControls, pTheme->rgControls, pTheme->nDpi); | 5501 | ScaleControls(pTheme, pTheme->cControls, pTheme->rgControls, pTheme->nDpi); |
5473 | 5502 | ||
5474 | ::SetWindowPos(pTheme->hwndParent, NULL, x, y, pTheme->nWidth, pTheme->nHeight, SWP_NOACTIVATE | SWP_NOZORDER); | 5503 | if (pTheme->hwndParent) |
5504 | { | ||
5505 | ::SetWindowPos(pTheme->hwndParent, NULL, x, y, pTheme->nWidth, pTheme->nHeight, SWP_NOACTIVATE | SWP_NOZORDER); | ||
5506 | } | ||
5475 | } | 5507 | } |
5476 | 5508 | ||
5477 | static void ScaleControls( | 5509 | static void ScaleControls( |