diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/burn/balutil/inc/BAFunctions.h | 18 | ||||
| -rw-r--r-- | src/api/burn/balutil/inc/BalBaseBAFunctions.h | 9 | ||||
| -rw-r--r-- | src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | 12 | ||||
| -rw-r--r-- | src/api/burn/balutil/inc/IBAFunctions.h | 8 | ||||
| -rw-r--r-- | src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | 65 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 35 | ||||
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 75 | ||||
| -rw-r--r-- | src/samples/thmviewer/display.cpp | 2 | ||||
| -rw-r--r-- | src/samples/thmviewer/thmviewer.cpp | 27 | ||||
| -rw-r--r-- | src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp | 59 | ||||
| -rw-r--r-- | src/test/burn/TestData/Manual/BundleA/BundleA.wixproj | 2 | ||||
| -rw-r--r-- | src/test/burn/TestData/Manual/BundleA/BundleA.wxs | 3 | ||||
| -rw-r--r-- | src/test/burn/TestData/Manual/BundleA/CustomHyperlinkTheme.xml | 107 |
13 files changed, 374 insertions, 48 deletions
diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h index 43786701..2a34aaad 100644 --- a/src/api/burn/balutil/inc/BAFunctions.h +++ b/src/api/burn/balutil/inc/BAFunctions.h | |||
| @@ -85,6 +85,7 @@ enum BA_FUNCTIONS_MESSAGE | |||
| 85 | 85 | ||
| 86 | BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, | 86 | BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, |
| 87 | BA_FUNCTIONS_MESSAGE_WNDPROC, | 87 | BA_FUNCTIONS_MESSAGE_WNDPROC, |
| 88 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, | ||
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 90 | typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( | 91 | typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( |
| @@ -94,6 +95,10 @@ typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( | |||
| 94 | __in_opt LPVOID pvContext | 95 | __in_opt LPVOID pvContext |
| 95 | ); | 96 | ); |
| 96 | 97 | ||
| 98 | // Should be the same as THEME_FIRST_ASSIGN_CONTROL_ID. | ||
| 99 | // BAFunctions must only assign ids in the range [BAFUNCTIONS_FIRST_ASSIGN_CONTROL_ID, 0x8000) to avoid collisions. | ||
| 100 | const WORD BAFUNCTIONS_FIRST_ASSIGN_CONTROL_ID = 0x4000; | ||
| 101 | |||
| 97 | struct BA_FUNCTIONS_CREATE_ARGS | 102 | struct BA_FUNCTIONS_CREATE_ARGS |
| 98 | { | 103 | { |
| 99 | DWORD cbSize; | 104 | DWORD cbSize; |
| @@ -108,6 +113,19 @@ struct BA_FUNCTIONS_CREATE_RESULTS | |||
| 108 | LPVOID pvBAFunctionsProcContext; | 113 | LPVOID pvBAFunctionsProcContext; |
| 109 | }; | 114 | }; |
| 110 | 115 | ||
| 116 | struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS | ||
| 117 | { | ||
| 118 | DWORD cbSize; | ||
| 119 | LPCWSTR wzName; | ||
| 120 | }; | ||
| 121 | |||
| 122 | struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS | ||
| 123 | { | ||
| 124 | DWORD cbSize; | ||
| 125 | BOOL fProcessed; | ||
| 126 | WORD wId; | ||
| 127 | }; | ||
| 128 | |||
| 111 | struct BA_FUNCTIONS_ONTHEMELOADED_ARGS | 129 | struct BA_FUNCTIONS_ONTHEMELOADED_ARGS |
| 112 | { | 130 | { |
| 113 | DWORD cbSize; | 131 | DWORD cbSize; |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h index a3054709..c2c8a6dc 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h | |||
| @@ -841,6 +841,15 @@ public: // IBAFunctions | |||
| 841 | return E_NOTIMPL; | 841 | return E_NOTIMPL; |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | virtual STDMETHODIMP OnThemeControlLoading( | ||
| 845 | __in LPCWSTR /*wzName*/, | ||
| 846 | __inout BOOL* /*pfProcessed*/, | ||
| 847 | __inout WORD* /*pwId*/ | ||
| 848 | ) | ||
| 849 | { | ||
| 850 | return S_OK; | ||
| 851 | } | ||
| 852 | |||
| 844 | protected: | 853 | protected: |
| 845 | CBalBaseBAFunctions( | 854 | CBalBaseBAFunctions( |
| 846 | __in HMODULE hModule, | 855 | __in HMODULE hModule, |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h index 8d1227fc..efe22ddd 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | |||
| @@ -24,6 +24,15 @@ static HRESULT BalBaseBAFunctionsProcWndProc( | |||
| 24 | return pBAFunctions->WndProc(pArgs->pTheme, pArgs->hWnd, pArgs->uMsg, pArgs->wParam, pArgs->lParam, &pResults->lres); | 24 | return pBAFunctions->WndProc(pArgs->pTheme, pArgs->hWnd, pArgs->uMsg, pArgs->wParam, pArgs->lParam, &pResults->lres); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | static HRESULT BalBaseBAFunctionsProcOnThemeControlLoading( | ||
| 28 | __in IBAFunctions* pBAFunctions, | ||
| 29 | __in BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS* pArgs, | ||
| 30 | __inout BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS* pResults | ||
| 31 | ) | ||
| 32 | { | ||
| 33 | return pBAFunctions->OnThemeControlLoading(pArgs->wzName, &pResults->fProcessed, &pResults->wId); | ||
| 34 | } | ||
| 35 | |||
| 27 | /******************************************************************* | 36 | /******************************************************************* |
| 28 | BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions. | 37 | BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions. |
| 29 | Provides a default mapping between the message based BAFunctions interface and | 38 | Provides a default mapping between the message based BAFunctions interface and |
| @@ -125,6 +134,9 @@ static HRESULT WINAPI BalBaseBAFunctionsProc( | |||
| 125 | case BA_FUNCTIONS_MESSAGE_WNDPROC: | 134 | case BA_FUNCTIONS_MESSAGE_WNDPROC: |
| 126 | hr = BalBaseBAFunctionsProcWndProc(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_WNDPROC_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_WNDPROC_RESULTS*>(pvResults)); | 135 | hr = BalBaseBAFunctionsProcWndProc(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_WNDPROC_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_WNDPROC_RESULTS*>(pvResults)); |
| 127 | break; | 136 | break; |
| 137 | case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING: | ||
| 138 | hr = BalBaseBAFunctionsProcOnThemeControlLoading(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS*>(pvResults)); | ||
| 139 | break; | ||
| 128 | } | 140 | } |
| 129 | } | 141 | } |
| 130 | 142 | ||
diff --git a/src/api/burn/balutil/inc/IBAFunctions.h b/src/api/burn/balutil/inc/IBAFunctions.h index 7d8a07fa..d41b7c9b 100644 --- a/src/api/burn/balutil/inc/IBAFunctions.h +++ b/src/api/burn/balutil/inc/IBAFunctions.h | |||
| @@ -31,4 +31,12 @@ DECLARE_INTERFACE_IID_(IBAFunctions, IBootstrapperApplication, "0FB445ED-17BD-49 | |||
| 31 | __inout LPVOID pvResults, | 31 | __inout LPVOID pvResults, |
| 32 | __in_opt LPVOID pvContext | 32 | __in_opt LPVOID pvContext |
| 33 | ) = 0; | 33 | ) = 0; |
| 34 | |||
| 35 | // OnThemeControlLoading - Called while creating a control for the theme. | ||
| 36 | // | ||
| 37 | STDMETHOD(OnThemeControlLoading)( | ||
| 38 | __in LPCWSTR wzName, | ||
| 39 | __inout BOOL* pfProcessed, | ||
| 40 | __inout WORD* pwId | ||
| 41 | ) = 0; | ||
| 34 | }; | 42 | }; |
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 74e0b7d3..8cdd31ce 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
| @@ -77,10 +77,15 @@ static LPCWSTR vrgwzPageNames[] = { | |||
| 77 | L"Failure", | 77 | L"Failure", |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | // The range [0, 100) is unused to avoid collisions with system ids, | ||
| 81 | // the range [100, 0x4000) is unused to avoid collisions with thmutil, | ||
| 82 | // the range [0x4000, 0x8000) is unused to avoid collisions with BAFunctions. | ||
| 83 | const WORD WIXSTDBA_FIRST_ASSIGN_CONTROL_ID = 0x8000; | ||
| 84 | |||
| 80 | enum WIXSTDBA_CONTROL | 85 | enum WIXSTDBA_CONTROL |
| 81 | { | 86 | { |
| 82 | // Welcome page | 87 | // Welcome page |
| 83 | WIXSTDBA_CONTROL_INSTALL_BUTTON = THEME_FIRST_ASSIGN_CONTROL_ID, | 88 | WIXSTDBA_CONTROL_INSTALL_BUTTON = WIXSTDBA_FIRST_ASSIGN_CONTROL_ID, |
| 84 | WIXSTDBA_CONTROL_EULA_RICHEDIT, | 89 | WIXSTDBA_CONTROL_EULA_RICHEDIT, |
| 85 | WIXSTDBA_CONTROL_EULA_LINK, | 90 | WIXSTDBA_CONTROL_EULA_LINK, |
| 86 | WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, | 91 | WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, |
| @@ -2833,6 +2838,9 @@ private: | |||
| 2833 | } | 2838 | } |
| 2834 | break; | 2839 | break; |
| 2835 | 2840 | ||
| 2841 | case WM_THMUTIL_LOADING_CONTROL: | ||
| 2842 | return pBA->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); | ||
| 2843 | |||
| 2836 | case WM_QUERYENDSESSION: | 2844 | case WM_QUERYENDSESSION: |
| 2837 | fCancel = true; | 2845 | fCancel = true; |
| 2838 | pBA->OnSystemShutdown(static_cast<DWORD>(lParam), &fCancel); | 2846 | pBA->OnSystemShutdown(static_cast<DWORD>(lParam), &fCancel); |
| @@ -2956,7 +2964,7 @@ private: | |||
| 2956 | BA_FUNCTIONS_ONTHEMELOADED_ARGS themeLoadedArgs = { }; | 2964 | BA_FUNCTIONS_ONTHEMELOADED_ARGS themeLoadedArgs = { }; |
| 2957 | BA_FUNCTIONS_ONTHEMELOADED_RESULTS themeLoadedResults = { }; | 2965 | BA_FUNCTIONS_ONTHEMELOADED_RESULTS themeLoadedResults = { }; |
| 2958 | 2966 | ||
| 2959 | hr = ThemeLoadControls(m_pTheme, vrgInitControls, countof(vrgInitControls)); | 2967 | hr = ThemeLoadControls(m_pTheme); |
| 2960 | BalExitOnFailure(hr, "Failed to load theme controls."); | 2968 | BalExitOnFailure(hr, "Failed to load theme controls."); |
| 2961 | 2969 | ||
| 2962 | C_ASSERT(COUNT_WIXSTDBA_PAGE == countof(vrgwzPageNames)); | 2970 | C_ASSERT(COUNT_WIXSTDBA_PAGE == countof(vrgwzPageNames)); |
| @@ -3029,6 +3037,57 @@ private: | |||
| 3029 | return SUCCEEDED(hr); | 3037 | return SUCCEEDED(hr); |
| 3030 | } | 3038 | } |
| 3031 | 3039 | ||
| 3040 | BOOL OnThemeLoadingControl( | ||
| 3041 | __in const THEME_LOADINGCONTROL_ARGS* pArgs, | ||
| 3042 | __in THEME_LOADINGCONTROL_RESULTS* pResults | ||
| 3043 | ) | ||
| 3044 | { | ||
| 3045 | HRESULT hr = S_OK; | ||
| 3046 | BOOL fProcessed = FALSE; | ||
| 3047 | BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS themeControlLoadingArgs = { }; | ||
| 3048 | BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS themeControlLoadingResults = { }; | ||
| 3049 | |||
| 3050 | for (DWORD iAssignControl = 0; iAssignControl < countof(vrgInitControls); ++iAssignControl) | ||
| 3051 | { | ||
| 3052 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, vrgInitControls[iAssignControl].wzName, -1)) | ||
| 3053 | { | ||
| 3054 | fProcessed = TRUE; | ||
| 3055 | pResults->wId = vrgInitControls[iAssignControl].wId; | ||
| 3056 | ExitFunction(); | ||
| 3057 | } | ||
| 3058 | } | ||
| 3059 | |||
| 3060 | if (m_pfnBAFunctionsProc) | ||
| 3061 | { | ||
| 3062 | themeControlLoadingArgs.cbSize = sizeof(themeControlLoadingArgs); | ||
| 3063 | themeControlLoadingArgs.wzName = pArgs->pThemeControl->sczName; | ||
| 3064 | |||
| 3065 | themeControlLoadingResults.cbSize = sizeof(themeControlLoadingResults); | ||
| 3066 | themeControlLoadingResults.wId = pResults->wId; | ||
| 3067 | |||
| 3068 | hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, &themeControlLoadingArgs, &themeControlLoadingResults, m_pvBAFunctionsProcContext); | ||
| 3069 | |||
| 3070 | if (E_NOTIMPL == hr) | ||
| 3071 | { | ||
| 3072 | hr = S_OK; | ||
| 3073 | } | ||
| 3074 | else | ||
| 3075 | { | ||
| 3076 | BalExitOnFailure(hr, "BAFunctions OnThemeControlLoading failed."); | ||
| 3077 | |||
| 3078 | if (themeControlLoadingResults.fProcessed) | ||
| 3079 | { | ||
| 3080 | fProcessed = TRUE; | ||
| 3081 | pResults->wId = themeControlLoadingResults.wId; | ||
| 3082 | } | ||
| 3083 | } | ||
| 3084 | } | ||
| 3085 | |||
| 3086 | LExit: | ||
| 3087 | pResults->hr = hr; | ||
| 3088 | return fProcessed || FAILED(hr); | ||
| 3089 | } | ||
| 3090 | |||
| 3032 | 3091 | ||
| 3033 | // | 3092 | // |
| 3034 | // OnShowFailure - display the failure page. | 3093 | // OnShowFailure - display the failure page. |
| @@ -3857,7 +3916,7 @@ private: | |||
| 3857 | BalExitOnNullWithLastError(pfnBAFunctionsCreate, hr, "Failed to get BAFunctionsCreate entry-point from: %ls", sczBafPath); | 3916 | BalExitOnNullWithLastError(pfnBAFunctionsCreate, hr, "Failed to get BAFunctionsCreate entry-point from: %ls", sczBafPath); |
| 3858 | 3917 | ||
| 3859 | bafCreateArgs.cbSize = sizeof(bafCreateArgs); | 3918 | bafCreateArgs.cbSize = sizeof(bafCreateArgs); |
| 3860 | bafCreateArgs.qwBAFunctionsAPIVersion = MAKEQWORDVERSION(0, 0, 0, 2); // TODO: need to decide whether to keep this, and if so when to update it. | 3919 | bafCreateArgs.qwBAFunctionsAPIVersion = MAKEQWORDVERSION(2021, 9, 20, 0); |
| 3861 | bafCreateArgs.pBootstrapperCreateArgs = &m_createArgs; | 3920 | bafCreateArgs.pBootstrapperCreateArgs = &m_createArgs; |
| 3862 | 3921 | ||
| 3863 | bafCreateResults.cbSize = sizeof(bafCreateResults); | 3922 | bafCreateResults.cbSize = sizeof(bafCreateResults); |
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 | } |
diff --git a/src/samples/thmviewer/display.cpp b/src/samples/thmviewer/display.cpp index 52fa3cf8..c0e6c7e1 100644 --- a/src/samples/thmviewer/display.cpp +++ b/src/samples/thmviewer/display.cpp | |||
| @@ -329,7 +329,7 @@ static BOOL DisplayOnCreate( | |||
| 329 | { | 329 | { |
| 330 | HRESULT hr = S_OK; | 330 | HRESULT hr = S_OK; |
| 331 | 331 | ||
| 332 | hr = ThemeLoadControls(pTheme, NULL, 0); | 332 | hr = ThemeLoadControls(pTheme); |
| 333 | ExitOnFailure(hr, "Failed to load theme controls"); | 333 | ExitOnFailure(hr, "Failed to load theme controls"); |
| 334 | 334 | ||
| 335 | // Pre-populate some control types with data. | 335 | // Pre-populate some control types with data. |
diff --git a/src/samples/thmviewer/thmviewer.cpp b/src/samples/thmviewer/thmviewer.cpp index f83182d3..cffa3851 100644 --- a/src/samples/thmviewer/thmviewer.cpp +++ b/src/samples/thmviewer/thmviewer.cpp | |||
| @@ -14,10 +14,6 @@ enum THMVWR_CONTROL | |||
| 14 | THMVWR_CONTROL_TREE = THEME_FIRST_ASSIGN_CONTROL_ID, | 14 | THMVWR_CONTROL_TREE = THEME_FIRST_ASSIGN_CONTROL_ID, |
| 15 | }; | 15 | }; |
| 16 | 16 | ||
| 17 | static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = { | ||
| 18 | { THMVWR_CONTROL_TREE, L"Tree" }, | ||
| 19 | }; | ||
| 20 | |||
| 21 | // Internal functions | 17 | // Internal functions |
| 22 | 18 | ||
| 23 | static HRESULT ProcessCommandLine( | 19 | static HRESULT ProcessCommandLine( |
| @@ -52,6 +48,10 @@ static void OnNewTheme( | |||
| 52 | __in HWND hWnd, | 48 | __in HWND hWnd, |
| 53 | __in HANDLE_THEME* pHandle | 49 | __in HANDLE_THEME* pHandle |
| 54 | ); | 50 | ); |
| 51 | static BOOL OnThemeLoadingControl( | ||
| 52 | __in const THEME_LOADINGCONTROL_ARGS* pArgs, | ||
| 53 | __in THEME_LOADINGCONTROL_RESULTS* pResults | ||
| 54 | ); | ||
| 55 | static void CALLBACK ThmviewerTraceError( | 55 | static void CALLBACK ThmviewerTraceError( |
| 56 | __in_z LPCSTR szFile, | 56 | __in_z LPCSTR szFile, |
| 57 | __in int iLine, | 57 | __in int iLine, |
| @@ -353,7 +353,7 @@ static LRESULT CALLBACK MainWndProc( | |||
| 353 | 353 | ||
| 354 | case WM_CREATE: | 354 | case WM_CREATE: |
| 355 | { | 355 | { |
| 356 | HRESULT hr = ThemeLoadControls(vpTheme, vrgInitControls, countof(vrgInitControls)); | 356 | HRESULT hr = ThemeLoadControls(vpTheme); |
| 357 | if (FAILED(hr)) | 357 | if (FAILED(hr)) |
| 358 | { | 358 | { |
| 359 | return -1; | 359 | return -1; |
| @@ -400,6 +400,9 @@ static LRESULT CALLBACK MainWndProc( | |||
| 400 | } | 400 | } |
| 401 | } | 401 | } |
| 402 | break; | 402 | break; |
| 403 | |||
| 404 | case WM_THMUTIL_LOADING_CONTROL: | ||
| 405 | return OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); | ||
| 403 | } | 406 | } |
| 404 | 407 | ||
| 405 | return ThemeDefWindowProc(vpTheme, hWnd, uMsg, wParam, lParam); | 408 | return ThemeDefWindowProc(vpTheme, hWnd, uMsg, wParam, lParam); |
| @@ -541,3 +544,17 @@ static void OnNewTheme( | |||
| 541 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast<LPARAM>(htiSelected)); | 544 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_SELECTITEM, TVGN_CARET, reinterpret_cast<LPARAM>(htiSelected)); |
| 542 | } | 545 | } |
| 543 | } | 546 | } |
| 547 | |||
| 548 | static BOOL OnThemeLoadingControl( | ||
| 549 | __in const THEME_LOADINGCONTROL_ARGS* pArgs, | ||
| 550 | __in THEME_LOADINGCONTROL_RESULTS* pResults | ||
| 551 | ) | ||
| 552 | { | ||
| 553 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, L"Tree", -1)) | ||
| 554 | { | ||
| 555 | pResults->wId = THMVWR_CONTROL_TREE; | ||
| 556 | } | ||
| 557 | |||
| 558 | pResults->hr = S_OK; | ||
| 559 | return TRUE; | ||
| 560 | } | ||
diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp index 8b49cab6..b35b4e02 100644 --- a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp | |||
| @@ -6,6 +6,11 @@ | |||
| 6 | 6 | ||
| 7 | static const LPCWSTR BAFTHMUTILTESTING_WINDOW_CLASS = L"BafThmUtilTesting"; | 7 | static const LPCWSTR BAFTHMUTILTESTING_WINDOW_CLASS = L"BafThmUtilTesting"; |
| 8 | 8 | ||
| 9 | enum BAF_CONTROL | ||
| 10 | { | ||
| 11 | BAF_CONTROL_INSTALL_TEST_BUTTON = BAFUNCTIONS_FIRST_ASSIGN_CONTROL_ID, | ||
| 12 | }; | ||
| 13 | |||
| 9 | enum BAFTHMUTILTESTING_CONTROL | 14 | enum BAFTHMUTILTESTING_CONTROL |
| 10 | { | 15 | { |
| 11 | BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT = THEME_FIRST_ASSIGN_CONTROL_ID, | 16 | BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT = THEME_FIRST_ASSIGN_CONTROL_ID, |
| @@ -59,24 +64,41 @@ public: // IBAFunctions | |||
| 59 | __inout LRESULT* plRes | 64 | __inout LRESULT* plRes |
| 60 | ) | 65 | ) |
| 61 | { | 66 | { |
| 62 | HRESULT hr = S_OK; | ||
| 63 | |||
| 64 | __super::WndProc(pTheme, hWnd, uMsg, wParam, lParam, plRes); | ||
| 65 | |||
| 66 | // Show our window when any button is clicked. | ||
| 67 | switch (uMsg) | 67 | switch (uMsg) |
| 68 | { | 68 | { |
| 69 | case WM_COMMAND: | 69 | case WM_COMMAND: |
| 70 | switch (HIWORD(wParam)) | 70 | switch (HIWORD(wParam)) |
| 71 | { | 71 | { |
| 72 | case BN_CLICKED: | 72 | case BN_CLICKED: |
| 73 | OnShowTheme(); | 73 | switch (LOWORD(wParam)) |
| 74 | { | ||
| 75 | case BAF_CONTROL_INSTALL_TEST_BUTTON: | ||
| 76 | OnShowTheme(); | ||
| 77 | *plRes = 0; | ||
| 78 | return S_OK; | ||
| 79 | } | ||
| 80 | |||
| 74 | break; | 81 | break; |
| 75 | } | 82 | } |
| 76 | break; | 83 | break; |
| 77 | } | 84 | } |
| 78 | 85 | ||
| 79 | return hr; | 86 | return __super::WndProc(pTheme, hWnd, uMsg, wParam, lParam, plRes); |
| 87 | } | ||
| 88 | |||
| 89 | virtual STDMETHODIMP OnThemeControlLoading( | ||
| 90 | __in LPCWSTR wzName, | ||
| 91 | __inout BOOL* pfProcessed, | ||
| 92 | __inout WORD* pwId | ||
| 93 | ) | ||
| 94 | { | ||
| 95 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzName, -1, L"InstallTestButton", -1)) | ||
| 96 | { | ||
| 97 | *pfProcessed = TRUE; | ||
| 98 | *pwId = BAF_CONTROL_INSTALL_TEST_BUTTON; | ||
| 99 | } | ||
| 100 | |||
| 101 | return S_OK; | ||
| 80 | } | 102 | } |
| 81 | 103 | ||
| 82 | private: | 104 | private: |
| @@ -229,6 +251,9 @@ private: | |||
| 229 | } | 251 | } |
| 230 | break; | 252 | break; |
| 231 | 253 | ||
| 254 | case WM_THMUTIL_LOADING_CONTROL: | ||
| 255 | return pBaf->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); | ||
| 256 | |||
| 232 | case WM_TIMER: | 257 | case WM_TIMER: |
| 233 | if (!lParam && pBaf) | 258 | if (!lParam && pBaf) |
| 234 | { | 259 | { |
| @@ -255,7 +280,7 @@ private: | |||
| 255 | HWND hwndBottomLeft = NULL; | 280 | HWND hwndBottomLeft = NULL; |
| 256 | HWND hwndBottomRight = NULL; | 281 | HWND hwndBottomRight = NULL; |
| 257 | 282 | ||
| 258 | hr = ThemeLoadControls(m_pBafTheme, vrgInitControls, countof(vrgInitControls)); | 283 | hr = ThemeLoadControls(m_pBafTheme); |
| 259 | BalExitOnFailure(hr, "Failed to load theme controls."); | 284 | BalExitOnFailure(hr, "Failed to load theme controls."); |
| 260 | 285 | ||
| 261 | hwndTopLeft = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT); | 286 | hwndTopLeft = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT); |
| @@ -333,6 +358,24 @@ private: | |||
| 333 | return SUCCEEDED(hr); | 358 | return SUCCEEDED(hr); |
| 334 | } | 359 | } |
| 335 | 360 | ||
| 361 | BOOL OnThemeLoadingControl( | ||
| 362 | __in const THEME_LOADINGCONTROL_ARGS* pArgs, | ||
| 363 | __in THEME_LOADINGCONTROL_RESULTS* pResults | ||
| 364 | ) | ||
| 365 | { | ||
| 366 | for (DWORD iAssignControl = 0; iAssignControl < countof(vrgInitControls); ++iAssignControl) | ||
| 367 | { | ||
| 368 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, vrgInitControls[iAssignControl].wzName, -1)) | ||
| 369 | { | ||
| 370 | pResults->wId = vrgInitControls[iAssignControl].wId; | ||
| 371 | break; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 375 | pResults->hr = S_OK; | ||
| 376 | return TRUE; | ||
| 377 | } | ||
| 378 | |||
| 336 | void UpdateProgressBarProgress() | 379 | void UpdateProgressBarProgress() |
| 337 | { | 380 | { |
| 338 | static DWORD dwProgress = 0; | 381 | static DWORD dwProgress = 0; |
diff --git a/src/test/burn/TestData/Manual/BundleA/BundleA.wixproj b/src/test/burn/TestData/Manual/BundleA/BundleA.wixproj index dcfd3b7e..907b85c9 100644 --- a/src/test/burn/TestData/Manual/BundleA/BundleA.wixproj +++ b/src/test/burn/TestData/Manual/BundleA/BundleA.wixproj | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | <Project Sdk="WixToolset.Sdk"> | 2 | <Project Sdk="WixToolset.Sdk"> |
| 3 | <PropertyGroup> | 3 | <PropertyGroup> |
| 4 | <OutputType>Bundle</OutputType> | 4 | <OutputType>Bundle</OutputType> |
| 5 | <BA>hyperlinkLicense</BA> | 5 | <BA>customHyperlinkLicense</BA> |
| 6 | <UpgradeCode>{98ACBCF6-B54A-46AF-8990-DFB8795B965B}</UpgradeCode> | 6 | <UpgradeCode>{98ACBCF6-B54A-46AF-8990-DFB8795B965B}</UpgradeCode> |
| 7 | </PropertyGroup> | 7 | </PropertyGroup> |
| 8 | <ItemGroup> | 8 | <ItemGroup> |
diff --git a/src/test/burn/TestData/Manual/BundleA/BundleA.wxs b/src/test/burn/TestData/Manual/BundleA/BundleA.wxs index 1706f4e8..20706b6a 100644 --- a/src/test/burn/TestData/Manual/BundleA/BundleA.wxs +++ b/src/test/burn/TestData/Manual/BundleA/BundleA.wxs | |||
| @@ -3,7 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> |
| 5 | <Fragment> | 5 | <Fragment> |
| 6 | <BootstrapperApplication> | 6 | <BootstrapperApplication Id="customHyperlinkLicense"> |
| 7 | <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" ThemeFile="CustomHyperlinkTheme.xml" /> | ||
| 7 | <Payload SourceFile="$(var.BafThmUtilTesting.TargetPath)" bal:BAFunctions="yes" /> | 8 | <Payload SourceFile="$(var.BafThmUtilTesting.TargetPath)" bal:BAFunctions="yes" /> |
| 8 | </BootstrapperApplication> | 9 | </BootstrapperApplication> |
| 9 | <PackageGroup Id="BundlePackages"> | 10 | <PackageGroup Id="BundlePackages"> |
diff --git a/src/test/burn/TestData/Manual/BundleA/CustomHyperlinkTheme.xml b/src/test/burn/TestData/Manual/BundleA/CustomHyperlinkTheme.xml new file mode 100644 index 00000000..b8157193 --- /dev/null +++ b/src/test/burn/TestData/Manual/BundleA/CustomHyperlinkTheme.xml | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | |||
| 5 | <Theme xmlns="http://wixtoolset.org/schemas/v4/thmutil"> | ||
| 6 | <Font Id="0" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font> | ||
| 7 | <Font Id="1" Height="-24" Weight="500" Foreground="windowtext">Segoe UI</Font> | ||
| 8 | <Font Id="2" Height="-22" Weight="500" Foreground="graytext">Segoe UI</Font> | ||
| 9 | <Font Id="3" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font> | ||
| 10 | |||
| 11 | <Window Width="485" Height="300" HexStyle="100a0000" FontId="0" Caption="#(loc.Caption)"> | ||
| 12 | <ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" Visible="yes"/> | ||
| 13 | <Label X="80" Y="11" Width="-11" Height="64" FontId="1" Visible="yes" DisablePrefix="yes">#(loc.Title)</Label> | ||
| 14 | |||
| 15 | <Page Name="Help"> | ||
| 16 | <Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Label> | ||
| 17 | <Label X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Label> | ||
| 18 | <Button Name="HelpCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 19 | <Text>#(loc.HelpCloseButton)</Text> | ||
| 20 | <CloseWindowAction /> | ||
| 21 | </Button> | ||
| 22 | </Page> | ||
| 23 | <Page Name="Install"> | ||
| 24 | <Hypertext Name="EulaHyperlink" X="11" Y="121" Width="-11" Height="51" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallLicenseLinkText)</Hypertext> | ||
| 25 | <Checkbox Name="EulaAcceptCheckbox" X="-11" Y="-41" Width="260" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox> | ||
| 26 | <Button Name="InstallTestButton" X="-251" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">Test</Button> | ||
| 27 | <Button Name="OptionsButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" VisibleCondition="NOT WixStdBASuppressOptionsUI"> | ||
| 28 | <Text>#(loc.InstallOptionsButton)</Text> | ||
| 29 | <ChangePageAction Page="Options" /> | ||
| 30 | </Button> | ||
| 31 | <Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button> | ||
| 32 | <Button Name="InstallCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 33 | <Text>#(loc.InstallCancelButton)</Text> | ||
| 34 | <CloseWindowAction /> | ||
| 35 | </Button> | ||
| 36 | </Page> | ||
| 37 | <Page Name="Options"> | ||
| 38 | <Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Label> | ||
| 39 | <Label X="11" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OptionsLocationLabel)</Label> | ||
| 40 | <Editbox Name="InstallFolder" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" /> | ||
| 41 | <Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3"> | ||
| 42 | <Text>#(loc.OptionsBrowseButton)</Text> | ||
| 43 | <BrowseDirectoryAction VariableName="InstallFolder" /> | ||
| 44 | </Button> | ||
| 45 | <Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 46 | <Text>#(loc.OptionsOkButton)</Text> | ||
| 47 | <ChangePageAction Page="Install" /> | ||
| 48 | </Button> | ||
| 49 | <Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 50 | <Text>#(loc.OptionsCancelButton)</Text> | ||
| 51 | <ChangePageAction Page="Install" Cancel="yes" /> | ||
| 52 | </Button> | ||
| 53 | </Page> | ||
| 54 | <Page Name="Progress"> | ||
| 55 | <Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Label> | ||
| 56 | <Label X="11" Y="121" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Label> | ||
| 57 | <Label Name="OverallProgressPackageText" X="85" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Label> | ||
| 58 | <Progressbar Name="OverallCalculatedProgressbar" X="11" Y="143" Width="-11" Height="15" /> | ||
| 59 | <Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button> | ||
| 60 | </Page> | ||
| 61 | <Page Name="Modify"> | ||
| 62 | <Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Label> | ||
| 63 | <Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button> | ||
| 64 | <Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button> | ||
| 65 | <Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 66 | <Text>#(loc.ModifyCancelButton)</Text> | ||
| 67 | <CloseWindowAction /> | ||
| 68 | </Button> | ||
| 69 | </Page> | ||
| 70 | <Page Name="Success"> | ||
| 71 | <Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes"> | ||
| 72 | <Text>#(loc.SuccessHeader)</Text> | ||
| 73 | <Text Condition="WixBundleAction = 2">#(loc.SuccessLayoutHeader)</Text> | ||
| 74 | <Text Condition="WixBundleAction = 3">#(loc.SuccessUninstallHeader)</Text> | ||
| 75 | <Text Condition="WixBundleAction = 5">#(loc.SuccessInstallHeader)</Text> | ||
| 76 | <Text Condition="WixBundleAction = 7">#(loc.SuccessRepairHeader)</Text> | ||
| 77 | </Label> | ||
| 78 | <Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button> | ||
| 79 | <Label X="-11" Y="-51" Width="400" Height="34" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired"> | ||
| 80 | <Text>#(loc.SuccessRestartText)</Text> | ||
| 81 | <Text Condition="WixBundleAction = 3">#(loc.SuccessUninstallRestartText)</Text> | ||
| 82 | </Label> | ||
| 83 | <Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button> | ||
| 84 | <Button Name="SuccessCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 85 | <Text>#(loc.SuccessCloseButton)</Text> | ||
| 86 | <CloseWindowAction /> | ||
| 87 | </Button> | ||
| 88 | </Page> | ||
| 89 | <Page Name="Failure"> | ||
| 90 | <Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes"> | ||
| 91 | <Text>#(loc.FailureHeader)</Text> | ||
| 92 | <Text Condition="WixBundleAction = 2">#(loc.FailureLayoutHeader)</Text> | ||
| 93 | <Text Condition="WixBundleAction = 3">#(loc.FailureUninstallHeader)</Text> | ||
| 94 | <Text Condition="WixBundleAction = 5">#(loc.FailureInstallHeader)</Text> | ||
| 95 | <Text Condition="WixBundleAction = 7">#(loc.FailureRepairHeader)</Text> | ||
| 96 | </Label> | ||
| 97 | <Hypertext Name="FailureLogFileLink" X="11" Y="121" Width="-11" Height="42" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext> | ||
| 98 | <Hypertext Name="FailureMessageText" X="22" Y="163" Width="-11" Height="51" FontId="3" TabStop="yes" HideWhenDisabled="yes" /> | ||
| 99 | <Label X="-11" Y="-51" Width="400" Height="34" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">#(loc.FailureRestartText)</Label> | ||
| 100 | <Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button> | ||
| 101 | <Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0"> | ||
| 102 | <Text>#(loc.FailureCloseButton)</Text> | ||
| 103 | <CloseWindowAction /> | ||
| 104 | </Button> | ||
| 105 | </Page> | ||
| 106 | </Window> | ||
| 107 | </Theme> | ||
