diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-10-27 13:55:16 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-11-01 16:34:09 -0500 |
commit | 8fa040da9d0d3826f5ffda6bcbec4f53abd97452 (patch) | |
tree | a8a1094f3ac17bd6feed8a6f971c0d6008694345 /src/libs | |
parent | 4917383e6f52f0e44f63c60a645f1dd7e8f8d5f9 (diff) | |
download | wix-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.h | 35 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 75 |
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. | ||
100 | typedef 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 | ||
99 | struct THEME_COLUMN | 108 | struct 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 | ||
174 | const DWORD THEME_FIRST_ASSIGN_CONTROL_ID = 1024; // Recommended first control id to be assigned. | 183 | const WORD THEME_FIRST_ASSIGN_CONTROL_ID = 0x4000; // Recommended first control id to be assigned. |
175 | 184 | ||
176 | struct THEME_CONTROL | 185 | struct THEME_CONTROL |
177 | { | 186 | { |
@@ -325,7 +334,7 @@ struct THEME_FONT | |||
325 | 334 | ||
326 | struct THEME | 335 | struct 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 | ||
400 | typedef struct _THEME_LOADINGCONTROL_ARGS | ||
401 | { | ||
402 | DWORD cbSize; | ||
403 | const THEME_CONTROL* pThemeControl; | ||
404 | } THEME_LOADINGCONTROL_ARGS; | ||
405 | |||
406 | typedef 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 | *******************************************************************/ |
474 | HRESULT DAPI ThemeLoadControls( | 501 | HRESULT 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 | ||
42 | const WORD THEME_FIRST_AUTO_ASSIGN_CONTROL_ID = 100; | ||
42 | const DWORD THEME_INVALID_ID = 0xFFFFFFFF; | 43 | const DWORD THEME_INVALID_ID = 0xFFFFFFFF; |
43 | const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; | 44 | const COLORREF THEME_INVISIBLE_COLORREF = 0xFFFFFFFF; |
44 | const DWORD GROW_FONT_INSTANCES = 3; | 45 | const 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 | ); |
276 | static HRESULT OnLoadingControl( | ||
277 | __in THEME* pTheme, | ||
278 | __in const THEME_CONTROL* pControl, | ||
279 | __inout WORD* pwId | ||
280 | ); | ||
275 | static HRESULT LoadControls( | 281 | static 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 | ); |
281 | static HRESULT ShowControl( | 285 | static HRESULT ShowControl( |
282 | __in THEME* pTheme, | 286 | __in THEME* pTheme, |
@@ -871,9 +875,7 @@ LExit: | |||
871 | 875 | ||
872 | 876 | ||
873 | DAPI_(HRESULT) ThemeLoadControls( | 877 | DAPI_(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 | ||
888 | LExit: | 890 | LExit: |
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( | |||
5248 | LExit: | 5248 | LExit: |
5249 | return fHandled; | 5249 | return fHandled; |
5250 | } | 5250 | } |
5251 | 5251 | ||
5252 | static BOOL OnDpiChanged( | 5252 | static 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 | ||
5937 | static 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 | |||
5937 | static HRESULT LoadControls( | 5966 | static 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 | } |