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
}