From 41819270bbb7129a5568125a6b0cbfdf719680bd Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 15 Oct 2015 01:18:25 +0200 Subject: Windows: Solve lost focus for application after displaying the waiting dialog --- src/Common/Dlgcode.c | 50 +++++++++++++++++++++++++++++++++++++++++++------- src/Common/Dlgcode.h | 1 + src/Mount/Mount.c | 5 +++-- 3 files changed, 47 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index a295d5b5..65801bea 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -6592,6 +6592,43 @@ BOOL CALLBACK WaitDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) } } + +void BringToForeground(HWND hWnd) +{ + if(!::IsWindow(hWnd)) return; + + DWORD lockTimeOut = 0; + HWND hCurrWnd = ::GetForegroundWindow(); + DWORD dwThisTID = ::GetCurrentThreadId(), + dwCurrTID = ::GetWindowThreadProcessId(hCurrWnd,0); + + if(dwThisTID != dwCurrTID) + { + ::AttachThreadInput(dwThisTID, dwCurrTID, TRUE); + + ::SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,0,&lockTimeOut,0); + ::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); + + ::AllowSetForegroundWindow(ASFW_ANY); + } + + ::SetForegroundWindow(hWnd); + + if(dwThisTID != dwCurrTID) + { + ::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,(PVOID)lockTimeOut,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); + ::AttachThreadInput(dwThisTID, dwCurrTID, FALSE); + } + +#ifdef TCMOUNT + if (hWnd == MainDlg) + { + SetFocus (hWnd); + ::SendMessage(hWnd, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hWnd, IDC_DRIVELIST), 1L); + } +#endif +} + void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, void* pArg) { HWND hParent = (hwnd && bUseHwndAsParent)? hwnd : GetDesktopWindow(); @@ -6605,24 +6642,23 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v } else { + BOOL bIsForeground = FALSE; WaitDialogDisplaying = TRUE; if (hwnd) + { + if (GetForegroundWindow () == hwnd) + bIsForeground = TRUE; EnableWindow (hwnd, FALSE); + } else EnableWindow (MainDlg, FALSE); - finally_do_arg (HWND, hwnd, { if (finally_arg) EnableWindow(finally_arg, TRUE); else EnableWindow (MainDlg, TRUE);}); + finally_do_arg2 (HWND, hwnd, BOOL, bIsForeground, { if (finally_arg) {EnableWindow(finally_arg, TRUE); if (finally_arg2) BringToForeground (finally_arg);} else EnableWindow (MainDlg, TRUE);}); DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_STATIC_MODAL_WAIT_DLG), hParent, (DLGPROC) WaitDlgProc, (LPARAM) &threadParam); WaitDialogDisplaying = FALSE; - - if (hwnd && IsWindowVisible(hwnd) && !bUseHwndAsParent) - { - SetForegroundWindow(hwnd); - BringWindowToTop(hwnd); - } } } diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 5d8d7e29..a7f4affd 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -568,6 +568,7 @@ inline std::wstring AppendSrcPos (const wchar_t* msg, const char* srcPos) // Display a wait dialog while calling the provided callback with the given parameter typedef void (CALLBACK* WaitThreadProc)(void* pArg, HWND hWaitDlg); +void BringToForeground(HWND hWnd); void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, void* pArg); #endif // __cplusplus diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 9ee58151..cd82c08e 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -4598,9 +4598,10 @@ static BOOL Dismount (HWND hwndDlg, int nDosDriveNo) void __cdecl mountThreadFunction (void *hwndDlgArg) { HWND hwndDlg =(HWND) hwndDlgArg; + BOOL bIsForeground = (GetForegroundWindow () == hwndDlg)? TRUE : FALSE; // Disable parent dialog during processing to avoid user interaction EnableWindow(hwndDlg, FALSE); - finally_do_arg (HWND, hwndDlg, { EnableWindow(finally_arg, TRUE); bPrebootPasswordDlgMode = FALSE;}); + finally_do_arg2 (HWND, hwndDlg, BOOL, bIsForeground, { EnableWindow(finally_arg, TRUE); if (finally_arg2) BringToForeground (finally_arg); bPrebootPasswordDlgMode = FALSE;}); Mount (hwndDlg, 0, 0, -1); } @@ -9102,7 +9103,7 @@ void CALLBACK mountFavoriteVolumeCallbackFunction (void *pArg, HWND hwnd) void __cdecl mountFavoriteVolumeThreadFunction (void *pArg) { - ShowWaitDialog (NULL, FALSE, mountFavoriteVolumeCallbackFunction, pArg); + ShowWaitDialog (MainDlg, FALSE, mountFavoriteVolumeCallbackFunction, pArg); } static void SaveDefaultKeyFilesParam (HWND hwnd) -- cgit v1.2.3