@joebigelow / wix / commits / e586152b

Add ThemeCreateParentWindow so thmutil controls its window creation.

Sean Hall committed Jul 5, 2020 at 17:15 UTC e586152b76d62dbf38cd2882819e23eee2e0af7f
2 files changed +90 -14
src/dutil/inc/thmutil.h
+20 -2
@@ -354,12 +354,30 @@ HRESULT DAPI ThemeRegisterVariableCallbacks(
354 );
355
356 /********************************************************************
357 - ThemeLoadControls - creates the windows for all the theme controls.
357 + ThemeCreateParentWindow - creates a parent window for the theme.
358 +
359 +*******************************************************************/
360 +HRESULT DAPI ThemeCreateParentWindow(
361 + __in THEME* pTheme,
362 + __in DWORD dwExStyle,
363 + __in LPCWSTR szClassName,
364 + __in LPCWSTR szWindowName,
365 + __in DWORD dwStyle,
366 + __in int x,
367 + __in int y,
368 + __in_opt HWND hwndParent,
369 + __in_opt HINSTANCE hInstance,
370 + __in_opt LPVOID lpParam,
371 + __out_opt HWND* phWnd
372 + );
373 +
374 +/********************************************************************
375 + ThemeLoadControls - creates the windows for all the theme controls
376 + using the window created in ThemeCreateParentWindow.
377
378 *******************************************************************/
379 HRESULT DAPI ThemeLoadControls(
380 __in THEME* pTheme,
362 - __in HWND hwndParent,
381 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
382 __in DWORD cAssignControlIds
383 );
src/dutil/thmutil.cpp
+70 -12
@@ -17,6 +17,7 @@
17 #define ThmExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_THMUTIL, e, x, s, __VA_ARGS__)
18 #define ThmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_THMUTIL, g, x, s, __VA_ARGS__)
19
20 +// from CommCtrl.h
21 #ifndef BS_COMMANDLINK
22 #define BS_COMMANDLINK 0x0000000EL
23 #endif
@@ -184,7 +185,6 @@ static HRESULT FindImageList(
185 static HRESULT LoadControls(
186 __in THEME* pTheme,
187 __in_opt THEME_CONTROL* pParentControl,
187 - __in HWND hwndParent,
188 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
189 __in DWORD cAssignControlIds
190 );
@@ -287,6 +287,11 @@ static BOOL OnButtonClicked(
287 __in HWND hWnd,
288 __in const THEME_CONTROL* pControl
289 );
290 +static void OnNcCreate(
291 + __in THEME* pTheme,
292 + __in HWND hWnd,
293 + __in LPARAM lParam
294 + );
295 static HRESULT OnRichEditEnLink(
296 __in LPARAM lParam,
297 __in HWND hWndRichEdit,
@@ -553,14 +558,60 @@ LExit:
558 }
559
560
561 +DAPI_(HRESULT) ThemeCreateParentWindow(
562 + __in THEME* pTheme,
563 + __in DWORD dwExStyle,
564 + __in LPCWSTR szClassName,
565 + __in LPCWSTR szWindowName,
566 + __in DWORD dwStyle,
567 + __in int x,
568 + __in int y,
569 + __in_opt HWND hwndParent,
570 + __in_opt HINSTANCE hInstance,
571 + __in_opt LPVOID lpParam,
572 + __out_opt HWND* phWnd
573 + )
574 +{
575 + HRESULT hr = S_OK;
576 + HWND hWnd = NULL;
577 +
578 + if (pTheme->hwndParent)
579 + {
580 + ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeCreateParentWindow called after the theme was loaded.");
581 + }
582 +
583 + hWnd = ::CreateWindowExW(dwExStyle, szClassName, szWindowName, dwStyle, x, y, pTheme->nWidth, pTheme->nHeight, hwndParent, NULL, hInstance, lpParam);
584 + ThmExitOnNullWithLastError(hWnd, hr, "Failed to create theme parent window.");
585 + ThmExitOnNull(pTheme->hwndParent, hr, E_INVALIDSTATE, "Theme parent window is not set, make sure ThemeDefWindowProc is called for WM_NCCREATE.");
586 + AssertSz(hWnd == pTheme->hwndParent, "Theme parent window does not equal newly created window.");
587 +
588 + if (phWnd)
589 + {
590 + *phWnd = hWnd;
591 + }
592 +
593 +LExit:
594 + return hr;
595 +}
596 +
597 +
598 DAPI_(HRESULT) ThemeLoadControls(
599 __in THEME* pTheme,
558 - __in HWND hwndParent,
600 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
601 __in DWORD cAssignControlIds
602 )
603 {
563 - return LoadControls(pTheme, NULL, hwndParent, rgAssignControlIds, cAssignControlIds);
604 + HRESULT hr = S_OK;
605 +
606 + if (!pTheme->hwndParent)
607 + {
608 + ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeLoadControls called before theme parent window created.");
609 + }
610 +
611 + hr = LoadControls(pTheme, NULL, rgAssignControlIds, cAssignControlIds);
612 +
613 +LExit:
614 + return hr;
615 }
616
617
@@ -735,6 +786,10 @@ extern "C" LRESULT CALLBACK ThemeDefWindowProc(
786 {
787 switch (uMsg)
788 {
789 + case WM_NCCREATE:
790 + OnNcCreate(pTheme, hWnd, lParam);
791 + break;
792 +
793 case WM_NCHITTEST:
794 if (pTheme->dwStyle & WS_POPUP)
795 {
@@ -4107,6 +4162,15 @@ LExit:
4162 return fHandled;
4163 }
4164
4165 +static void OnNcCreate(
4166 + __in THEME* pTheme,
4167 + __in HWND hWnd,
4168 + __in LPARAM /*lParam*/
4169 + )
4170 +{
4171 + pTheme->hwndParent = hWnd;
4172 +}
4173 +
4174 static HRESULT OnRichEditEnLink(
4175 __in LPARAM lParam,
4176 __in HWND hWndRichEdit,
@@ -4620,7 +4684,6 @@ static LRESULT CALLBACK PanelWndProc(
4684 static HRESULT LoadControls(
4685 __in THEME* pTheme,
4686 __in_opt THEME_CONTROL* pParentControl,
4623 - __in HWND hwndParent,
4687 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
4688 __in DWORD cAssignControlIds
4689 )
@@ -4631,15 +4694,10 @@ static HRESULT LoadControls(
4694 BOOL fStartNewGroup = FALSE;
4695 DWORD cControls = 0;
4696 THEME_CONTROL* rgControls = NULL;
4634 -
4635 - if (!pParentControl)
4636 - {
4637 - AssertSz(!pTheme->hwndParent, "Theme already loaded controls because it has a parent window.");
4638 - pTheme->hwndParent = hwndParent;
4639 - }
4697 + HWND hwndParent = pParentControl ? pParentControl->hWnd : pTheme->hwndParent;
4698
4699 GetControls(pTheme, pParentControl, cControls, rgControls);
4642 - ::GetClientRect(pParentControl ? pParentControl->hWnd : pTheme->hwndParent, &rcParent);
4700 + ::GetClientRect(hwndParent, &rcParent);
4701
4702 for (DWORD i = 0; i < cControls; ++i)
4703 {
@@ -4974,7 +5032,7 @@ static HRESULT LoadControls(
5032
5033 if (pControl->cControls)
5034 {
4977 - hr = LoadControls(pTheme, pControl, pControl->hWnd, rgAssignControlIds, cAssignControlIds);
5035 + hr = LoadControls(pTheme, pControl, rgAssignControlIds, cAssignControlIds);
5036 ThmExitOnFailure(hr, "Failed to load child controls.");
5037 }
5038 }