@joebigelow / wix-1 / commits / 7e2a9522

Make the clean room process replace the splash screen with its own.

This is required to get Windows to automatically transfer foreground focus so that the BA's window or the elevation prompt is automatically activated. Fixes 6836

Sean Hall committed Aug 3, 2022 at 11:38 UTC 7e2a9522351c58c45c7185f9e97b3b2faf1f9c90
3 files changed +21 -2
src/burn/engine/engine.cpp
+1 -1
@@ -132,7 +132,7 @@ extern "C" HRESULT EngineRun(
132
133 engineState.command.nCmdShow = nCmdShow;
134
135 - if (BURN_MODE_ELEVATED != engineState.internalCommand.mode && BOOTSTRAPPER_DISPLAY_NONE < engineState.command.display && !engineState.command.hwndSplashScreen)
135 + if (BURN_MODE_ELEVATED != engineState.internalCommand.mode && BOOTSTRAPPER_DISPLAY_NONE < engineState.command.display)
136 {
137 SplashScreenCreate(hInstance, NULL, &engineState.command.hwndSplashScreen);
138 }
src/burn/engine/splashscreen.cpp
+19
@@ -13,6 +13,7 @@ struct SPLASHSCREEN_INFO
13 SIZE size;
14 UINT nDpi;
15 HWND hWnd;
16 + HWND hwndPrevious;
17 };
18
19 struct SPLASHSCREEN_CONTEXT
@@ -258,6 +259,19 @@ static LRESULT CALLBACK WndProc(
259 case WM_ERASEBKGND:
260 OnEraseBkgnd(pSplashScreen, wParam);
261 return 1;
262 +
263 + case WM_ENTERIDLE:
264 + lres = ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
265 +
266 + // We had to create our own splash screen so that Windows would automatically transfer focus from the other process's splash screen.
267 + // Try to make sure new splash screen has painted before closing old one to avoid flickering.
268 + if (pSplashScreen->hwndPrevious)
269 + {
270 + ::PostMessageW(pSplashScreen->hwndPrevious, WM_CLOSE, 0, 0);
271 + pSplashScreen->hwndPrevious = NULL;
272 + }
273 +
274 + return lres;
275 }
276
277 return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
@@ -276,6 +290,11 @@ static HRESULT LoadSplashScreen(
290 DPIU_MONITOR_CONTEXT* pMonitorContext = NULL;
291 RECT* pMonitorRect = NULL;
292
293 + if (::IsWindow(*pContext->pHwnd))
294 + {
295 + pSplashScreen->hwndPrevious = *pContext->pHwnd;
296 + }
297 +
298 pSplashScreen->nDpi = USER_DEFAULT_SCREEN_DPI;
299 pSplashScreen->hBitmap = ::LoadBitmapW(pContext->hInstance, MAKEINTRESOURCEW(pContext->pSplashScreenConfiguration->wResourceId));
300 ExitOnNullWithLastError(pSplashScreen->hBitmap, hr, "Failed to load splash screen bitmap.");
src/test/burn/WixToolsetTest.BurnE2E/WixIuiBaTests.cs
+1 -1
@@ -114,7 +114,7 @@ namespace WixToolsetTest.BurnE2E
114 // Manual test for InternalUIBundle:
115 // 1. Double click InternalUIBundle.exe on a machine that will prompt for elevation.
116 // 2. Verify that the splash screen appeared but the prereq BA did not come up.
117 - // 3. Verify that the elevation prompt came up immediately instead of flashing on the taskbar. (This is currently broken)
117 + // 3. Verify that the elevation prompt came up immediately instead of flashing on the taskbar.
118 // 4. Allow elevation.
119 // 5. Verify that the MSI UI came up and the splash screen disappeared.
120 // 6. Accept the two CA messages and click the install button.