summaryrefslogtreecommitdiff
path: root/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-06-04 14:23:20 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-06-04 14:57:11 -0500
commit1d3bd04d4aca82979b08a955dc0bf61eb80f2e66 (patch)
tree2d8c998916fcf4991b33dab114d29fd44b02839b /src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
parent1f85dac530dee933457e99438fd1c82485a2a48e (diff)
downloadwix-1d3bd04d4aca82979b08a955dc0bf61eb80f2e66.tar.gz
wix-1d3bd04d4aca82979b08a955dc0bf61eb80f2e66.tar.bz2
wix-1d3bd04d4aca82979b08a955dc0bf61eb80f2e66.zip
Add a manual test bundle for testing BAFunctions and thmutil.
Diffstat (limited to 'src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp')
-rw-r--r--src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp432
1 files changed, 432 insertions, 0 deletions
diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
new file mode 100644
index 00000000..8b49cab6
--- /dev/null
+++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
@@ -0,0 +1,432 @@
1// 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.
2
3#include "precomp.h"
4#include "BalBaseBAFunctions.h"
5#include "BalBaseBAFunctionsProc.h"
6
7static const LPCWSTR BAFTHMUTILTESTING_WINDOW_CLASS = L"BafThmUtilTesting";
8
9enum BAFTHMUTILTESTING_CONTROL
10{
11 BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT = THEME_FIRST_ASSIGN_CONTROL_ID,
12 BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_RIGHT,
13 BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_LEFT,
14 BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_RIGHT,
15 BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD,
16 BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE,
17};
18
19static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = {
20 { BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT, L"ListViewTopLeft" },
21 { BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_RIGHT, L"ListViewTopRight" },
22 { BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_LEFT, L"ListViewBottomLeft" },
23 { BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_RIGHT, L"ListViewBottomRight" },
24 { BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, L"ImageProgressBar" },
25 { BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD, L"StandardProgressBar" },
26};
27
28static void CALLBACK BafThmUtilTestingTraceError(
29 __in_z LPCSTR szFile,
30 __in int iLine,
31 __in REPORT_LEVEL rl,
32 __in UINT source,
33 __in HRESULT hrError,
34 __in_z __format_string LPCSTR szFormat,
35 __in va_list args
36 );
37
38class CBafThmUtilTesting : public CBalBaseBAFunctions
39{
40public: // IBAFunctions
41 /*virtual STDMETHODIMP OnThemeLoaded(
42 THEME* pTheme,
43 WIX_LOCALIZATION* pWixLoc
44 )
45 {
46 HRESULT hr = S_OK;
47
48 hr = __super::OnThemeLoaded(pTheme, pWixLoc);
49
50 return hr;
51 }*/
52
53 virtual STDMETHODIMP WndProc(
54 __in THEME* pTheme,
55 __in HWND hWnd,
56 __in UINT uMsg,
57 __in WPARAM wParam,
58 __in LPARAM lParam,
59 __inout LRESULT* plRes
60 )
61 {
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)
68 {
69 case WM_COMMAND:
70 switch (HIWORD(wParam))
71 {
72 case BN_CLICKED:
73 OnShowTheme();
74 break;
75 }
76 break;
77 }
78
79 return hr;
80 }
81
82private:
83 HRESULT OnShowTheme()
84 {
85 HRESULT hr = S_OK;
86 BOOL fRet = FALSE;
87 MSG msg = { };
88
89 hr = ThemeLoadFromResource(m_hModule, MAKEINTRESOURCEA(1), &m_pBafTheme);
90 BalExitOnFailure(hr, "Failed to load BafThmUtilTesting theme.");
91
92 hr = CreateTestingWindow();
93 BalExitOnFailure(hr, "Failed to create BafThmUtilTesting window.");
94
95 ::EnableWindow(m_pTheme->hwndParent, FALSE);
96
97 // message pump
98 while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0)))
99 {
100 if (-1 == fRet)
101 {
102 hr = E_UNEXPECTED;
103 BalExitOnFailure(hr, "Unexpected return value from message pump.");
104 }
105 else if (!ThemeHandleKeyboardMessage(m_pBafTheme, msg.hwnd, &msg))
106 {
107 ::TranslateMessage(&msg);
108 ::DispatchMessageW(&msg);
109 }
110 }
111
112 LExit:
113 ::EnableWindow(m_pTheme->hwndParent, TRUE);
114
115 DestroyTestingWindow();
116
117 ReleaseTheme(m_pBafTheme);
118
119 return hr;
120 }
121
122 HRESULT CreateTestingWindow()
123 {
124 HRESULT hr = S_OK;
125 HICON hIcon = reinterpret_cast<HICON>(m_pTheme->hIcon);
126 WNDCLASSW wc = { };
127 int x = CW_USEDEFAULT;
128 int y = CW_USEDEFAULT;
129 POINT ptCursor = { };
130
131 // If the theme did not provide an icon, try using the icon from the bundle engine.
132 if (!hIcon)
133 {
134 HMODULE hBootstrapperEngine = ::GetModuleHandleW(NULL);
135 if (hBootstrapperEngine)
136 {
137 hIcon = ::LoadIconW(hBootstrapperEngine, MAKEINTRESOURCEW(1));
138 }
139 }
140
141 // Register the window class and create the window.
142 wc.lpfnWndProc = CBafThmUtilTesting::TestingWndProc;
143 wc.hInstance = m_hModule;
144 wc.hIcon = hIcon;
145 wc.hCursor = ::LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
146 wc.hbrBackground = m_pTheme->rgFonts[m_pBafTheme->dwFontId].hBackground;
147 wc.lpszMenuName = NULL;
148 wc.lpszClassName = BAFTHMUTILTESTING_WINDOW_CLASS;
149 if (!::RegisterClassW(&wc))
150 {
151 ExitWithLastError(hr, "Failed to register window.");
152 }
153
154 m_fRegistered = TRUE;
155
156 // Center the window on the monitor with the mouse.
157 if (::GetCursorPos(&ptCursor))
158 {
159 x = ptCursor.x;
160 y = ptCursor.y;
161 }
162
163 hr = ThemeCreateParentWindow(m_pBafTheme, 0, wc.lpszClassName, m_pBafTheme->sczCaption, m_pBafTheme->dwStyle, x, y, m_pTheme->hwndParent, m_hModule, this, THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES, &m_hWndBaf);
164 ExitOnFailure(hr, "Failed to create window.");
165
166 hr = S_OK;
167
168 LExit:
169 return hr;
170 }
171
172 void DestroyTestingWindow()
173 {
174 if (::IsWindow(m_hWndBaf))
175 {
176 ::DestroyWindow(m_hWndBaf);
177 m_hWndBaf = NULL;
178 }
179
180 if (m_fRegistered)
181 {
182 ::UnregisterClassW(BAFTHMUTILTESTING_WINDOW_CLASS, m_hModule);
183 m_fRegistered = FALSE;
184 }
185 }
186
187 static LRESULT CALLBACK TestingWndProc(
188 __in HWND hWnd,
189 __in UINT uMsg,
190 __in WPARAM wParam,
191 __in LPARAM lParam
192 )
193 {
194#pragma warning(suppress:4312)
195 CBafThmUtilTesting* pBaf = reinterpret_cast<CBafThmUtilTesting*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
196
197 switch (uMsg)
198 {
199 case WM_NCCREATE:
200 {
201 LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
202 pBaf = reinterpret_cast<CBafThmUtilTesting*>(lpcs->lpCreateParams);
203#pragma warning(suppress:4244)
204 ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pBaf));
205 break;
206 }
207
208 case WM_CLOSE:
209 if (pBaf)
210 {
211 ::EnableWindow(pBaf->m_pTheme->hwndParent, TRUE);
212 }
213
214 break;
215
216 case WM_NCDESTROY:
217 {
218 LRESULT lres = ThemeDefWindowProc(pBaf ? pBaf->m_pBafTheme : NULL, hWnd, uMsg, wParam, lParam);
219 ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0);
220
221 ::PostQuitMessage(0);
222 return lres;
223 }
224
225 case WM_CREATE:
226 if (!pBaf->OnCreate(hWnd))
227 {
228 return -1;
229 }
230 break;
231
232 case WM_TIMER:
233 if (!lParam && pBaf)
234 {
235 pBaf->UpdateProgressBarProgress();
236
237 return 0;
238 }
239 break;
240 }
241
242 return ThemeDefWindowProc(pBaf ? pBaf->m_pBafTheme : NULL, hWnd, uMsg, wParam, lParam);
243 }
244
245 BOOL OnCreate(
246 __in HWND hWnd
247 )
248 {
249 HRESULT hr = S_OK;
250 LVITEMW lvitem = { };
251 LVGROUP lvgroup = { };
252 static UINT puColumns[] = { 0, 1, 2 };
253 HWND hwndTopLeft = NULL;
254 HWND hwndTopRight = NULL;
255 HWND hwndBottomLeft = NULL;
256 HWND hwndBottomRight = NULL;
257
258 hr = ThemeLoadControls(m_pBafTheme, vrgInitControls, countof(vrgInitControls));
259 BalExitOnFailure(hr, "Failed to load theme controls.");
260
261 hwndTopLeft = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_LEFT);
262 BalExitOnNull(hwndTopLeft, hr, E_INVALIDSTATE, "Failed to get top left list view hWnd.");
263
264 hwndTopRight = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_TOP_RIGHT);
265 BalExitOnNull(hwndTopRight, hr, E_INVALIDSTATE, "Failed to get top right list view hWnd.");
266
267 hwndBottomLeft = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_LEFT);
268 BalExitOnNull(hwndBottomLeft, hr, E_INVALIDSTATE, "Failed to get bottom left list view hWnd.");
269
270 hwndBottomRight = ::GetDlgItem(m_pBafTheme->hwndParent, BAFTHMUTILTESTING_CONTROL_LISTVIEW_BOTTOM_RIGHT);
271 BalExitOnNull(hwndBottomRight, hr, E_INVALIDSTATE, "Failed to get bottom right list view hWnd.");
272
273 lvgroup.cbSize = sizeof(LVGROUP);
274 lvgroup.mask = LVGF_GROUPID | LVGF_TITLEIMAGE | LVGF_DESCRIPTIONTOP | LVGF_HEADER;
275
276 for (int i = 0; i < 3; ++i)
277 {
278 lvgroup.iGroupId = i;
279 lvgroup.iTitleImage = i;
280
281 hr = StrAllocFormatted(&lvgroup.pszDescriptionTop, L"DescriptionTop_%d", i);
282 BalExitOnFailure(hr, "Failed to alloc list view group description.");
283
284 hr = StrAllocFormatted(&lvgroup.pszHeader, L"Header_%d", i);
285 BalExitOnFailure(hr, "Failed to alloc list view group header.");
286
287 ListView_InsertGroup(hwndTopLeft, -1, &lvgroup);
288 ListView_InsertGroup(hwndTopRight, -1, &lvgroup);
289 ListView_InsertGroup(hwndBottomLeft, -1, &lvgroup);
290 ListView_InsertGroup(hwndBottomRight, -1, &lvgroup);
291
292 lvitem.mask = LVIF_COLUMNS | LVIF_GROUPID | LVIF_IMAGE | LVIF_TEXT;
293 lvitem.iItem = i;
294 lvitem.iSubItem = 0;
295
296 hr = StrAllocFormatted(&lvitem.pszText, L"ListViewItem_%d", i);
297 BalExitOnFailure(hr, "Failed to alloc list view item text.");
298
299 lvitem.iImage = i;
300 lvitem.iGroupId = i;
301 lvitem.cColumns = countof(puColumns);
302 lvitem.puColumns = puColumns;
303
304 ListView_InsertItem(hwndTopLeft, &lvitem);
305 ListView_InsertItem(hwndTopRight, &lvitem);
306 ListView_InsertItem(hwndBottomLeft, &lvitem);
307 ListView_InsertItem(hwndBottomRight, &lvitem);
308
309 for (int j = 0; j < 3; ++j)
310 {
311 lvitem.mask = LVIF_TEXT;
312 lvitem.iSubItem = j + 1;
313
314 hr = StrAllocFormatted(&lvitem.pszText, L"%d_%d", j, i);
315 BalExitOnFailure(hr, "Failed to alloc list view subitem text.");
316
317 ListView_InsertItem(hwndTopLeft, &lvitem);
318 ListView_InsertItem(hwndTopRight, &lvitem);
319 ListView_InsertItem(hwndBottomLeft, &lvitem);
320 ListView_InsertItem(hwndBottomRight, &lvitem);
321 }
322 }
323
324 ListView_EnableGroupView(hwndTopRight, TRUE);
325
326 ::SetTimer(hWnd, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, 500, NULL);
327
328 LExit:
329 ReleaseStr(lvgroup.pszDescriptionTop);
330 ReleaseStr(lvgroup.pszHeader);
331 ReleaseStr(lvitem.pszText);
332
333 return SUCCEEDED(hr);
334 }
335
336 void UpdateProgressBarProgress()
337 {
338 static DWORD dwProgress = 0;
339 DWORD dwCurrent = dwProgress < 100 ? dwProgress : 200 - dwProgress;
340
341 if (0 == dwProgress || 100 == dwProgress)
342 {
343 ThemeSetProgressControlColor(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, 100 == dwProgress ? 1 : 0);
344 }
345
346 dwProgress = (dwProgress + 10) % 200;
347
348 ThemeSetProgressControl(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_IMAGE, dwCurrent);
349 ThemeSetProgressControl(m_pBafTheme, BAFTHMUTILTESTING_CONTROL_PROGRESSBAR_STANDARD, dwCurrent);
350 }
351
352public:
353 //
354 // Constructor - initialize member variables.
355 //
356 CBafThmUtilTesting(
357 __in HMODULE hModule,
358 __in IBootstrapperEngine* pEngine,
359 __in const BA_FUNCTIONS_CREATE_ARGS* pArgs
360 ) : CBalBaseBAFunctions(hModule, pEngine, pArgs)
361 {
362 m_pBafTheme = NULL;
363 m_fRegistered = FALSE;
364 m_hWndBaf = NULL;
365
366 ThemeInitialize(hModule);
367 }
368
369 //
370 // Destructor - release member variables.
371 //
372 ~CBafThmUtilTesting()
373 {
374 Assert(!::IsWindow(m_hWndBaf));
375 Assert(!m_pBafTheme);
376
377 ThemeUninitialize();
378 }
379
380private:
381 THEME* m_pBafTheme;
382 BOOL m_fRegistered;
383 HWND m_hWndBaf;
384};
385
386
387HRESULT WINAPI CreateBAFunctions(
388 __in HMODULE hModule,
389 __in const BA_FUNCTIONS_CREATE_ARGS* pArgs,
390 __inout BA_FUNCTIONS_CREATE_RESULTS* pResults
391 )
392{
393 HRESULT hr = S_OK;
394 CBafThmUtilTesting* pBAFunctions = NULL;
395 IBootstrapperEngine* pEngine = NULL;
396
397 DutilInitialize(&BafThmUtilTestingTraceError);
398
399 hr = BalInitializeFromCreateArgs(pArgs->pBootstrapperCreateArgs, &pEngine);
400 ExitOnFailure(hr, "Failed to initialize Bal.");
401
402 pBAFunctions = new CBafThmUtilTesting(hModule, pEngine, pArgs);
403 ExitOnNull(pBAFunctions, hr, E_OUTOFMEMORY, "Failed to create new CBafThmUtilTesting object.");
404
405 pResults->pfnBAFunctionsProc = BalBaseBAFunctionsProc;
406 pResults->pvBAFunctionsProcContext = pBAFunctions;
407 pBAFunctions = NULL;
408
409LExit:
410 ReleaseObject(pBAFunctions);
411 ReleaseObject(pEngine);
412
413 return hr;
414}
415
416static void CALLBACK BafThmUtilTestingTraceError(
417 __in_z LPCSTR /*szFile*/,
418 __in int /*iLine*/,
419 __in REPORT_LEVEL /*rl*/,
420 __in UINT source,
421 __in HRESULT hrError,
422 __in_z __format_string LPCSTR szFormat,
423 __in va_list args
424 )
425{
426 // BalLogError currently uses the Exit... macros,
427 // so if expanding the scope need to ensure this doesn't get called recursively.
428 if (DUTIL_SOURCE_THMUTIL == source)
429 {
430 BalLogErrorArgs(hrError, szFormat, args);
431 }
432}