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( |
