aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-07-06 16:22:38 +1000
committerSean Hall <r.sean.hall@gmail.com>2020-07-06 21:30:49 +1000
commitabeba64d77336b3fbf9aafe9ecc66b779c1e5d02 (patch)
tree7af0a5f74071685cf22f75ec9ca6bd457227089e
parent00bd06f02cf168eb0752e1d0819969a528742ba7 (diff)
downloadwix-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.cpp53
-rw-r--r--src/dutil/inc/dpiutil.h15
-rw-r--r--src/dutil/inc/thmutil.h7
-rw-r--r--src/dutil/thmutil.cpp34
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
65DAPI_(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
107LExit:
108 if (hdc)
109 {
110 ::ReleaseDC(NULL, hdc);
111 }
112
113 MemFree(pMonitorContext);
114
115 return hr;
116}
117
65DAPI_(void) DpiuGetWindowContext( 118DAPI_(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
17typedef struct _DPIU_MONITOR_CONTEXT
18{
19 UINT nDpi;
20 MONITORINFOEXW mi;
21} DPIU_MONITOR_CONTEXT;
22
17typedef struct _DPIU_WINDOW_CONTEXT 23typedef struct _DPIU_WINDOW_CONTEXT
18{ 24{
19 UINT nDpi; 25 UINT nDpi;
@@ -33,6 +39,15 @@ void DAPI DpiuInitialize();
33void DAPI DpiuUninitialize(); 39void DAPI DpiuUninitialize();
34 40
35/******************************************************************** 41/********************************************************************
42 DpiuGetMonitorContextFromPoint - get the DPI context of the monitor from the given point.
43
44*******************************************************************/
45HRESULT 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
84typedef 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
85struct THEME_COLUMN 91struct 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
627LExit: 654LExit:
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
5477static void ScaleControls( 5509static void ScaleControls(