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