@joebigelow / wix-1 / commits / 2e327df0

Use radio buttons in FilesInUse task dialog.

Sean Hall committed Jul 24, 2022 at 14:09 UTC 2e327df0b7c785a6cad36f6b3bf79ba8becf9000
1 file changed +30 -25
src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+30 -25
@@ -1044,7 +1044,7 @@ public: // IBootstrapperApplication
1044 __in int nRecommendation,
1045 __in BOOTSTRAPPER_FILES_IN_USE_TYPE source,
1046 __inout int* pResult
1047 - )
1047 + )
1048 {
1049
1050 if (!m_fShowingInternalUiThisPackage && !m_fPrereq && wzPackageId && *wzPackageId)
@@ -2217,14 +2217,14 @@ private: // privates
2217 __in DWORD cFiles,
2218 __in_ecount_z(cFiles) LPCWSTR* rgwzFiles,
2219 __in BOOTSTRAPPER_FILES_IN_USE_TYPE /*source*/
2220 - )
2220 + )
2221 {
2222 HRESULT hr = S_OK;
2223 LPWSTR sczFilesInUse = NULL;
2224 DWORD_PTR cchLen = 0;
2225 int nResult = IDERROR;
2226
2227 - // If the user has choosen to ignore on a previously displayed "files in use" page,
2227 + // If the user has chosen to ignore on a previously displayed "files in use" page,
2228 // we will return the same result for other cases. No need to display the page again.
2229 if (IDIGNORE == m_nLastFilesInUseResult)
2230 {
@@ -2232,26 +2232,20 @@ private: // privates
2232 }
2233 else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // Only show files in use when using full display mode.
2234 {
2235 - // Show applications using the files.
2236 - if (cFiles > 0)
2235 + // See https://docs.microsoft.com/en-us/windows/win32/msi/sending-messages-to-windows-installer-using-msiprocessmessage for details.
2236 + for (DWORD i = 1; i < cFiles; i += 2)
2237 {
2238 - // See https://msdn.microsoft.com/en-us/library/aa371614%28v=vs.85%29.aspx for details.
2239 - for (DWORD i = 1; i < cFiles; i += 2)
2240 - {
2241 - hr = ::StringCchLengthW(rgwzFiles[i], STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
2242 - BalExitOnFailure(hr, "Failed to calculate length of string");
2243 -
2244 - if (cchLen > 0)
2245 - {
2246 - hr = StrAllocConcat(&sczFilesInUse, rgwzFiles[i], 0);
2247 - BalExitOnFailure(hr, "Failed to concat files in use");
2238 + hr = ::StringCchLengthW(rgwzFiles[i], STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
2239 + BalExitOnFailure(hr, "Failed to calculate length of string.");
2240
2249 - hr = StrAllocConcat(&sczFilesInUse, L"\r\n", 2);
2250 - BalExitOnFailure(hr, "Failed to concat files in use");
2251 - }
2241 + if (cchLen)
2242 + {
2243 + hr = StrAllocConcatFormatted(&sczFilesInUse, L"%ls\r\n", rgwzFiles[i]);
2244 + BalExitOnFailure(hr, "Failed to concat files in use.");
2245 }
2246 }
2247
2248 + // Show applications using the files.
2249 hr = ShowFilesInUseDialog(sczFilesInUse, &nResult);
2250 ExitOnFailure(hr, "Failed to show files-in-use task dialog.");
2251 }
@@ -2275,7 +2269,7 @@ private: // privates
2269 int ShowFilesInUseDialog(
2270 __in_z_opt LPCWSTR sczFilesInUse,
2271 __out int* pnResult
2278 - )
2272 + )
2273 {
2274 HRESULT hr = S_OK;
2275 TASKDIALOGCONFIG config = { };
@@ -2284,6 +2278,8 @@ private: // privates
2278 LPWSTR sczCloseRadioButton = NULL;
2279 LPWSTR sczDontCloseRadioButton = NULL;
2280 LOC_STRING* pLocString = NULL;
2281 + int nButton = 0;
2282 + int nRadioButton = 0;
2283
2284 // Get the loc strings for the files-in-use task dialog text.
2285 hr = LocGetString(m_pWixLoc, L"#(loc.FilesInUseTitle)", &pLocString);
@@ -2310,24 +2306,33 @@ private: // privates
2306 hr = StrAllocString(&sczDontCloseRadioButton, pLocString->wzText, 0);
2307 ExitOnFailure(hr, "Failed to copy FilesInUseDontCloseRadioButton loc string.");
2308
2313 - const TASKDIALOG_BUTTON buttons[] = {
2309 + const TASKDIALOG_BUTTON rgRadioButtons[] = {
2310 { IDOK, sczCloseRadioButton },
2311 { IDIGNORE, sczDontCloseRadioButton },
2312 };
2313
2314 config.cbSize = sizeof(config);
2315 + config.hwndParent = m_hWnd;
2316 config.hInstance = m_hModule;
2320 - config.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_USE_COMMAND_LINKS | TDF_SIZE_TO_CONTENT;
2321 - config.dwCommonButtons = TDCBF_CANCEL_BUTTON;
2317 + config.dwFlags = TDF_SIZE_TO_CONTENT | TDF_POSITION_RELATIVE_TO_WINDOW;
2318 + config.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON;
2319 config.pszWindowTitle = sczTitle;
2320 config.pszMainInstruction = sczLabel;
2321 config.pszContent = sczFilesInUse ? sczFilesInUse : L"";
2325 - config.pButtons = buttons;
2326 - config.cButtons = 2;
2322 + config.nDefaultButton = IDOK;
2323 + config.pRadioButtons = rgRadioButtons;
2324 + config.cRadioButtons = countof(rgRadioButtons);
2325 + config.nDefaultRadioButton = IDOK;
2326
2328 - hr = TaskDialogIndirect(&config, pnResult, NULL, NULL);
2327 + hr = ::TaskDialogIndirect(&config, &nButton, &nRadioButton, NULL);
2328 ExitOnFailure(hr, "Failed to show files-in-use task dialog.");
2329
2330 + *pnResult = IDOK == nButton ? nRadioButton : nButton;
2331 +
2332 +#ifdef DEBUG
2333 + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: FilesInUse task dialog result: button - %d, radio button - %d, result - %d", nButton, nRadioButton, *pnResult);
2334 +#endif
2335 +
2336 LExit:
2337 return hr;
2338 }