Windows: Fix some cases of external applications freezing during mount/dismount by using an internal window as parent to the waiting dialog instead of the desktop window.

This commit is contained in:
Mounir IDRASSI 2018-03-20 00:15:15 +01:00
parent f278df95e9
commit fd693b3a0c
No known key found for this signature in database
GPG Key ID: DD0C382D5FCFB8FC

View File

@ -7616,9 +7616,14 @@ void BringToForeground(HWND hWnd)
#endif
}
static LRESULT CALLBACK ShowWaitDialogParentWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProcW (hWnd, message, wParam, lParam);
}
void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, void* pArg)
{
HWND hParent = (hwnd && bUseHwndAsParent)? hwnd : GetDesktopWindow();
BOOL bEffectiveHideWaitingDialog = bCmdHideWaitingDialogValid? bCmdHideWaitingDialog : bHideWaitingDialog;
WaitThreadParam threadParam;
threadParam.callback = callback;
@ -7632,9 +7637,12 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v
}
else
{
const wchar_t *className = L"VeraCryptShowWaitDialogParent";
BOOL bIsForeground = FALSE;
HWND creatorWnd = hwnd? hwnd : MainDlg;
WaitDialogDisplaying = TRUE;
HWND hParent = NULL;
if (creatorWnd)
{
if (GetForegroundWindow () == creatorWnd)
@ -7642,6 +7650,28 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v
EnableWindow (creatorWnd, FALSE);
}
if (hwnd && bUseHwndAsParent)
hParent = hwnd;
else
{
/* create invisible window and use it as parent */
WNDCLASSEXW winClass;
memset (&winClass, 0, sizeof (winClass));
winClass.cbSize = sizeof (WNDCLASSEX);
winClass.lpfnWndProc = (WNDPROC) ShowWaitDialogParentWndProc;
winClass.hInstance = hInst;
winClass.lpszClassName = className;
RegisterClassExW (&winClass);
hParent = CreateWindowExW (WS_EX_TOOLWINDOW | WS_EX_LAYERED, className, L"VeraCrypt ShowWaitDialog Parent", 0, 0, 0, 1, 1, NULL, NULL, hInst, NULL);
if (hParent)
{
SetLayeredWindowAttributes (hParent, 0, 1, LWA_ALPHA);
ShowWindow (hParent, SW_SHOWNORMAL);
}
}
finally_do_arg2 (HWND, creatorWnd, BOOL, bIsForeground, { if (finally_arg) { EnableWindow(finally_arg, TRUE); if (finally_arg2) BringToForeground (finally_arg);}});
DialogBoxParamW (hInst,
@ -7649,6 +7679,13 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v
(DLGPROC) WaitDlgProc, (LPARAM) &threadParam);
WaitDialogDisplaying = FALSE;
if (!(hwnd && bUseHwndAsParent))
{
if (hParent)
DestroyWindow (hParent);
UnregisterClassW (className, hInst);
}
}
}