diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2018-03-20 00:15:15 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2018-03-20 00:21:58 +0100 |
commit | fd693b3a0c324a38fc25d24f03e5c86008574b09 (patch) | |
tree | d50978ca8405396f703018f656b27b5a46b4d48b /src/Common | |
parent | f278df95e9fc7604a69b4fcbf8289fe7fe59258d (diff) | |
download | VeraCrypt-fd693b3a0c324a38fc25d24f03e5c86008574b09.tar.gz VeraCrypt-fd693b3a0c324a38fc25d24f03e5c86008574b09.zip |
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.
Diffstat (limited to 'src/Common')
-rw-r--r-- | src/Common/Dlgcode.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index eed087aa..56938518 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -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); + } } } |