aboutsummaryrefslogtreecommitdiff
path: root/src/libs
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-10-27 13:55:16 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-11-01 16:34:09 -0500
commit8fa040da9d0d3826f5ffda6bcbec4f53abd97452 (patch)
treea8a1094f3ac17bd6feed8a6f971c0d6008694345 /src/libs
parent4917383e6f52f0e44f63c60a645f1dd7e8f8d5f9 (diff)
downloadwix-8fa040da9d0d3826f5ffda6bcbec4f53abd97452.tar.gz
wix-8fa040da9d0d3826f5ffda6bcbec4f53abd97452.tar.bz2
wix-8fa040da9d0d3826f5ffda6bcbec4f53abd97452.zip
Allow more customization of control ids in thmutil.
Allow BAFunctions to set control ids. Make sure control ids don't collide.
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/thmutil.h35
-rw-r--r--src/libs/dutil/WixToolset.DUtil/thmutil.cpp75
2 files changed, 81 insertions, 29 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
index 6ac3711f..dc554219 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
@@ -95,6 +95,15 @@ typedef enum THEME_WINDOW_INITIAL_POSITION
95 THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES, 95 THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES,
96} THEME_WINDOW_INITIAL_POSITION; 96} THEME_WINDOW_INITIAL_POSITION;
97 97
98// These messages are sent by thmutil to the parent window created in ThemeCreateParentWindow.
99// thmutil reserves the last values of WM_USER's range.
100typedef enum _WM_THMUTIL
101{
102 // Sent while creating a control.
103 // wparam is THEME_LOADINGCONTROL_ARGS* and lparam is THEME_LOADINGCONTROL_RESULTS*.
104 // Return code is TRUE if it was processed.
105 WM_THMUTIL_LOADING_CONTROL = WM_APP - 1,
106} WM_THMUTIL;
98 107
99struct THEME_COLUMN 108struct THEME_COLUMN
100{ 109{
@@ -171,7 +180,7 @@ struct THEME_ASSIGN_CONTROL_ID
171 LPCWSTR wzName; // name of control to match 180 LPCWSTR wzName; // name of control to match
172}; 181};
173 182
174const DWORD THEME_FIRST_ASSIGN_CONTROL_ID = 1024; // Recommended first control id to be assigned. 183const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned.
175 184
176struct THEME_CONTROL 185struct THEME_CONTROL
177{ 186{
@@ -325,7 +334,7 @@ struct THEME_FONT
325 334
326struct THEME 335struct THEME
327{ 336{
328 WORD wId; 337 WORD wNextControlId;
329 338
330 BOOL fAutoResize; 339 BOOL fAutoResize;
331 BOOL fForceResize; 340 BOOL fForceResize;
@@ -388,6 +397,24 @@ struct THEME
388 LPVOID pvVariableContext; 397 LPVOID pvVariableContext;
389}; 398};
390 399
400typedef struct _THEME_LOADINGCONTROL_ARGS
401{
402 DWORD cbSize;
403 const THEME_CONTROL* pThemeControl;
404} THEME_LOADINGCONTROL_ARGS;
405
406typedef struct _THEME_LOADINGCONTROL_RESULTS
407{
408 DWORD cbSize;
409 HRESULT hr;
410
411 // Used to apply a specific id to the control (usually used for WM_COMMAND).
412 // If assigning an id, it is recommended to start with THEME_FIRST_ASSIGN_CONTROL_ID to avoid collisions with well known ids such as IDOK and IDCANCEL.
413 // The values [100, THEME_FIRST_ASSIGN_CONTROL_ID) are reserved for thmutil.
414 // Due to this value being packed into 16 bits for many system window messages, this is restricted to a WORD.
415 WORD wId;
416} THEME_LOADINGCONTROL_RESULTS;
417
391 418
392/******************************************************************** 419/********************************************************************
393 ThemeInitialize - initialized theme management. 420 ThemeInitialize - initialized theme management.
@@ -472,9 +499,7 @@ HRESULT DAPI ThemeCreateParentWindow(
472 499
473*******************************************************************/ 500*******************************************************************/
474HRESULT DAPI ThemeLoadControls( 501HRESULT DAPI ThemeLoadControls(
475 __in THEME* pTheme, 502 __in THEME* pTheme
476 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
477 __in DWORD cAssignControlIds
478 ); 503 );
479 504
480/******************************************************************** 505/********************************************************************
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
index 53257d8e..d796bbaf 100644
--- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
@@ -39,6 +39,7 @@
39#define LWS_NOPREFIX 0x0004 39#define LWS_NOPREFIX 0x0004
40#endif 40#endif
41 41
42const WORD THEME_FIRST_AUTO_ASSIGN_CONTROL_ID = 100;
42const DWORD THEME_INVALID_ID = 0xFFFFFFFF; 43const DWORD THEME_INVALID_ID = 0xFFFFFFFF;
43const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; 44const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF;
44const DWORD GROW_FONT_INSTANCES = 3; 45const DWORD GROW_FONT_INSTANCES = 3;
@@ -272,11 +273,14 @@ static HRESULT FindImageList(
272 __in_z LPCWSTR wzImageListName, 273 __in_z LPCWSTR wzImageListName,
273 __out HIMAGELIST *phImageList 274 __out HIMAGELIST *phImageList
274 ); 275 );
276static HRESULT OnLoadingControl(
277 __in THEME* pTheme,
278 __in const THEME_CONTROL* pControl,
279 __inout WORD* pwId
280 );
275static HRESULT LoadControls( 281static HRESULT LoadControls(
276 __in THEME* pTheme, 282 __in THEME* pTheme,
277 __in_opt THEME_CONTROL* pParentControl, 283 __in_opt THEME_CONTROL* pParentControl
278 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
279 __in DWORD cAssignControlIds
280 ); 284 );
281static HRESULT ShowControl( 285static HRESULT ShowControl(
282 __in THEME* pTheme, 286 __in THEME* pTheme,
@@ -871,9 +875,7 @@ LExit:
871 875
872 876
873DAPI_(HRESULT) ThemeLoadControls( 877DAPI_(HRESULT) ThemeLoadControls(
874 __in THEME* pTheme, 878 __in THEME* pTheme
875 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
876 __in DWORD cAssignControlIds
877 ) 879 )
878{ 880{
879 HRESULT hr = S_OK; 881 HRESULT hr = S_OK;
@@ -883,7 +885,7 @@ DAPI_(HRESULT) ThemeLoadControls(
883 ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeLoadControls called before theme parent window created."); 885 ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeLoadControls called before theme parent window created.");
884 } 886 }
885 887
886 hr = LoadControls(pTheme, NULL, rgAssignControlIds, cAssignControlIds); 888 hr = LoadControls(pTheme, NULL);
887 889
888LExit: 890LExit:
889 return hr; 891 return hr;
@@ -1844,8 +1846,6 @@ static HRESULT ParseTheme(
1844 __out THEME** ppTheme 1846 __out THEME** ppTheme
1845 ) 1847 )
1846{ 1848{
1847 static WORD wThemeId = 0;
1848
1849 HRESULT hr = S_OK; 1849 HRESULT hr = S_OK;
1850 THEME* pTheme = NULL; 1850 THEME* pTheme = NULL;
1851 IXMLDOMElement *pThemeElement = NULL; 1851 IXMLDOMElement *pThemeElement = NULL;
@@ -1858,8 +1858,8 @@ static HRESULT ParseTheme(
1858 pTheme = static_cast<THEME*>(MemAlloc(sizeof(THEME), TRUE)); 1858 pTheme = static_cast<THEME*>(MemAlloc(sizeof(THEME), TRUE));
1859 ThmExitOnNull(pTheme, hr, E_OUTOFMEMORY, "Failed to allocate memory for theme."); 1859 ThmExitOnNull(pTheme, hr, E_OUTOFMEMORY, "Failed to allocate memory for theme.");
1860 1860
1861 pTheme->wId = ++wThemeId;
1862 pTheme->nDpi = USER_DEFAULT_SCREEN_DPI; 1861 pTheme->nDpi = USER_DEFAULT_SCREEN_DPI;
1862 pTheme->wNextControlId = THEME_FIRST_AUTO_ASSIGN_CONTROL_ID;
1863 1863
1864 // Parse the optional background resource image. 1864 // Parse the optional background resource image.
1865 hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pThemeElement, &pBitmap); 1865 hr = GetAttributeImageFileOrResource(hModule, wzRelativePath, pThemeElement, &pBitmap);
@@ -5248,7 +5248,7 @@ static BOOL OnButtonClicked(
5248LExit: 5248LExit:
5249 return fHandled; 5249 return fHandled;
5250} 5250}
5251 5251
5252static BOOL OnDpiChanged( 5252static BOOL OnDpiChanged(
5253 __in THEME* pTheme, 5253 __in THEME* pTheme,
5254 __in WPARAM wParam, 5254 __in WPARAM wParam,
@@ -5934,11 +5934,38 @@ static LRESULT CALLBACK StaticOwnerDrawWndProc(
5934 } 5934 }
5935} 5935}
5936 5936
5937static HRESULT OnLoadingControl(
5938 __in THEME* pTheme,
5939 __in const THEME_CONTROL* pControl,
5940 __inout WORD* pwId
5941 )
5942{
5943 HRESULT hr = S_OK;
5944 THEME_LOADINGCONTROL_ARGS loadingControlArgs = { };
5945 THEME_LOADINGCONTROL_RESULTS loadingControlResults = { };
5946
5947 loadingControlArgs.cbSize = sizeof(loadingControlArgs);
5948 loadingControlArgs.pThemeControl = pControl;
5949
5950 loadingControlResults.cbSize = sizeof(loadingControlResults);
5951 loadingControlResults.hr = E_NOTIMPL;
5952 loadingControlResults.wId = *pwId;
5953
5954 if (::SendMessageW(pTheme->hwndParent, WM_THMUTIL_LOADING_CONTROL, reinterpret_cast<WPARAM>(&loadingControlArgs), reinterpret_cast<LPARAM>(&loadingControlResults)))
5955 {
5956 hr = loadingControlResults.hr;
5957 if (SUCCEEDED(hr))
5958 {
5959 *pwId = loadingControlResults.wId;
5960 }
5961 }
5962
5963 return hr;
5964}
5965
5937static HRESULT LoadControls( 5966static HRESULT LoadControls(
5938 __in THEME* pTheme, 5967 __in THEME* pTheme,
5939 __in_opt THEME_CONTROL* pParentControl, 5968 __in_opt THEME_CONTROL* pParentControl
5940 __in_ecount_opt(cAssignControlIds) const THEME_ASSIGN_CONTROL_ID* rgAssignControlIds,
5941 __in DWORD cAssignControlIds
5942 ) 5969 )
5943{ 5970{
5944 HRESULT hr = S_OK; 5971 HRESULT hr = S_OK;
@@ -6101,16 +6128,16 @@ static HRESULT LoadControls(
6101 } 6128 }
6102 ThmExitOnNull(wzWindowClass, hr, E_INVALIDDATA, "Failed to configure control %u because of unknown type: %u", i, pControl->type); 6129 ThmExitOnNull(wzWindowClass, hr, E_INVALIDDATA, "Failed to configure control %u because of unknown type: %u", i, pControl->type);
6103 6130
6104 // Default control ids to the theme id and its index in the control array, unless there 6131 // Default control ids to the next id, unless there is a specific id to assign to a control.
6105 // is a specific id to assign to a named control. 6132 WORD wControlId = THEME_FIRST_AUTO_ASSIGN_CONTROL_ID;
6106 WORD wControlId = MAKEWORD(i, pTheme->wId); 6133 hr = OnLoadingControl(pTheme, pControl, &wControlId);
6107 for (DWORD iAssignControl = 0; pControl->sczName && iAssignControl < cAssignControlIds; ++iAssignControl) 6134 ThmExitOnFailure(hr, "ThmLoadingControl failed.");
6135
6136 // This range is reserved for thmutil. The process will run out of available window handles before reaching the end of the range.
6137 if (THEME_FIRST_AUTO_ASSIGN_CONTROL_ID <= wControlId && THEME_FIRST_ASSIGN_CONTROL_ID > wControlId)
6108 { 6138 {
6109 if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pControl->sczName, -1, rgAssignControlIds[iAssignControl].wzName, -1)) 6139 wControlId = pTheme->wNextControlId;
6110 { 6140 pTheme->wNextControlId += 1;
6111 wControlId = rgAssignControlIds[iAssignControl].wId;
6112 break;
6113 }
6114 } 6141 }
6115 6142
6116 pControl->wId = wControlId; 6143 pControl->wId = wControlId;
@@ -6296,7 +6323,7 @@ static HRESULT LoadControls(
6296 6323
6297 if (pControl->cControls) 6324 if (pControl->cControls)
6298 { 6325 {
6299 hr = LoadControls(pTheme, pControl, rgAssignControlIds, cAssignControlIds); 6326 hr = LoadControls(pTheme, pControl);
6300 ThmExitOnFailure(hr, "Failed to load child controls."); 6327 ThmExitOnFailure(hr, "Failed to load child controls.");
6301 } 6328 }
6302 } 6329 }