diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-10-27 15:29:19 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-11-01 16:34:09 -0500 |
commit | dce1c97c7d3e76c18e4f80d4ffe288d2933a74bc (patch) | |
tree | 68dc0653ee1a6fe962d82dac2159c8ab00a95808 | |
parent | bad2e93524f376cfeb76d5231d4b08510bdad033 (diff) | |
download | wix-dce1c97c7d3e76c18e4f80d4ffe288d2933a74bc.tar.gz wix-dce1c97c7d3e76c18e4f80d4ffe288d2933a74bc.tar.bz2 wix-dce1c97c7d3e76c18e4f80d4ffe288d2933a74bc.zip |
Make thmutil automatically load controls during window creation.
Add control loaded event.
-rw-r--r-- | src/api/burn/balutil/inc/BAFunctions.h | 15 | ||||
-rw-r--r-- | src/api/burn/balutil/inc/BalBaseBAFunctions.h | 10 | ||||
-rw-r--r-- | src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | 12 | ||||
-rw-r--r-- | src/api/burn/balutil/inc/IBAFunctions.h | 9 | ||||
-rw-r--r-- | src/api/burn/balutil/inc/balutil.h | 2 | ||||
-rw-r--r-- | src/api/burn/bextutil/inc/bextutil.h | 2 | ||||
-rw-r--r-- | src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | 188 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 43 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 137 | ||||
-rw-r--r-- | src/samples/thmviewer/display.cpp | 58 | ||||
-rw-r--r-- | src/samples/thmviewer/thmviewer.cpp | 15 | ||||
-rw-r--r-- | src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp | 103 | ||||
-rw-r--r-- | src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingTheme.xml | 21 | ||||
-rw-r--r-- | src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingThemeLoose.xml | 158 |
14 files changed, 542 insertions, 231 deletions
diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h index ab6ea4d7..0eda95a1 100644 --- a/src/api/burn/balutil/inc/BAFunctions.h +++ b/src/api/burn/balutil/inc/BAFunctions.h | |||
@@ -88,6 +88,7 @@ enum BA_FUNCTIONS_MESSAGE | |||
88 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, | 88 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, |
89 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, | 89 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, |
90 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY, | 90 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY, |
91 | BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADED, | ||
91 | }; | 92 | }; |
92 | 93 | ||
93 | typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( | 94 | typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( |
@@ -115,6 +116,20 @@ struct BA_FUNCTIONS_CREATE_RESULTS | |||
115 | LPVOID pvBAFunctionsProcContext; | 116 | LPVOID pvBAFunctionsProcContext; |
116 | }; | 117 | }; |
117 | 118 | ||
119 | struct BA_FUNCTIONS_ONTHEMECONTROLLOADED_ARGS | ||
120 | { | ||
121 | DWORD cbSize; | ||
122 | LPCWSTR wzName; | ||
123 | WORD wId; | ||
124 | HWND hWnd; | ||
125 | }; | ||
126 | |||
127 | struct BA_FUNCTIONS_ONTHEMECONTROLLOADED_RESULTS | ||
128 | { | ||
129 | DWORD cbSize; | ||
130 | BOOL fProcessed; | ||
131 | }; | ||
132 | |||
118 | struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS | 133 | struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS |
119 | { | 134 | { |
120 | DWORD cbSize; | 135 | DWORD cbSize; |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h index f6c33f58..d97df350 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h | |||
@@ -874,6 +874,16 @@ public: // IBAFunctions | |||
874 | return S_OK; | 874 | return S_OK; |
875 | } | 875 | } |
876 | 876 | ||
877 | virtual STDMETHODIMP OnThemeControlLoaded( | ||
878 | __in LPCWSTR /*wzName*/, | ||
879 | __in WORD /*wId*/, | ||
880 | __in HWND /*hWnd*/, | ||
881 | __inout BOOL* /*pfProcessed*/ | ||
882 | ) | ||
883 | { | ||
884 | return S_OK; | ||
885 | } | ||
886 | |||
877 | protected: | 887 | protected: |
878 | CBalBaseBAFunctions( | 888 | CBalBaseBAFunctions( |
879 | __in HMODULE hModule, | 889 | __in HMODULE hModule, |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h index 1d51c5b6..2af231e8 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | |||
@@ -51,6 +51,15 @@ static HRESULT BalBaseBAFunctionsProcOnThemeControlWmNotify( | |||
51 | return pBAFunctions->OnThemeControlWmNotify(pArgs->lParam, pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed, &pResults->lResult); | 51 | return pBAFunctions->OnThemeControlWmNotify(pArgs->lParam, pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed, &pResults->lResult); |
52 | } | 52 | } |
53 | 53 | ||
54 | static HRESULT BalBaseBAFunctionsProcOnThemeControlLoaded( | ||
55 | __in IBAFunctions* pBAFunctions, | ||
56 | __in BA_FUNCTIONS_ONTHEMECONTROLLOADED_ARGS* pArgs, | ||
57 | __inout BA_FUNCTIONS_ONTHEMECONTROLLOADED_RESULTS* pResults | ||
58 | ) | ||
59 | { | ||
60 | return pBAFunctions->OnThemeControlLoaded(pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed); | ||
61 | } | ||
62 | |||
54 | /******************************************************************* | 63 | /******************************************************************* |
55 | BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions. | 64 | BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions. |
56 | Provides a default mapping between the message based BAFunctions interface and | 65 | Provides a default mapping between the message based BAFunctions interface and |
@@ -161,6 +170,9 @@ static HRESULT WINAPI BalBaseBAFunctionsProc( | |||
161 | case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY: | 170 | case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY: |
162 | hr = BalBaseBAFunctionsProcOnThemeControlWmNotify(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS*>(pvResults)); | 171 | hr = BalBaseBAFunctionsProcOnThemeControlWmNotify(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS*>(pvResults)); |
163 | break; | 172 | break; |
173 | case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADED: | ||
174 | hr = BalBaseBAFunctionsProcOnThemeControlLoaded(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADED_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADED_RESULTS*>(pvResults)); | ||
175 | break; | ||
164 | } | 176 | } |
165 | } | 177 | } |
166 | 178 | ||
diff --git a/src/api/burn/balutil/inc/IBAFunctions.h b/src/api/burn/balutil/inc/IBAFunctions.h index 63395e1e..2e71608d 100644 --- a/src/api/burn/balutil/inc/IBAFunctions.h +++ b/src/api/burn/balutil/inc/IBAFunctions.h | |||
@@ -61,4 +61,13 @@ DECLARE_INTERFACE_IID_(IBAFunctions, IBootstrapperApplication, "0FB445ED-17BD-49 | |||
61 | __inout BOOL* pfProcessed, | 61 | __inout BOOL* pfProcessed, |
62 | __inout LRESULT* plResult | 62 | __inout LRESULT* plResult |
63 | ) = 0; | 63 | ) = 0; |
64 | |||
65 | // OnThemeControlLoaded - Called after a control was created for the theme. | ||
66 | // | ||
67 | STDMETHOD(OnThemeControlLoaded)( | ||
68 | __in LPCWSTR wzName, | ||
69 | __in WORD wId, | ||
70 | __in HWND hWnd, | ||
71 | __inout BOOL* pfProcessed | ||
72 | ) = 0; | ||
64 | }; | 73 | }; |
diff --git a/src/api/burn/balutil/inc/balutil.h b/src/api/burn/balutil/inc/balutil.h index 82fd1fe5..0c47301a 100644 --- a/src/api/burn/balutil/inc/balutil.h +++ b/src/api/burn/balutil/inc/balutil.h | |||
@@ -11,6 +11,7 @@ extern "C" { | |||
11 | 11 | ||
12 | #define BalExitOnFailureSource(d, x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 12 | #define BalExitOnFailureSource(d, x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
13 | #define BalExitOnRootFailureSource(d, x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 13 | #define BalExitOnRootFailureSource(d, x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
14 | #define BalExitWithRootFailureSource(d, x, e, f, ...) { x = FAILED(e) ? e : E_FAIL; BalLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | ||
14 | #define BalExitOnLastErrorSource(d, x, f, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } } | 15 | #define BalExitOnLastErrorSource(d, x, f, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } } |
15 | #define BalExitOnNullSource(d, p, x, e, f, ...) if (NULL == p) { x = e; BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 16 | #define BalExitOnNullSource(d, p, x, e, f, ...) if (NULL == p) { x = e; BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
16 | #define BalExitOnNullWithLastErrorSource(d, p, x, f, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 17 | #define BalExitOnNullWithLastErrorSource(d, p, x, f, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BalLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
@@ -18,6 +19,7 @@ extern "C" { | |||
18 | 19 | ||
19 | #define BalExitOnFailure(x, f, ...) BalExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) | 20 | #define BalExitOnFailure(x, f, ...) BalExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) |
20 | #define BalExitOnRootFailure(x, f, ...) BalExitOnRootFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) | 21 | #define BalExitOnRootFailure(x, f, ...) BalExitOnRootFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) |
22 | #define BalExitWithRootFailure(x, e, f, ...) BalExitWithRootFailureSource(DUTIL_SOURCE_DEFAULT, x, e, f, __VA_ARGS__) | ||
21 | #define BalExitOnLastError(x, f, ...) BalExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) | 23 | #define BalExitOnLastError(x, f, ...) BalExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) |
22 | #define BalExitOnNull(p, x, e, f, ...) BalExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, f, __VA_ARGS__) | 24 | #define BalExitOnNull(p, x, e, f, ...) BalExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, f, __VA_ARGS__) |
23 | #define BalExitOnNullWithLastError(p, x, f, ...) BalExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, f, __VA_ARGS__) | 25 | #define BalExitOnNullWithLastError(p, x, f, ...) BalExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, f, __VA_ARGS__) |
diff --git a/src/api/burn/bextutil/inc/bextutil.h b/src/api/burn/bextutil/inc/bextutil.h index ac9c0062..facaf2e8 100644 --- a/src/api/burn/bextutil/inc/bextutil.h +++ b/src/api/burn/bextutil/inc/bextutil.h | |||
@@ -11,6 +11,7 @@ extern "C" { | |||
11 | 11 | ||
12 | #define BextExitOnFailureSource(d, x, f, ...) if (FAILED(x)) { BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 12 | #define BextExitOnFailureSource(d, x, f, ...) if (FAILED(x)) { BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
13 | #define BextExitOnRootFailureSource(d, x, f, ...) if (FAILED(x)) { BextLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 13 | #define BextExitOnRootFailureSource(d, x, f, ...) if (FAILED(x)) { BextLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
14 | #define BextExitWithRootFailureSource(d, x, e, f, ...) { x = FAILED(e) ? e : E_FAIL; BextLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | ||
14 | #define BextExitOnLastErrorSource(d, x, f, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } } | 15 | #define BextExitOnLastErrorSource(d, x, f, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } } |
15 | #define BextExitOnNullSource(d, p, x, e, f, ...) if (NULL == p) { x = e; BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 16 | #define BextExitOnNullSource(d, p, x, e, f, ...) if (NULL == p) { x = e; BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
16 | #define BextExitOnNullWithLastErrorSource(d, p, x, f, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } | 17 | #define BextExitOnNullWithLastErrorSource(d, p, x, f, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BextLogError(x, f, __VA_ARGS__); ExitTraceSource(d, x, f, __VA_ARGS__); goto LExit; } |
@@ -18,6 +19,7 @@ extern "C" { | |||
18 | 19 | ||
19 | #define BextExitOnFailure(x, f, ...) BextExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) | 20 | #define BextExitOnFailure(x, f, ...) BextExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) |
20 | #define BextExitOnRootFailure(x, f, ...) BextExitOnRootFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) | 21 | #define BextExitOnRootFailure(x, f, ...) BextExitOnRootFailureSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) |
22 | #define BextExitWithRootFailure(x, e, f, ...) BextExitWithRootFailureSource(DUTIL_SOURCE_DEFAULT, x, e, f, __VA_ARGS__) | ||
21 | #define BextExitOnLastError(x, f, ...) BextExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) | 23 | #define BextExitOnLastError(x, f, ...) BextExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, f, __VA_ARGS__) |
22 | #define BextExitOnNull(p, x, e, f, ...) BextExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, f, __VA_ARGS__) | 24 | #define BextExitOnNull(p, x, e, f, ...) BextExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, f, __VA_ARGS__) |
23 | #define BextExitOnNullWithLastError(p, x, f, ...) BextExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, f, __VA_ARGS__) | 25 | #define BextExitOnNullWithLastError(p, x, f, ...) BextExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, f, __VA_ARGS__) |
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 2283880c..5546b74f 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
@@ -2389,6 +2389,11 @@ private: | |||
2389 | hr = ThemeRegisterVariableCallbacks(m_pTheme, EvaluateVariableConditionCallback, FormatVariableStringCallback, GetVariableNumericCallback, SetVariableNumericCallback, GetVariableStringCallback, SetVariableStringCallback, NULL); | 2389 | hr = ThemeRegisterVariableCallbacks(m_pTheme, EvaluateVariableConditionCallback, FormatVariableStringCallback, GetVariableNumericCallback, SetVariableNumericCallback, GetVariableStringCallback, SetVariableStringCallback, NULL); |
2390 | BalExitOnFailure(hr, "Failed to register variable theme callbacks."); | 2390 | BalExitOnFailure(hr, "Failed to register variable theme callbacks."); |
2391 | 2391 | ||
2392 | C_ASSERT(COUNT_WIXSTDBA_PAGE == countof(vrgwzPageNames)); | ||
2393 | C_ASSERT(countof(m_rgdwPageIds) == countof(vrgwzPageNames)); | ||
2394 | |||
2395 | ThemeGetPageIds(m_pTheme, vrgwzPageNames, m_rgdwPageIds, countof(m_rgdwPageIds)); | ||
2396 | |||
2392 | hr = ThemeLocalize(m_pTheme, m_pWixLoc); | 2397 | hr = ThemeLocalize(m_pTheme, m_pWixLoc); |
2393 | BalExitOnFailure(hr, "Failed to localize theme: %ls", sczThemePath); | 2398 | BalExitOnFailure(hr, "Failed to localize theme: %ls", sczThemePath); |
2394 | 2399 | ||
@@ -2697,6 +2702,8 @@ private: | |||
2697 | hr = ThemeCreateParentWindow(m_pTheme, 0, wc.lpszClassName, m_pTheme->sczCaption, dwWindowStyle, x, y, HWND_DESKTOP, m_hModule, this, THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES, &m_hWnd); | 2702 | hr = ThemeCreateParentWindow(m_pTheme, 0, wc.lpszClassName, m_pTheme->sczCaption, dwWindowStyle, x, y, HWND_DESKTOP, m_hModule, this, THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES, &m_hWnd); |
2698 | ExitOnFailure(hr, "Failed to create window."); | 2703 | ExitOnFailure(hr, "Failed to create window."); |
2699 | 2704 | ||
2705 | OnThemeLoaded(); | ||
2706 | |||
2700 | hr = S_OK; | 2707 | hr = S_OK; |
2701 | 2708 | ||
2702 | LExit: | 2709 | LExit: |
@@ -2831,16 +2838,12 @@ private: | |||
2831 | return lres; | 2838 | return lres; |
2832 | } | 2839 | } |
2833 | 2840 | ||
2834 | case WM_CREATE: | ||
2835 | if (!pBA->OnCreate(hWnd)) | ||
2836 | { | ||
2837 | return -1; | ||
2838 | } | ||
2839 | break; | ||
2840 | |||
2841 | case WM_THMUTIL_LOADING_CONTROL: | 2841 | case WM_THMUTIL_LOADING_CONTROL: |
2842 | return pBA->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); | 2842 | return pBA->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); |
2843 | 2843 | ||
2844 | case WM_THMUTIL_LOADED_CONTROL: | ||
2845 | return pBA->OnThemeLoadedControl(reinterpret_cast<THEME_LOADEDCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADEDCONTROL_RESULTS*>(lParam)); | ||
2846 | |||
2844 | case WM_QUERYENDSESSION: | 2847 | case WM_QUERYENDSESSION: |
2845 | fCancel = true; | 2848 | fCancel = true; |
2846 | pBA->OnSystemShutdown(static_cast<DWORD>(lParam), &fCancel); | 2849 | pBA->OnSystemShutdown(static_cast<DWORD>(lParam), &fCancel); |
@@ -2896,74 +2899,14 @@ private: | |||
2896 | 2899 | ||
2897 | 2900 | ||
2898 | // | 2901 | // |
2899 | // OnCreate - finishes loading the theme. | 2902 | // OnThemeLoaded - finishes loading the theme. |
2900 | // | 2903 | // |
2901 | BOOL OnCreate( | 2904 | BOOL OnThemeLoaded() |
2902 | __in HWND /*hWnd*/ | ||
2903 | ) | ||
2904 | { | 2905 | { |
2905 | HRESULT hr = S_OK; | 2906 | HRESULT hr = S_OK; |
2906 | LPWSTR sczLicenseFormatted = NULL; | ||
2907 | LPWSTR sczLicensePath = NULL; | ||
2908 | LPWSTR sczLicenseDirectory = NULL; | ||
2909 | LPWSTR sczLicenseFilename = NULL; | ||
2910 | BA_FUNCTIONS_ONTHEMELOADED_ARGS themeLoadedArgs = { }; | 2907 | BA_FUNCTIONS_ONTHEMELOADED_ARGS themeLoadedArgs = { }; |
2911 | BA_FUNCTIONS_ONTHEMELOADED_RESULTS themeLoadedResults = { }; | 2908 | BA_FUNCTIONS_ONTHEMELOADED_RESULTS themeLoadedResults = { }; |
2912 | 2909 | ||
2913 | hr = ThemeLoadControls(m_pTheme); | ||
2914 | BalExitOnFailure(hr, "Failed to load theme controls."); | ||
2915 | |||
2916 | C_ASSERT(COUNT_WIXSTDBA_PAGE == countof(vrgwzPageNames)); | ||
2917 | C_ASSERT(countof(m_rgdwPageIds) == countof(vrgwzPageNames)); | ||
2918 | |||
2919 | ThemeGetPageIds(m_pTheme, vrgwzPageNames, m_rgdwPageIds, countof(m_rgdwPageIds)); | ||
2920 | |||
2921 | // Load the RTF EULA control with text if the control exists. | ||
2922 | if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_RICHEDIT)) | ||
2923 | { | ||
2924 | hr = (m_sczLicenseFile && *m_sczLicenseFile) ? S_OK : E_INVALIDDATA; | ||
2925 | if (SUCCEEDED(hr)) | ||
2926 | { | ||
2927 | hr = StrAllocString(&sczLicenseFormatted, m_sczLicenseFile, 0); | ||
2928 | if (SUCCEEDED(hr)) | ||
2929 | { | ||
2930 | hr = LocLocalizeString(m_pWixLoc, &sczLicenseFormatted); | ||
2931 | if (SUCCEEDED(hr)) | ||
2932 | { | ||
2933 | // Assume there is no hidden variables to be formatted | ||
2934 | // so don't worry about securely freeing it. | ||
2935 | hr = BalFormatString(sczLicenseFormatted, &sczLicenseFormatted); | ||
2936 | if (SUCCEEDED(hr)) | ||
2937 | { | ||
2938 | hr = PathRelativeToModule(&sczLicensePath, sczLicenseFormatted, m_hModule); | ||
2939 | if (SUCCEEDED(hr)) | ||
2940 | { | ||
2941 | hr = PathGetDirectory(sczLicensePath, &sczLicenseDirectory); | ||
2942 | if (SUCCEEDED(hr)) | ||
2943 | { | ||
2944 | hr = StrAllocString(&sczLicenseFilename, PathFile(sczLicenseFormatted), 0); | ||
2945 | if (SUCCEEDED(hr)) | ||
2946 | { | ||
2947 | hr = LocProbeForFile(sczLicenseDirectory, sczLicenseFilename, m_sczLanguage, &sczLicensePath); | ||
2948 | if (SUCCEEDED(hr)) | ||
2949 | { | ||
2950 | hr = ThemeLoadRichEditFromFile(m_pTheme, WIXSTDBA_CONTROL_EULA_RICHEDIT, sczLicensePath, m_hModule); | ||
2951 | } | ||
2952 | } | ||
2953 | } | ||
2954 | } | ||
2955 | } | ||
2956 | } | ||
2957 | } | ||
2958 | } | ||
2959 | |||
2960 | if (FAILED(hr)) | ||
2961 | { | ||
2962 | BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load file into license richedit control from path '%ls' manifest value: %ls", sczLicensePath, m_sczLicenseFile); | ||
2963 | hr = S_OK; | ||
2964 | } | ||
2965 | } | ||
2966 | |||
2967 | if (m_pfnBAFunctionsProc) | 2910 | if (m_pfnBAFunctionsProc) |
2968 | { | 2911 | { |
2969 | themeLoadedArgs.cbSize = sizeof(themeLoadedArgs); | 2912 | themeLoadedArgs.cbSize = sizeof(themeLoadedArgs); |
@@ -2975,11 +2918,6 @@ private: | |||
2975 | } | 2918 | } |
2976 | 2919 | ||
2977 | LExit: | 2920 | LExit: |
2978 | ReleaseStr(sczLicenseFilename); | ||
2979 | ReleaseStr(sczLicenseDirectory); | ||
2980 | ReleaseStr(sczLicensePath); | ||
2981 | ReleaseStr(sczLicenseFormatted); | ||
2982 | |||
2983 | return SUCCEEDED(hr); | 2921 | return SUCCEEDED(hr); |
2984 | } | 2922 | } |
2985 | 2923 | ||
@@ -3034,6 +2972,108 @@ private: | |||
3034 | return fProcessed || FAILED(hr); | 2972 | return fProcessed || FAILED(hr); |
3035 | } | 2973 | } |
3036 | 2974 | ||
2975 | BOOL OnThemeLoadedControl( | ||
2976 | __in const THEME_LOADEDCONTROL_ARGS* pArgs, | ||
2977 | __in THEME_LOADEDCONTROL_RESULTS* pResults | ||
2978 | ) | ||
2979 | { | ||
2980 | HRESULT hr = S_OK; | ||
2981 | BOOL fProcessed = FALSE; | ||
2982 | BA_FUNCTIONS_ONTHEMECONTROLLOADED_ARGS themeControlLoadedArgs = { }; | ||
2983 | BA_FUNCTIONS_ONTHEMECONTROLLOADED_RESULTS themeControlLoadedResults = { }; | ||
2984 | |||
2985 | if (WIXSTDBA_CONTROL_EULA_RICHEDIT == pArgs->pThemeControl->wId) | ||
2986 | { | ||
2987 | // Best effort to load the RTF EULA control with text. | ||
2988 | OnLoadedEulaRtfControl(pArgs->pThemeControl); | ||
2989 | fProcessed = TRUE; | ||
2990 | ExitFunction(); | ||
2991 | } | ||
2992 | |||
2993 | if (m_pfnBAFunctionsProc) | ||
2994 | { | ||
2995 | themeControlLoadedArgs.cbSize = sizeof(themeControlLoadedArgs); | ||
2996 | themeControlLoadedArgs.wzName = pArgs->pThemeControl->sczName; | ||
2997 | themeControlLoadedArgs.wId = pArgs->pThemeControl->wId; | ||
2998 | themeControlLoadedArgs.hWnd = pArgs->pThemeControl->hWnd; | ||
2999 | |||
3000 | themeControlLoadedResults.cbSize = sizeof(themeControlLoadedResults); | ||
3001 | |||
3002 | hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADED, &themeControlLoadedArgs, &themeControlLoadedResults, m_pvBAFunctionsProcContext); | ||
3003 | |||
3004 | if (E_NOTIMPL == hr) | ||
3005 | { | ||
3006 | hr = S_OK; | ||
3007 | } | ||
3008 | else | ||
3009 | { | ||
3010 | BalExitOnFailure(hr, "BAFunctions OnThemeControlLoaded failed."); | ||
3011 | |||
3012 | if (themeControlLoadedResults.fProcessed) | ||
3013 | { | ||
3014 | fProcessed = TRUE; | ||
3015 | } | ||
3016 | } | ||
3017 | } | ||
3018 | |||
3019 | LExit: | ||
3020 | pResults->hr = hr; | ||
3021 | return fProcessed || FAILED(hr); | ||
3022 | } | ||
3023 | |||
3024 | HRESULT OnLoadedEulaRtfControl( | ||
3025 | const THEME_CONTROL* pThemeControl | ||
3026 | ) | ||
3027 | { | ||
3028 | HRESULT hr = S_OK; | ||
3029 | LPWSTR sczLicenseFormatted = NULL; | ||
3030 | LPWSTR sczLicensePath = NULL; | ||
3031 | LPWSTR sczLicenseDirectory = NULL; | ||
3032 | LPWSTR sczLicenseFilename = NULL; | ||
3033 | |||
3034 | if (!m_sczLicenseFile || !*m_sczLicenseFile) | ||
3035 | { | ||
3036 | ExitWithRootFailure(hr, E_INVALIDDATA, "No license file in manifest."); | ||
3037 | } | ||
3038 | |||
3039 | hr = StrAllocString(&sczLicenseFormatted, m_sczLicenseFile, 0); | ||
3040 | ExitOnFailure(hr, "Failed to copy manifest license file."); | ||
3041 | |||
3042 | hr = LocLocalizeString(m_pWixLoc, &sczLicenseFormatted); | ||
3043 | ExitOnFailure(hr, "Failed to localize manifest license file."); | ||
3044 | |||
3045 | hr = BalFormatString(sczLicenseFormatted, &sczLicenseFormatted); | ||
3046 | ExitOnFailure(hr, "Failed to expand localized manifest license file."); | ||
3047 | |||
3048 | hr = PathRelativeToModule(&sczLicensePath, sczLicenseFormatted, m_hModule); | ||
3049 | ExitOnFailure(hr, "Failed to get relative path for license file."); | ||
3050 | |||
3051 | hr = PathGetDirectory(sczLicensePath, &sczLicenseDirectory); | ||
3052 | ExitOnFailure(hr, "Failed to get license file directory."); | ||
3053 | |||
3054 | hr = StrAllocString(&sczLicenseFilename, PathFile(sczLicenseFormatted), 0); | ||
3055 | ExitOnFailure(hr, "Failed to copy license file name."); | ||
3056 | |||
3057 | hr = LocProbeForFile(sczLicenseDirectory, sczLicenseFilename, m_sczLanguage, &sczLicensePath); | ||
3058 | ExitOnFailure(hr, "Failed to probe for localized license file."); | ||
3059 | |||
3060 | hr = ThemeLoadRichEditFromFile(m_pTheme, pThemeControl->wId, sczLicensePath, m_hModule); | ||
3061 | ExitOnFailure(hr, "Failed to load license file into richedit control."); | ||
3062 | |||
3063 | LExit: | ||
3064 | if (FAILED(hr)) | ||
3065 | { | ||
3066 | BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load file into license richedit control from path '%ls' manifest value: %ls", sczLicensePath, m_sczLicenseFile); | ||
3067 | } | ||
3068 | |||
3069 | ReleaseStr(sczLicenseFilename); | ||
3070 | ReleaseStr(sczLicenseDirectory); | ||
3071 | ReleaseStr(sczLicensePath); | ||
3072 | ReleaseStr(sczLicenseFormatted); | ||
3073 | |||
3074 | return hr; | ||
3075 | } | ||
3076 | |||
3037 | 3077 | ||
3038 | // | 3078 | // |
3039 | // OnShowFailure - display the failure page. | 3079 | // OnShowFailure - display the failure page. |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h index 9557c11c..eda81485 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | |||
@@ -6,6 +6,10 @@ | |||
6 | extern "C" { | 6 | extern "C" { |
7 | #endif | 7 | #endif |
8 | 8 | ||
9 | // forward declare | ||
10 | |||
11 | typedef struct _THEME THEME; | ||
12 | |||
9 | #define ReleaseTheme(p) if (p) { ThemeFree(p); p = NULL; } | 13 | #define ReleaseTheme(p) if (p) { ThemeFree(p); p = NULL; } |
10 | 14 | ||
11 | typedef HRESULT(CALLBACK *PFNTHM_EVALUATE_VARIABLE_CONDITION)( | 15 | typedef HRESULT(CALLBACK *PFNTHM_EVALUATE_VARIABLE_CONDITION)( |
@@ -111,6 +115,10 @@ typedef enum _WM_THMUTIL | |||
111 | // wparam is THEME_CONTROLWMNOTIFY_ARGS* and lparam is THEME_CONTROLWMNOTIFY_RESULTS*. | 115 | // wparam is THEME_CONTROLWMNOTIFY_ARGS* and lparam is THEME_CONTROLWMNOTIFY_RESULTS*. |
112 | // Return code is TRUE to prevent further processing of the message. | 116 | // Return code is TRUE to prevent further processing of the message. |
113 | WM_THMUTIL_CONTROL_WM_NOTIFY = WM_APP - 3, | 117 | WM_THMUTIL_CONTROL_WM_NOTIFY = WM_APP - 3, |
118 | // Sent after created a control. | ||
119 | // wparam is THEME_LOADEDCONTROL_ARGS* and lparam is THEME_LOADEDCONTROL_RESULTS*. | ||
120 | // Return code is TRUE if it was processed. | ||
121 | WM_THMUTIL_LOADED_CONTROL = WM_APP - 4, | ||
114 | } WM_THMUTIL; | 122 | } WM_THMUTIL; |
115 | 123 | ||
116 | struct THEME_COLUMN | 124 | struct THEME_COLUMN |
@@ -287,6 +295,7 @@ struct THEME_CONTROL | |||
287 | // state variables that should be ignored | 295 | // state variables that should be ignored |
288 | HWND hWnd; | 296 | HWND hWnd; |
289 | DWORD dwData; // type specific data | 297 | DWORD dwData; // type specific data |
298 | THEME* pTheme; | ||
290 | }; | 299 | }; |
291 | 300 | ||
292 | 301 | ||
@@ -340,7 +349,7 @@ struct THEME_FONT | |||
340 | }; | 349 | }; |
341 | 350 | ||
342 | 351 | ||
343 | struct THEME | 352 | typedef struct _THEME |
344 | { | 353 | { |
345 | WORD wNextControlId; | 354 | WORD wNextControlId; |
346 | 355 | ||
@@ -403,7 +412,7 @@ struct THEME | |||
403 | PFNTHM_SET_VARIABLE_STRING pfnSetStringVariable; | 412 | PFNTHM_SET_VARIABLE_STRING pfnSetStringVariable; |
404 | 413 | ||
405 | LPVOID pvVariableContext; | 414 | LPVOID pvVariableContext; |
406 | }; | 415 | } THEME; |
407 | 416 | ||
408 | typedef struct _THEME_CONTROLWMCOMMAND_ARGS | 417 | typedef struct _THEME_CONTROLWMCOMMAND_ARGS |
409 | { | 418 | { |
@@ -431,6 +440,18 @@ typedef struct _THEME_CONTROLWMNOTIFY_RESULTS | |||
431 | LRESULT lResult; | 440 | LRESULT lResult; |
432 | } THEME_CONTROLWMNOTIFY_RESULTS; | 441 | } THEME_CONTROLWMNOTIFY_RESULTS; |
433 | 442 | ||
443 | typedef struct _THEME_LOADEDCONTROL_ARGS | ||
444 | { | ||
445 | DWORD cbSize; | ||
446 | const THEME_CONTROL* pThemeControl; | ||
447 | } THEME_LOADEDCONTROL_ARGS; | ||
448 | |||
449 | typedef struct _THEME_LOADEDCONTROL_RESULTS | ||
450 | { | ||
451 | DWORD cbSize; | ||
452 | HRESULT hr; | ||
453 | } THEME_LOADEDCONTROL_RESULTS; | ||
454 | |||
434 | typedef struct _THEME_LOADINGCONTROL_ARGS | 455 | typedef struct _THEME_LOADINGCONTROL_ARGS |
435 | { | 456 | { |
436 | DWORD cbSize; | 457 | DWORD cbSize; |
@@ -528,24 +549,6 @@ HRESULT DAPI ThemeCreateParentWindow( | |||
528 | ); | 549 | ); |
529 | 550 | ||
530 | /******************************************************************** | 551 | /******************************************************************** |
531 | ThemeLoadControls - creates the windows for all the theme controls | ||
532 | using the window created in ThemeCreateParentWindow. | ||
533 | |||
534 | *******************************************************************/ | ||
535 | HRESULT DAPI ThemeLoadControls( | ||
536 | __in THEME* pTheme | ||
537 | ); | ||
538 | |||
539 | /******************************************************************** | ||
540 | ThemeUnloadControls - resets all the theme control windows so the theme | ||
541 | controls can be reloaded. | ||
542 | |||
543 | *******************************************************************/ | ||
544 | void DAPI ThemeUnloadControls( | ||
545 | __in THEME* pTheme | ||
546 | ); | ||
547 | |||
548 | /******************************************************************** | ||
549 | ThemeLocalize - Localizes all of the strings in the theme. | 552 | ThemeLocalize - Localizes all of the strings in the theme. |
550 | 553 | ||
551 | *******************************************************************/ | 554 | *******************************************************************/ |
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index a3c5d80c..068638f6 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp | |||
@@ -205,6 +205,7 @@ static HRESULT ParseControl( | |||
205 | __in_opt THEME_PAGE* pPage | 205 | __in_opt THEME_PAGE* pPage |
206 | ); | 206 | ); |
207 | static void InitializeThemeControl( | 207 | static void InitializeThemeControl( |
208 | THEME* pTheme, | ||
208 | THEME_CONTROL* pControl | 209 | THEME_CONTROL* pControl |
209 | ); | 210 | ); |
210 | static HRESULT ParseActions( | 211 | static HRESULT ParseActions( |
@@ -273,6 +274,12 @@ static HRESULT FindImageList( | |||
273 | __in_z LPCWSTR wzImageListName, | 274 | __in_z LPCWSTR wzImageListName, |
274 | __out HIMAGELIST *phImageList | 275 | __out HIMAGELIST *phImageList |
275 | ); | 276 | ); |
277 | static HRESULT LoadThemeControls( | ||
278 | __in THEME* pTheme | ||
279 | ); | ||
280 | static void UnloadThemeControls( | ||
281 | __in THEME* pTheme | ||
282 | ); | ||
276 | static HRESULT OnLoadingControl( | 283 | static HRESULT OnLoadingControl( |
277 | __in THEME* pTheme, | 284 | __in THEME* pTheme, |
278 | __in const THEME_CONTROL* pControl, | 285 | __in const THEME_CONTROL* pControl, |
@@ -452,6 +459,10 @@ static BOOL OnNotifyEnMsgFilter( | |||
452 | __in const THEME_CONTROL* pThemeControl, | 459 | __in const THEME_CONTROL* pThemeControl, |
453 | __in MSGFILTER* msgFilter | 460 | __in MSGFILTER* msgFilter |
454 | ); | 461 | ); |
462 | static BOOL OnPanelCreate( | ||
463 | __in THEME_CONTROL* pControl, | ||
464 | __in HWND hWnd | ||
465 | ); | ||
455 | static BOOL OnWmCommand( | 466 | static BOOL OnWmCommand( |
456 | __in THEME* pTheme, | 467 | __in THEME* pTheme, |
457 | __in WPARAM wParam, | 468 | __in WPARAM wParam, |
@@ -888,35 +899,6 @@ LExit: | |||
888 | return hr; | 899 | return hr; |
889 | } | 900 | } |
890 | 901 | ||
891 | |||
892 | DAPI_(HRESULT) ThemeLoadControls( | ||
893 | __in THEME* pTheme | ||
894 | ) | ||
895 | { | ||
896 | HRESULT hr = S_OK; | ||
897 | |||
898 | if (!pTheme->hwndParent) | ||
899 | { | ||
900 | ThmExitOnFailure(hr = E_INVALIDSTATE, "ThemeLoadControls called before theme parent window created."); | ||
901 | } | ||
902 | |||
903 | hr = LoadControls(pTheme, NULL); | ||
904 | |||
905 | LExit: | ||
906 | return hr; | ||
907 | } | ||
908 | |||
909 | |||
910 | DAPI_(void) ThemeUnloadControls( | ||
911 | __in THEME* pTheme | ||
912 | ) | ||
913 | { | ||
914 | UnloadControls(pTheme->cControls, pTheme->rgControls); | ||
915 | |||
916 | pTheme->hwndHover = NULL; | ||
917 | pTheme->hwndParent = NULL; | ||
918 | } | ||
919 | |||
920 | DAPI_(HRESULT) ThemeLocalize( | 902 | DAPI_(HRESULT) ThemeLocalize( |
921 | __in THEME *pTheme, | 903 | __in THEME *pTheme, |
922 | __in const WIX_LOCALIZATION *pWixLoc | 904 | __in const WIX_LOCALIZATION *pWixLoc |
@@ -1089,6 +1071,17 @@ extern "C" LRESULT CALLBACK ThemeDefWindowProc( | |||
1089 | } | 1071 | } |
1090 | break; | 1072 | break; |
1091 | 1073 | ||
1074 | case WM_CREATE: | ||
1075 | if (FAILED(LoadThemeControls(pTheme))) | ||
1076 | { | ||
1077 | return -1; | ||
1078 | } | ||
1079 | break; | ||
1080 | |||
1081 | case WM_DESTROY: | ||
1082 | UnloadThemeControls(pTheme); | ||
1083 | break; | ||
1084 | |||
1092 | case WM_NCHITTEST: | 1085 | case WM_NCHITTEST: |
1093 | if (pTheme->dwStyle & WS_POPUP) | 1086 | if (pTheme->dwStyle & WS_POPUP) |
1094 | { | 1087 | { |
@@ -3406,7 +3399,7 @@ static HRESULT ParseControl( | |||
3406 | BOOL fAnyTextChildren = FALSE; | 3399 | BOOL fAnyTextChildren = FALSE; |
3407 | BOOL fAnyNoteChildren = FALSE; | 3400 | BOOL fAnyNoteChildren = FALSE; |
3408 | 3401 | ||
3409 | InitializeThemeControl(pControl); | 3402 | InitializeThemeControl(pTheme, pControl); |
3410 | 3403 | ||
3411 | hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName); | 3404 | hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName); |
3412 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control Name attribute."); | 3405 | ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control Name attribute."); |
@@ -3715,6 +3708,7 @@ LExit: | |||
3715 | } | 3708 | } |
3716 | 3709 | ||
3717 | static void InitializeThemeControl( | 3710 | static void InitializeThemeControl( |
3711 | THEME* pTheme, | ||
3718 | THEME_CONTROL* pControl | 3712 | THEME_CONTROL* pControl |
3719 | ) | 3713 | ) |
3720 | { | 3714 | { |
@@ -3722,6 +3716,7 @@ static void InitializeThemeControl( | |||
3722 | pControl->dwFontId = THEME_INVALID_ID; | 3716 | pControl->dwFontId = THEME_INVALID_ID; |
3723 | pControl->dwFontSelectedId = THEME_INVALID_ID; | 3717 | pControl->dwFontSelectedId = THEME_INVALID_ID; |
3724 | pControl->uStringId = UINT_MAX; | 3718 | pControl->uStringId = UINT_MAX; |
3719 | pControl->pTheme = pTheme; | ||
3725 | } | 3720 | } |
3726 | 3721 | ||
3727 | 3722 | ||
@@ -3854,7 +3849,7 @@ static HRESULT ParseBillboardPanels( | |||
3854 | pControl = pParentControl->rgControls + pParentControl->cControls; | 3849 | pControl = pParentControl->rgControls + pParentControl->cControls; |
3855 | pParentControl->cControls += 1; | 3850 | pParentControl->cControls += 1; |
3856 | pControl->type = THEME_CONTROL_TYPE_PANEL; | 3851 | pControl->type = THEME_CONTROL_TYPE_PANEL; |
3857 | InitializeThemeControl(pControl); | 3852 | InitializeThemeControl(pTheme, pControl); |
3858 | 3853 | ||
3859 | if (pPage) | 3854 | if (pPage) |
3860 | { | 3855 | { |
@@ -5400,6 +5395,24 @@ static BOOL OnNotifyEnMsgFilter( | |||
5400 | return fProcessed; | 5395 | return fProcessed; |
5401 | } | 5396 | } |
5402 | 5397 | ||
5398 | static BOOL OnPanelCreate( | ||
5399 | __in THEME_CONTROL* pControl, | ||
5400 | __in HWND hWnd | ||
5401 | ) | ||
5402 | { | ||
5403 | HRESULT hr = S_OK; | ||
5404 | |||
5405 | ThmExitOnNull(pControl, hr, E_INVALIDSTATE, "Null control for OnPanelCreate"); | ||
5406 | |||
5407 | pControl->hWnd = hWnd; | ||
5408 | |||
5409 | hr = LoadControls(pControl->pTheme, pControl); | ||
5410 | ThmExitOnFailure(hr, "Failed to load panel controls."); | ||
5411 | |||
5412 | LExit: | ||
5413 | return SUCCEEDED(hr); | ||
5414 | } | ||
5415 | |||
5403 | static BOOL OnWmCommand( | 5416 | static BOOL OnWmCommand( |
5404 | __in THEME* pTheme, | 5417 | __in THEME* pTheme, |
5405 | __in WPARAM wParam, | 5418 | __in WPARAM wParam, |
@@ -6017,17 +6030,24 @@ static LRESULT CALLBACK PanelWndProc( | |||
6017 | ) | 6030 | ) |
6018 | { | 6031 | { |
6019 | LRESULT lres = 0; | 6032 | LRESULT lres = 0; |
6020 | THEME* pTheme = reinterpret_cast<THEME*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); | 6033 | THEME_CONTROL* pControl = reinterpret_cast<THEME_CONTROL*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); |
6021 | 6034 | ||
6022 | switch (uMsg) | 6035 | switch (uMsg) |
6023 | { | 6036 | { |
6024 | case WM_NCCREATE: | 6037 | case WM_NCCREATE: |
6025 | { | 6038 | { |
6026 | LPCREATESTRUCTW lpcs = reinterpret_cast<LPCREATESTRUCTW>(lParam); | 6039 | LPCREATESTRUCTW lpcs = reinterpret_cast<LPCREATESTRUCTW>(lParam); |
6027 | pTheme = reinterpret_cast<THEME*>(lpcs->lpCreateParams); | 6040 | pControl = reinterpret_cast<THEME_CONTROL*>(lpcs->lpCreateParams); |
6028 | ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pTheme)); | 6041 | ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pControl)); |
6042 | break; | ||
6029 | } | 6043 | } |
6030 | break; | 6044 | |
6045 | case WM_CREATE: | ||
6046 | if (!OnPanelCreate(pControl, hWnd)) | ||
6047 | { | ||
6048 | return -1; | ||
6049 | } | ||
6050 | break; | ||
6031 | 6051 | ||
6032 | case WM_NCDESTROY: | 6052 | case WM_NCDESTROY: |
6033 | lres = ::DefWindowProcW(hWnd, uMsg, wParam, lParam); | 6053 | lres = ::DefWindowProcW(hWnd, uMsg, wParam, lParam); |
@@ -6039,7 +6059,7 @@ static LRESULT CALLBACK PanelWndProc( | |||
6039 | break; | 6059 | break; |
6040 | } | 6060 | } |
6041 | 6061 | ||
6042 | return ControlGroupDefWindowProc(pTheme, hWnd, uMsg, wParam, lParam); | 6062 | return ControlGroupDefWindowProc(pControl ? pControl->pTheme : NULL, hWnd, uMsg, wParam, lParam); |
6043 | } | 6063 | } |
6044 | 6064 | ||
6045 | static LRESULT CALLBACK StaticOwnerDrawWndProc( | 6065 | static LRESULT CALLBACK StaticOwnerDrawWndProc( |
@@ -6087,6 +6107,30 @@ static HRESULT OnLoadingControl( | |||
6087 | return hr; | 6107 | return hr; |
6088 | } | 6108 | } |
6089 | 6109 | ||
6110 | static HRESULT LoadThemeControls( | ||
6111 | __in THEME* pTheme | ||
6112 | ) | ||
6113 | { | ||
6114 | HRESULT hr = S_OK; | ||
6115 | |||
6116 | ThmExitOnNull(pTheme->hwndParent, hr, E_INVALIDSTATE, "LoadThemeControls called before theme parent window created."); | ||
6117 | |||
6118 | hr = LoadControls(pTheme, NULL); | ||
6119 | |||
6120 | LExit: | ||
6121 | return hr; | ||
6122 | } | ||
6123 | |||
6124 | static void UnloadThemeControls( | ||
6125 | __in THEME* pTheme | ||
6126 | ) | ||
6127 | { | ||
6128 | UnloadControls(pTheme->cControls, pTheme->rgControls); | ||
6129 | |||
6130 | pTheme->hwndHover = NULL; | ||
6131 | pTheme->hwndParent = NULL; | ||
6132 | } | ||
6133 | |||
6090 | static HRESULT LoadControls( | 6134 | static HRESULT LoadControls( |
6091 | __in THEME* pTheme, | 6135 | __in THEME* pTheme, |
6092 | __in_opt THEME_CONTROL* pParentControl | 6136 | __in_opt THEME_CONTROL* pParentControl |
@@ -6103,10 +6147,15 @@ static HRESULT LoadControls( | |||
6103 | int h = 0; | 6147 | int h = 0; |
6104 | int x = 0; | 6148 | int x = 0; |
6105 | int y = 0; | 6149 | int y = 0; |
6150 | THEME_LOADEDCONTROL_ARGS loadedControlArgs = { }; | ||
6151 | THEME_LOADEDCONTROL_RESULTS loadedControlResults = { }; | ||
6106 | 6152 | ||
6107 | GetControls(pTheme, pParentControl, cControls, rgControls); | 6153 | GetControls(pTheme, pParentControl, cControls, rgControls); |
6108 | ::GetClientRect(hwndParent, &rcParent); | 6154 | ::GetClientRect(hwndParent, &rcParent); |
6109 | 6155 | ||
6156 | loadedControlArgs.cbSize = sizeof(loadedControlArgs); | ||
6157 | loadedControlResults.cbSize = sizeof(loadedControlResults); | ||
6158 | |||
6110 | for (DWORD i = 0; i < cControls; ++i) | 6159 | for (DWORD i = 0; i < cControls; ++i) |
6111 | { | 6160 | { |
6112 | THEME_CONTROL* pControl = rgControls + i; | 6161 | THEME_CONTROL* pControl = rgControls + i; |
@@ -6124,8 +6173,7 @@ static HRESULT LoadControls( | |||
6124 | 6173 | ||
6125 | switch (pControl->type) | 6174 | switch (pControl->type) |
6126 | { | 6175 | { |
6127 | case THEME_CONTROL_TYPE_BILLBOARD: | 6176 | case THEME_CONTROL_TYPE_BILLBOARD: __fallthrough; |
6128 | __fallthrough; | ||
6129 | case THEME_CONTROL_TYPE_PANEL: | 6177 | case THEME_CONTROL_TYPE_PANEL: |
6130 | wzWindowClass = vsczPanelClass; | 6178 | wzWindowClass = vsczPanelClass; |
6131 | dwWindowExBits |= WS_EX_CONTROLPARENT; | 6179 | dwWindowExBits |= WS_EX_CONTROLPARENT; |
@@ -6309,7 +6357,7 @@ static HRESULT LoadControls( | |||
6309 | pControl->dwStyle &= ~WS_VISIBLE; | 6357 | pControl->dwStyle &= ~WS_VISIBLE; |
6310 | } | 6358 | } |
6311 | 6359 | ||
6312 | pControl->hWnd = ::CreateWindowExW(dwWindowExBits, wzWindowClass, pControl->sczText, pControl->dwStyle | dwWindowBits, x, y, w, h, hwndParent, reinterpret_cast<HMENU>(wControlId), NULL, pTheme); | 6360 | pControl->hWnd = ::CreateWindowExW(dwWindowExBits, wzWindowClass, pControl->sczText, pControl->dwStyle | dwWindowBits, x, y, w, h, hwndParent, reinterpret_cast<HMENU>(wControlId), NULL, pControl); |
6313 | ThmExitOnNullWithLastError(pControl->hWnd, hr, "Failed to create window."); | 6361 | ThmExitOnNullWithLastError(pControl->hWnd, hr, "Failed to create window."); |
6314 | 6362 | ||
6315 | if (pControl->sczTooltip) | 6363 | if (pControl->sczTooltip) |
@@ -6445,10 +6493,15 @@ static HRESULT LoadControls( | |||
6445 | } | 6493 | } |
6446 | } | 6494 | } |
6447 | 6495 | ||
6448 | if (pControl->cControls) | 6496 | loadedControlArgs.pThemeControl = pControl; |
6497 | loadedControlResults.hr = E_NOTIMPL; | ||
6498 | if (::SendMessageW(pTheme->hwndParent, WM_THMUTIL_LOADED_CONTROL, reinterpret_cast<WPARAM>(&loadedControlArgs), reinterpret_cast<LPARAM>(&loadedControlResults))) | ||
6449 | { | 6499 | { |
6450 | hr = LoadControls(pTheme, pControl); | 6500 | if (E_NOTIMPL != loadedControlResults.hr) |
6451 | ThmExitOnFailure(hr, "Failed to load child controls."); | 6501 | { |
6502 | hr = loadedControlResults.hr; | ||
6503 | ThmExitOnFailure(hr, "ThmLoadedControl failed"); | ||
6504 | } | ||
6452 | } | 6505 | } |
6453 | } | 6506 | } |
6454 | 6507 | ||
diff --git a/src/samples/thmviewer/display.cpp b/src/samples/thmviewer/display.cpp index c0e6c7e1..e64f79c6 100644 --- a/src/samples/thmviewer/display.cpp +++ b/src/samples/thmviewer/display.cpp | |||
@@ -21,9 +21,10 @@ static LRESULT CALLBACK DisplayWndProc( | |||
21 | __in WPARAM wParam, | 21 | __in WPARAM wParam, |
22 | __in LPARAM lParam | 22 | __in LPARAM lParam |
23 | ); | 23 | ); |
24 | static BOOL DisplayOnCreate( | 24 | static BOOL DisplayOnThmLoadedControl( |
25 | __in THEME* pTheme, | 25 | __in THEME* pTheme, |
26 | __in HWND hWnd | 26 | __in const THEME_LOADEDCONTROL_ARGS* args, |
27 | __in THEME_LOADEDCONTROL_RESULTS* results | ||
27 | ); | 28 | ); |
28 | 29 | ||
29 | 30 | ||
@@ -270,13 +271,6 @@ static LRESULT CALLBACK DisplayWndProc( | |||
270 | } | 271 | } |
271 | break; | 272 | break; |
272 | 273 | ||
273 | case WM_CREATE: | ||
274 | if (!DisplayOnCreate(pHandleTheme->pTheme, hWnd)) | ||
275 | { | ||
276 | return -1; | ||
277 | } | ||
278 | break; | ||
279 | |||
280 | case WM_TIMER: | 274 | case WM_TIMER: |
281 | if (!lParam && SUCCEEDED(ThemeSetProgressControl(pHandleTheme->pTheme, wParam, dwProgress))) | 275 | if (!lParam && SUCCEEDED(ThemeSetProgressControl(pHandleTheme->pTheme, wParam, dwProgress))) |
282 | { | 276 | { |
@@ -308,47 +302,45 @@ static LRESULT CALLBACK DisplayWndProc( | |||
308 | } | 302 | } |
309 | break; | 303 | break; |
310 | 304 | ||
311 | case WM_DESTROY: | ||
312 | ThemeUnloadControls(pHandleTheme->pTheme); | ||
313 | ::PostQuitMessage(0); | ||
314 | break; | ||
315 | |||
316 | case WM_NCDESTROY: | 305 | case WM_NCDESTROY: |
317 | DecrementHandleTheme(pHandleTheme); | 306 | DecrementHandleTheme(pHandleTheme); |
318 | ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); | 307 | ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); |
308 | ::PostQuitMessage(0); | ||
319 | break; | 309 | break; |
310 | |||
311 | case WM_THMUTIL_LOADED_CONTROL: | ||
312 | if (pHandleTheme) | ||
313 | { | ||
314 | return DisplayOnThmLoadedControl(pHandleTheme->pTheme, reinterpret_cast<THEME_LOADEDCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADEDCONTROL_RESULTS*>(lParam)); | ||
315 | } | ||
320 | } | 316 | } |
321 | 317 | ||
322 | return ThemeDefWindowProc(pHandleTheme ? pHandleTheme->pTheme : NULL, hWnd, uMsg, wParam, lParam); | 318 | return ThemeDefWindowProc(pHandleTheme ? pHandleTheme->pTheme : NULL, hWnd, uMsg, wParam, lParam); |
323 | } | 319 | } |
324 | 320 | ||
325 | static BOOL DisplayOnCreate( | 321 | static BOOL DisplayOnThmLoadedControl( |
326 | __in THEME* pTheme, | 322 | __in THEME* pTheme, |
327 | __in HWND hWnd | 323 | __in const THEME_LOADEDCONTROL_ARGS* args, |
324 | __in THEME_LOADEDCONTROL_RESULTS* results | ||
328 | ) | 325 | ) |
329 | { | 326 | { |
330 | HRESULT hr = S_OK; | 327 | HRESULT hr = S_OK; |
331 | 328 | const THEME_CONTROL* pControl = args->pThemeControl; | |
332 | hr = ThemeLoadControls(pTheme); | ||
333 | ExitOnFailure(hr, "Failed to load theme controls"); | ||
334 | 329 | ||
335 | // Pre-populate some control types with data. | 330 | // Pre-populate some control types with data. |
336 | for (DWORD i = 0; i < pTheme->cControls; ++i) | 331 | if (THEME_CONTROL_TYPE_RICHEDIT == pControl->type) |
337 | { | 332 | { |
338 | THEME_CONTROL* pControl = pTheme->rgControls + i; | 333 | hr = ThemeLoadRichEditFromResource(pTheme, pControl->wId, MAKEINTRESOURCEA(THMVWR_RES_RICHEDIT_FILE), ::GetModuleHandleW(NULL)); |
339 | if (THEME_CONTROL_TYPE_RICHEDIT == pControl->type) | 334 | ExitOnFailure(hr, "Failed to load richedit text."); |
340 | { | 335 | } |
341 | hr = ThemeLoadRichEditFromResource(pTheme, pControl->wId, MAKEINTRESOURCEA(THMVWR_RES_RICHEDIT_FILE), ::GetModuleHandleW(NULL)); | 336 | else if (THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) |
342 | ExitOnFailure(hr, "Failed to load richedit text."); | 337 | { |
343 | } | 338 | DWORD dwId = ::SetTimer(pTheme->hwndParent, pControl->wId, 500, NULL); |
344 | else if (THEME_CONTROL_TYPE_PROGRESSBAR == pControl->type) | 339 | dwId = dwId; // prevents warning in "ship" build. |
345 | { | 340 | Assert(dwId == pControl->wId); |
346 | DWORD dwId = ::SetTimer(hWnd, pControl->wId, 500, NULL); | ||
347 | dwId = dwId; // prevents warning in "ship" build. | ||
348 | Assert(dwId == pControl->wId); | ||
349 | } | ||
350 | } | 341 | } |
351 | 342 | ||
352 | LExit: | 343 | LExit: |
353 | return SUCCEEDED(hr); | 344 | results->hr = hr; |
345 | return TRUE; | ||
354 | } | 346 | } |
diff --git a/src/samples/thmviewer/thmviewer.cpp b/src/samples/thmviewer/thmviewer.cpp index e593d6ad..1d941323 100644 --- a/src/samples/thmviewer/thmviewer.cpp +++ b/src/samples/thmviewer/thmviewer.cpp | |||
@@ -353,16 +353,7 @@ static LRESULT CALLBACK MainWndProc( | |||
353 | case WM_NCDESTROY: | 353 | case WM_NCDESTROY: |
354 | DecrementHandleTheme(pHandleTheme); | 354 | DecrementHandleTheme(pHandleTheme); |
355 | ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); | 355 | ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); |
356 | break; | 356 | ::PostQuitMessage(0); |
357 | |||
358 | case WM_CREATE: | ||
359 | { | ||
360 | HRESULT hr = ThemeLoadControls(vpTheme); | ||
361 | if (FAILED(hr)) | ||
362 | { | ||
363 | return -1; | ||
364 | } | ||
365 | } | ||
366 | break; | 357 | break; |
367 | 358 | ||
368 | case WM_THMVWR_THEME_LOAD_BEGIN: | 359 | case WM_THMVWR_THEME_LOAD_BEGIN: |
@@ -377,10 +368,6 @@ static LRESULT CALLBACK MainWndProc( | |||
377 | OnNewTheme(vpTheme, hWnd, reinterpret_cast<HANDLE_THEME*>(lParam)); | 368 | OnNewTheme(vpTheme, hWnd, reinterpret_cast<HANDLE_THEME*>(lParam)); |
378 | return 0; | 369 | return 0; |
379 | 370 | ||
380 | case WM_DESTROY: | ||
381 | ::PostQuitMessage(0); | ||
382 | break; | ||
383 | |||
384 | case WM_THMUTIL_LOADING_CONTROL: | 371 | case WM_THMUTIL_LOADING_CONTROL: |
385 | return OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); | 372 | return OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); |
386 | 373 | ||
diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp index a5bcba3e..8304403a 100644 --- a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp | |||
@@ -230,18 +230,14 @@ private: | |||
230 | return lres; | 230 | return lres; |
231 | } | 231 | } |
232 | 232 | ||
233 | case WM_CREATE: | ||
234 | if (!pBaf->OnCreate(hWnd)) | ||
235 | { | ||
236 | return -1; | ||
237 | } | ||
238 | break; | ||
239 | |||
240 | case WM_THMUTIL_LOADING_CONTROL: | 233 | case WM_THMUTIL_LOADING_CONTROL: |
241 | return pBaf->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); | 234 | return pBaf->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); |
242 | 235 | ||
236 | case WM_THMUTIL_LOADED_CONTROL: | ||
237 | return pBaf->OnThemeLoadedControl(hWnd, reinterpret_cast<THEME_LOADEDCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADEDCONTROL_RESULTS*>(lParam)); | ||
238 | |||
243 | case WM_TIMER: | 239 | case WM_TIMER: |
244 | if (!lParam && pBaf) | 240 | if (!lParam && BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE == wParam && pBaf) |
245 | { | 241 | { |
246 | pBaf->UpdateProgressBarProgress(); | 242 | pBaf->UpdateProgressBarProgress(); |
247 | 243 | ||
@@ -253,33 +249,14 @@ private: | |||
253 | return ThemeDefWindowProc(pBaf ? pBaf->m_pBafTheme : NULL, hWnd, uMsg, wParam, lParam); | 249 | return ThemeDefWindowProc(pBaf ? pBaf->m_pBafTheme : NULL, hWnd, uMsg, wParam, lParam); |
254 | } | 250 | } |
255 | 251 | ||
256 | BOOL OnCreate( | 252 | HRESULT OnCreatedListView( |
257 | __in HWND hWnd | 253 | __in HWND hWndListView |
258 | ) | 254 | ) |
259 | { | 255 | { |
260 | HRESULT hr = S_OK; | 256 | HRESULT hr = S_OK; |
261 | LVITEMW lvitem = { }; | 257 | LVITEMW lvitem = { }; |
262 | LVGROUP lvgroup = { }; | 258 | LVGROUP lvgroup = { }; |
263 | static UINT puColumns[] = { 0, 1, 2 }; | 259 | static UINT puColumns[] = { 0, 1, 2 }; |
264 | HWND hwndTopLeft = NULL; | ||
265 | HWND hwndTopRight = NULL; | ||
266 | HWND hwndBottomLeft = NULL; | ||
267 | HWND hwndBottomRight = NULL; | ||
268 | |||
269 | hr = ThemeLoadControls(m_pBafTheme); | ||
270 | BalExitOnFailure(hr, "Failed to load theme controls."); | ||
271 | |||
272 | hwndTopLeft = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT); | ||
273 | BalExitOnNull(hwndTopLeft, hr, E_INVALIDSTATE, "Failed to get top left list view hWnd."); | ||
274 | |||
275 | hwndTopRight = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_RIGHT); | ||
276 | BalExitOnNull(hwndTopRight, hr, E_INVALIDSTATE, "Failed to get top right list view hWnd."); | ||
277 | |||
278 | hwndBottomLeft = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_LEFT); | ||
279 | BalExitOnNull(hwndBottomLeft, hr, E_INVALIDSTATE, "Failed to get bottom left list view hWnd."); | ||
280 | |||
281 | hwndBottomRight = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_RIGHT); | ||
282 | BalExitOnNull(hwndBottomRight, hr, E_INVALIDSTATE, "Failed to get bottom right list view hWnd."); | ||
283 | 260 | ||
284 | lvgroup.cbSize = sizeof(LVGROUP); | 261 | lvgroup.cbSize = sizeof(LVGROUP); |
285 | lvgroup.mask = LVGF_GROUPID | LVGF_TITLEIMAGE | LVGF_DESCRIPTIONTOP | LVGF_HEADER; | 262 | lvgroup.mask = LVGF_GROUPID | LVGF_TITLEIMAGE | LVGF_DESCRIPTIONTOP | LVGF_HEADER; |
@@ -295,10 +272,7 @@ private: | |||
295 | hr = StrAllocFormatted(&lvgroup.pszHeader, L"Header_%d", i); | 272 | hr = StrAllocFormatted(&lvgroup.pszHeader, L"Header_%d", i); |
296 | BalExitOnFailure(hr, "Failed to alloc list view group header."); | 273 | BalExitOnFailure(hr, "Failed to alloc list view group header."); |
297 | 274 | ||
298 | ListView_InsertGroup(hwndTopLeft, -1, &lvgroup); | 275 | ListView_InsertGroup(hWndListView, -1, &lvgroup); |
299 | ListView_InsertGroup(hwndTopRight, -1, &lvgroup); | ||
300 | ListView_InsertGroup(hwndBottomLeft, -1, &lvgroup); | ||
301 | ListView_InsertGroup(hwndBottomRight, -1, &lvgroup); | ||
302 | 276 | ||
303 | lvitem.mask = LVIF_COLUMNS | LVIF_GROUPID | LVIF_IMAGE | LVIF_TEXT; | 277 | lvitem.mask = LVIF_COLUMNS | LVIF_GROUPID | LVIF_IMAGE | LVIF_TEXT; |
304 | lvitem.iItem = i; | 278 | lvitem.iItem = i; |
@@ -312,10 +286,7 @@ private: | |||
312 | lvitem.cColumns = countof(puColumns); | 286 | lvitem.cColumns = countof(puColumns); |
313 | lvitem.puColumns = puColumns; | 287 | lvitem.puColumns = puColumns; |
314 | 288 | ||
315 | ListView_InsertItem(hwndTopLeft, &lvitem); | 289 | ListView_InsertItem(hWndListView, &lvitem); |
316 | ListView_InsertItem(hwndTopRight, &lvitem); | ||
317 | ListView_InsertItem(hwndBottomLeft, &lvitem); | ||
318 | ListView_InsertItem(hwndBottomRight, &lvitem); | ||
319 | 290 | ||
320 | for (int j = 0; j < 3; ++j) | 291 | for (int j = 0; j < 3; ++j) |
321 | { | 292 | { |
@@ -325,23 +296,16 @@ private: | |||
325 | hr = StrAllocFormatted(&lvitem.pszText, L"%d_%d", j, i); | 296 | hr = StrAllocFormatted(&lvitem.pszText, L"%d_%d", j, i); |
326 | BalExitOnFailure(hr, "Failed to alloc list view subitem text."); | 297 | BalExitOnFailure(hr, "Failed to alloc list view subitem text."); |
327 | 298 | ||
328 | ListView_InsertItem(hwndTopLeft, &lvitem); | 299 | ListView_InsertItem(hWndListView, &lvitem); |
329 | ListView_InsertItem(hwndTopRight, &lvitem); | ||
330 | ListView_InsertItem(hwndBottomLeft, &lvitem); | ||
331 | ListView_InsertItem(hwndBottomRight, &lvitem); | ||
332 | } | 300 | } |
333 | } | 301 | } |
334 | 302 | ||
335 | ListView_EnableGroupView(hwndTopRight, TRUE); | ||
336 | |||
337 | ::SetTimer(hWnd, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, 500, NULL); | ||
338 | |||
339 | LExit: | 303 | LExit: |
340 | ReleaseStr(lvgroup.pszDescriptionTop); | 304 | ReleaseStr(lvgroup.pszDescriptionTop); |
341 | ReleaseStr(lvgroup.pszHeader); | 305 | ReleaseStr(lvgroup.pszHeader); |
342 | ReleaseStr(lvitem.pszText); | 306 | ReleaseStr(lvitem.pszText); |
343 | 307 | ||
344 | return SUCCEEDED(hr); | 308 | return hr; |
345 | } | 309 | } |
346 | 310 | ||
347 | BOOL OnThemeLoadingControl( | 311 | BOOL OnThemeLoadingControl( |
@@ -349,17 +313,60 @@ private: | |||
349 | __in THEME_LOADINGCONTROL_RESULTS* pResults | 313 | __in THEME_LOADINGCONTROL_RESULTS* pResults |
350 | ) | 314 | ) |
351 | { | 315 | { |
316 | HRESULT hr = S_OK; | ||
317 | BOOL fProcessed = FALSE; | ||
318 | |||
352 | for (DWORD iAssignControl = 0; iAssignControl < countof(vrgInitControls); ++iAssignControl) | 319 | for (DWORD iAssignControl = 0; iAssignControl < countof(vrgInitControls); ++iAssignControl) |
353 | { | 320 | { |
354 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, vrgInitControls[iAssignControl].wzName, -1)) | 321 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, vrgInitControls[iAssignControl].wzName, -1)) |
355 | { | 322 | { |
323 | fProcessed = TRUE; | ||
356 | pResults->wId = vrgInitControls[iAssignControl].wId; | 324 | pResults->wId = vrgInitControls[iAssignControl].wId; |
357 | break; | 325 | break; |
358 | } | 326 | } |
359 | } | 327 | } |
360 | 328 | ||
361 | pResults->hr = S_OK; | 329 | pResults->hr = hr; |
362 | return TRUE; | 330 | return fProcessed || FAILED(hr); |
331 | } | ||
332 | |||
333 | BOOL OnThemeLoadedControl( | ||
334 | __in HWND hWndParent, | ||
335 | __in const THEME_LOADEDCONTROL_ARGS* pArgs, | ||
336 | __in THEME_LOADEDCONTROL_RESULTS* pResults | ||
337 | ) | ||
338 | { | ||
339 | HRESULT hr = S_OK; | ||
340 | BOOL fProcessed = FALSE; | ||
341 | |||
342 | switch (pArgs->pThemeControl->wId) | ||
343 | { | ||
344 | case BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT: | ||
345 | case BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_RIGHT: | ||
346 | case BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_LEFT: | ||
347 | case BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_RIGHT: | ||
348 | fProcessed = TRUE; | ||
349 | |||
350 | hr = OnCreatedListView(pArgs->pThemeControl->hWnd); | ||
351 | ExitOnFailure(hr, "Failed to populate list view."); | ||
352 | |||
353 | if (BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_RIGHT == pArgs->pThemeControl->wId) | ||
354 | { | ||
355 | ListView_EnableGroupView(pArgs->pThemeControl->hWnd, TRUE); | ||
356 | } | ||
357 | |||
358 | break; | ||
359 | |||
360 | case BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD: | ||
361 | fProcessed = TRUE; | ||
362 | |||
363 | ::SetTimer(hWndParent, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, 500, NULL); | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | LExit: | ||
368 | pResults->hr = hr; | ||
369 | return fProcessed || FAILED(hr); | ||
363 | } | 370 | } |
364 | 371 | ||
365 | void UpdateProgressBarProgress() | 372 | void UpdateProgressBarProgress() |
diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingTheme.xml b/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingTheme.xml index 0d0dabf5..7491ab1c 100644 --- a/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingTheme.xml +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingTheme.xml | |||
@@ -124,6 +124,27 @@ There are currently four states for a button: default, focus, hover, and selecte | |||
124 | <Text>Back</Text> | 124 | <Text>Back</Text> |
125 | <ChangePageAction Page="Button" /> | 125 | <ChangePageAction Page="Button" /> |
126 | </Button> | 126 | </Button> |
127 | <Button Name="BillboardButton" X="-183" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
128 | <Text>Next</Text> | ||
129 | <ChangePageAction Page="Billboard" /> | ||
130 | </Button> | ||
131 | </Page> | ||
132 | <Page Name="Billboard"> | ||
133 | <Label X="6" Y="6" Width="-6" Height="43" FontId="Default"> | ||
134 | This page has a billboard. It loops between two panels every 1.5 seconds. Only one button should be visible at all times (this is currently broken). | ||
135 | </Label> | ||
136 | <Billboard Name="FirstBillboard" X="11" Y="59" Width="-11" Height="-39" Interval="1500" Loop="yes"> | ||
137 | <BillboardPanel> | ||
138 | <Button Name="FirstBillboardButton1" X="11" Y="11" Width="75" Height="23" TabStop="yes" FontId="Default">First Panel</Button> | ||
139 | </BillboardPanel> | ||
140 | <BillboardPanel> | ||
141 | <Button Name="FirstBillboardButton2" X="11" Y="39" Width="75" Height="23" TabStop="yes" FontId="Default">Second Panel</Button> | ||
142 | </BillboardPanel> | ||
143 | </Billboard> | ||
144 | <Button Name="BillboardBackButton" X="-269" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
145 | <Text>Back</Text> | ||
146 | <ChangePageAction Page="Progressbar" /> | ||
147 | </Button> | ||
127 | </Page> | 148 | </Page> |
128 | <Button Name="StartButton" X="-97" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default" Visible="yes"> | 149 | <Button Name="StartButton" X="-97" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default" Visible="yes"> |
129 | <Text>Start</Text> | 150 | <Text>Start</Text> |
diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingThemeLoose.xml b/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingThemeLoose.xml new file mode 100644 index 00000000..7e360544 --- /dev/null +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/theme/BafThmUtilTestingThemeLoose.xml | |||
@@ -0,0 +1,158 @@ | |||
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="Default" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font> | ||
7 | <Image Id="star_transparent.bmp" ImageFile="star_transparent.bmp" /> | ||
8 | <Image Id="star_opaque.bmp" ImageFile="star_opaque.bmp" /> | ||
9 | <Image Id="star_transparent.png" ImageFile="star_transparent.png" /> | ||
10 | <Image Id="square_default" ImageFile="16x16.png"> | ||
11 | <AlternateResolution ImageFile="32x32.png" /> | ||
12 | <AlternateResolution ImageFile="64x64.png" /> | ||
13 | <AlternateResolution ImageFile="128x128.png" /> | ||
14 | <AlternateResolution ImageFile="256x256.png" /> | ||
15 | </Image> | ||
16 | <Image Id="square_focus" ImageFile="64x64_focus.png"> | ||
17 | <AlternateResolution ImageFile="128x128_focus.png" /> | ||
18 | <AlternateResolution ImageFile="256x256_focus.png" /> | ||
19 | </Image> | ||
20 | <Image Id="square_hover" ImageFile="64x64_hover.png"> | ||
21 | <AlternateResolution ImageFile="128x128_hover.png" /> | ||
22 | <AlternateResolution ImageFile="256x256_hover.png" /> | ||
23 | </Image> | ||
24 | <Image Id="square_selected" ImageFile="64x64_selected.png"> | ||
25 | <AlternateResolution ImageFile="128x128_selected.png" /> | ||
26 | <AlternateResolution ImageFile="256x256_selected.png" /> | ||
27 | </Image> | ||
28 | <Image Id="progressbar" ImageFile="progressbar.bmp" /> | ||
29 | <Image Id="progressbar_reverse" ImageFile="progressbar_reverse.bmp" /> | ||
30 | |||
31 | <Window Width="600" Height="450" FontId="Default" Caption="BafThmUtilTestingTheme" HexStyle="10cf0000" AutoResize="yes"> | ||
32 | <ImageList Name="Stars"> | ||
33 | <ImageListItem ImageFile="star_transparent.bmp" /> | ||
34 | <ImageListItem ImageFile="star_opaque.bmp" /> | ||
35 | <ImageListItem ImageFile="star_transparent.png" /> | ||
36 | </ImageList> | ||
37 | <Page Name="Transparency"> | ||
38 | <Label X="6" Y="6" Width="-6" Height="94" FontId="Default"> | ||
39 | This page has three versions of an image. The top image is a bitmap with a transparent background, the yellow star should be visible but its black background should not (this is currently broken). The middle image is the same bitmap except the black background is fully opaque so the yellow star should be visible on a black background. The bottom image in a PNG version of the top image and should look exactly the same. | ||
40 | </Label> | ||
41 | <ImageControl X="6" Y="106" Width="64" Height="64" ImageId="star_transparent.bmp" /> | ||
42 | <ImageControl X="6" Y="176" Width="64" Height="64" ImageId="star_opaque.bmp" /> | ||
43 | <ImageControl X="6" Y="246" Width="64" Height="64" ImageId="star_transparent.png" /> | ||
44 | <Button Name="ListViewButton" X="-183" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
45 | <Text>Next</Text> | ||
46 | <ChangePageAction Page="ListView" /> | ||
47 | </Button> | ||
48 | </Page> | ||
49 | <Page Name="ListView"> | ||
50 | <Label X="6" Y="6" Width="-6" Height="18" FontId="Default"> | ||
51 | This page is for testing ListView. | ||
52 | </Label> | ||
53 | <ListView Name="ListViewTopLeft" X="6" Y="30" Width="288" Height="176" FontId="Default" HexStyle="00" ImageList="Stars"> | ||
54 | <Column Width="100">TL One</Column> | ||
55 | <Column Width="100">TL Two</Column> | ||
56 | <Column Width="88">TL Three</Column> | ||
57 | </ListView> | ||
58 | <ListView Name="ListViewTopRight" X="300" Y="30" Width="-11" Height="176" FontId="Default" HexStyle="01" ImageListGroupHeader="Stars"> | ||
59 | <Column Width="100">TR One</Column> | ||
60 | <Column Width="100">TR Two</Column> | ||
61 | <Column Width="88" Expands="yes">TR Exp</Column> | ||
62 | </ListView> | ||
63 | <ListView Name="ListViewBottomLeft" X="6" Y="212" Width="288" Height="176" FontId="Default" HexStyle="02" ImageListSmall="Stars"> | ||
64 | <Column Width="100">BL One</Column> | ||
65 | <Column Width="100">BL Two</Column> | ||
66 | <Column Width="88">BL Three</Column> | ||
67 | </ListView> | ||
68 | <ListView Name="ListViewBottomRight" X="300" Y="212" Width="-11" Height="176" FontId="Default" HexStyle="03"> | ||
69 | <Column Width="100">BR One</Column> | ||
70 | <Column Width="100">BR Two</Column> | ||
71 | <Column Width="88" Expands="yes">BR Exp</Column> | ||
72 | </ListView> | ||
73 | <Button Name="ListViewBackButton" X="-269" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
74 | <Text>Back</Text> | ||
75 | <ChangePageAction Page="Transparency" /> | ||
76 | </Button> | ||
77 | <Button Name="ButtonButton" X="-183" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
78 | <Text>Next</Text> | ||
79 | <ChangePageAction Page="Button" /> | ||
80 | </Button> | ||
81 | </Page> | ||
82 | <Page Name="Button"> | ||
83 | <Label X="6" Y="6" Width="-6" Height="132" FontId="Default"> | ||
84 | This page is for testing graphical buttons. The left image is 16x16 at 100% scaling, the middle image is 32x32 at 100% scaling. The images for the buttons display their dimensions, so the left should be 16x16 at 100% but 32x32 at 200%. The right button starts at 32x32 at 100%, but grows and shrinks with the window and its image should also change. | ||
85 | |||
86 | There are currently four states for a button: default, focus, hover, and selected (in that priority order). There should be a different image for each state, although the left button should have a focus rectangle over the default image since it didn't specify an image for the focused state. | ||
87 | </Label> | ||
88 | <Button Name="Square16Button" X="6" Y="140" Width="16" Height="16" FontId="Default" TabStop="yes"> | ||
89 | <ButtonImage ImageId="square_default" /> | ||
90 | <ButtonHoverImage ImageId="square_hover" /> | ||
91 | <ButtonSelectedImage ImageId="square_selected" /> | ||
92 | </Button> | ||
93 | <Button Name="Square32Button" X="54" Y="140" Width="32" Height="32" FontId="Default" TabStop="yes"> | ||
94 | <ButtonImage ImageId="square_default" /> | ||
95 | <ButtonFocusImage ImageId="square_focus" /> | ||
96 | <ButtonHoverImage ImageId="square_hover" /> | ||
97 | <ButtonSelectedImage ImageId="square_selected" /> | ||
98 | </Button> | ||
99 | <Button Name="SquareExpandButton" X="92" Y="140" Width="-476" Height="-278" FontId="Default" TabStop="yes"> | ||
100 | <ButtonImage ImageId="square_default" /> | ||
101 | <ButtonFocusImage ImageId="square_focus" /> | ||
102 | <ButtonHoverImage ImageId="square_hover" /> | ||
103 | <ButtonSelectedImage ImageId="square_selected" /> | ||
104 | </Button> | ||
105 | <Button Name="ButtonBackButton" X="-269" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
106 | <Text>Back</Text> | ||
107 | <ChangePageAction Page="ListView" /> | ||
108 | </Button> | ||
109 | <Button Name="ProgressbarButton" X="-183" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
110 | <Text>Next</Text> | ||
111 | <ChangePageAction Page="Progressbar" /> | ||
112 | </Button> | ||
113 | </Page> | ||
114 | <Page Name="Progressbar"> | ||
115 | <Label X="6" Y="6" Width="-6" Height="94" FontId="Default"> | ||
116 | This page has two progress bars. The top progress bar is a standard control, the bottom one is custom drawn from an image. The bottom one should have its left side one pixel wide as black, the right side one pixel wide as grey, the progress as green, and the remaining as blue. The colors should be reversed when the progress goes backward (this is a way to test different colors, not a standard feature of thmutil). | ||
117 | </Label> | ||
118 | <Progressbar Name="StandardProgressBar" X="6" Y="106" Width="-6" Height="23" /> | ||
119 | <Progressbar Name="ImageProgressBar" X="6" Y="141" Width="-6" Height="23"> | ||
120 | <ProgressbarImage ImageId="progressbar" /> | ||
121 | <ProgressbarImage ImageId="progressbar_reverse" /> | ||
122 | </Progressbar> | ||
123 | <Button Name="ProgressbarBackButton" X="-269" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
124 | <Text>Back</Text> | ||
125 | <ChangePageAction Page="Button" /> | ||
126 | </Button> | ||
127 | <Button Name="BillboardButton" X="-183" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
128 | <Text>Next</Text> | ||
129 | <ChangePageAction Page="Billboard" /> | ||
130 | </Button> | ||
131 | </Page> | ||
132 | <Page Name="Billboard"> | ||
133 | <Label X="6" Y="6" Width="-6" Height="43" FontId="Default"> | ||
134 | This page has a billboard. It loops between two panels every 1.5 seconds. Only one button should be visible at all times (this is currently broken). | ||
135 | </Label> | ||
136 | <Billboard Name="FirstBillboard" X="11" Y="59" Width="-11" Height="-39" Interval="1500" Loop="yes"> | ||
137 | <BillboardPanel> | ||
138 | <Button Name="FirstBillboardButton1" X="11" Y="11" Width="75" Height="23" TabStop="yes" FontId="Default">First Panel</Button> | ||
139 | </BillboardPanel> | ||
140 | <BillboardPanel> | ||
141 | <Button Name="FirstBillboardButton2" X="11" Y="39" Width="75" Height="23" TabStop="yes" FontId="Default">Second Panel</Button> | ||
142 | </BillboardPanel> | ||
143 | </Billboard> | ||
144 | <Button Name="BillboardBackButton" X="-269" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default"> | ||
145 | <Text>Back</Text> | ||
146 | <ChangePageAction Page="Progressbar" /> | ||
147 | </Button> | ||
148 | </Page> | ||
149 | <Button Name="StartButton" X="-97" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default" Visible="yes"> | ||
150 | <Text>Start</Text> | ||
151 | <ChangePageAction Page="Transparency" /> | ||
152 | </Button> | ||
153 | <Button Name="CloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="Default" Visible="yes"> | ||
154 | <Text>ThemeClose</Text> | ||
155 | <CloseWindowAction /> | ||
156 | </Button> | ||
157 | </Window> | ||
158 | </Theme> | ||