void bring_to_top(GtkWidget *win){ #ifdef __WIN32__ HWND hWnd; int nTargetID, nForegroundID; BOOL res; hWnd = GDK_WINDOW_HWND (win->window); /* From http://techtips.belution.com/ja/vc/0012/ */ nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL); nTargetID = GetWindowThreadProcessId(hWnd, NULL ); AttachThreadInput(nTargetID, nForegroundID, TRUE ); // SPI_GETFOREGROUNDLOCKTIMEOUT will be undefined. Why ? /* SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT,0,&sp_time,0); SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,(LPVOID)0,0); SetForegroundWindow(hWnd); SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,sp_time,0); */ res = SetForegroundWindow(hWnd); AttachThreadInput(nTargetID, nForegroundID, FALSE); if(!res){ SetFocus(hWnd); } #else gdk_window_show(GTK_WIDGET(win)->window); gdk_window_focus(GTK_WIDGET(win)->window, gtk_get_current_event_time()); #endif }
// http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo void SetForegroundWindowInternal(HWND hWnd) { SetWindowPos(hWnd,HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(hWnd,HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(hWnd,HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); return; //relation time of SetForegroundWindow lock DWORD lockTimeOut = 0; HWND hCurrWnd = GetForegroundWindow(); DWORD dwThisTID = GetCurrentThreadId(), dwCurrTID = GetWindowThreadProcessId(hCurrWnd, 0); //we need to bypass some limitations from Microsoft :) 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); } }
XBool activateGame(HWND h) { //方案1://不行 //return BringWindowToTop(XEG.getHWND()); //方案2://可以 //typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL); //PROCSWITCHTOTHISWINDOW SwitchToThisWindow; //HMODULE hUser32 = GetModuleHandle("user32"); //SwitchToThisWindow = ( PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow"); //if(SwitchToThisWindow == NULL) return false; ////接下来只要用任何现存窗口的句柄调用这个函数即可,第二个参数指定如果窗口极小化,是否恢复其原状态。 //SwitchToThisWindow(XEG.getHWND(), TRUE); //return true; //方案3://可行 HWND hCurWnd = GetForegroundWindow(); DWORD dwMyID = GetCurrentThreadId(); DWORD dwCurID = GetWindowThreadProcessId(hCurWnd, NULL); AttachThreadInput(dwCurID, dwMyID, TRUE); SetForegroundWindow(h); AttachThreadInput(dwCurID, dwMyID, FALSE); return true; //方法4://可行 //ShowWindow(XEG.getHWND(),SW_SHOWNA);//简单的显示主窗口完事儿 //SetActiveWindow(XEG.getHWND()); //SetForegroundWindow(XEG.getHWND()); ////this->SetWindowPos(this,LOWORD(lParam),HIWORD(lParam),c.Width(),c.Height(),SWP_NOACTIVATE); //BringWindowToTop(XEG.getHWND()); //return true; }
static DWORD set_foreground(HWND hwnd) { HWND hwnd_fore; DWORD set_id, fore_id, ret; char win_text[1024]; hwnd_fore = GetForegroundWindow(); GetWindowTextA(hwnd_fore, win_text, 1024); set_id = GetWindowThreadProcessId(hwnd, NULL); fore_id = GetWindowThreadProcessId(hwnd_fore, NULL); trace("\"%s\" %p %08x hwnd %p %08x\n", win_text, hwnd_fore, fore_id, hwnd, set_id); ret = AttachThreadInput(set_id, fore_id, TRUE); trace("AttachThreadInput returned %08x\n", ret); ret = ShowWindow(hwnd, SW_SHOWNORMAL); trace("ShowWindow returned %08x\n", ret); ret = SetWindowPos(hwnd, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); trace("set topmost returned %08x\n", ret); ret = SetWindowPos(hwnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); trace("set notopmost returned %08x\n", ret); ret = SetForegroundWindow(hwnd); trace("SetForegroundWindow returned %08x\n", ret); Sleep(250); AttachThreadInput(set_id, fore_id, FALSE); return ret; }
bool raiseWindow(QWidget *w, unsigned) #endif { Event e(EventRaiseWindow, w); if (e.process()) return false; #ifdef USE_KDE /* info.currentDesktop is 0 when iconified :( also onAllDesktops is 0 when Objekt isn't shown already */ KWin::Info info = KWin::info(w->winId()); if ((!info.onAllDesktops) || (desk == 0)) { if (desk == 0) desk = KWin::currentDesktop(); KWin::setOnDesktop(w->winId(), desk); } #endif w->show(); w->showNormal(); w->setActiveWindow(); w->raise(); #ifdef USE_KDE KWin::setActiveWindow(w->winId()); #endif #ifdef WIN32 AttachThreadInput(GetWindowThreadProcessId(GetForegroundWindow(),NULL), GetCurrentThreadId(), TRUE); SetForegroundWindow(w->winId()); SetFocus(w->winId()); AttachThreadInput(GetWindowThreadProcessId(GetForegroundWindow(),NULL), GetCurrentThreadId(), FALSE); #endif return true; }
void DoFocus(BOOL bUseCurrent,HWND hwndFocus) { HWND hwndEdit; char WinClass[256]; DWORD OtherAppThreadID; DWORD OtherAppProcessID; DWORD TrayThreadID; if(bUseCurrent) { TrayThreadID=GetCurrentThreadId(); hwndEdit=hwndFocus; GetClassName(hwndEdit,WinClass,255); OtherAppThreadID = GetWindowThreadProcessId( hwndEdit, &OtherAppProcessID); AttachThreadInput( TrayThreadID, OtherAppThreadID, TRUE ); // We can key off WinClass if something else // needs to be done SetFocus(hwndEdit); AttachThreadInput( TrayThreadID, OtherAppThreadID, FALSE ); } }
BOOL SetForegroundWindowInternal(HWND hWnd) { BOOL ret = false; if (!IsWindow(hWnd)) return ret; //relation time of SetForegroundWindow lock DWORD lockTimeOut = 0; HWND hCurrWnd = GetForegroundWindow(); DWORD dwThisTID = GetCurrentThreadId(), dwCurrTID = GetWindowThreadProcessId(hCurrWnd, 0); //we need to bypass some limitations from Microsoft :) 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); } ret = SetForegroundWindow(hWnd); if (dwThisTID != dwCurrTID) { SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (PVOID)lockTimeOut, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); AttachThreadInput(dwThisTID, dwCurrTID, FALSE); } return ret; }
void WaitForReleaseVkKeys(DWORD dwThreadCurrent, DWORD dwThreadTarget, DWORD dwTimeout) { DWORD dwStart=GetTickCount(); BYTE lpKeyState[256]; int i; Loop: if (dwTimeout == INFINITE || GetTickCount() - dwStart < dwTimeout) { AttachThreadInput(dwThreadCurrent, dwThreadTarget, FALSE); if (AttachThreadInput(dwThreadCurrent, dwThreadTarget, TRUE)) { Sleep(0); if (GetKeyboardState(lpKeyState)) { for (i=0; i < 256; ++i) { if (lpKeyState[i] & 0x80) goto Loop; } } } } }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ COMMONEXPORT BOOL _SetForegroundWindowEx ( HWND hWnd ) { if (hWnd == NULL) return FALSE; // determine current foreground window HWND hWndForeground = ::GetForegroundWindow (); if (hWndForeground == NULL) return ::SetForegroundWindow (hWnd); // check whether it is able to pump messages to avoid deadlocks DWORD dwResult = 0; if ( SendMessageTimeout ( hWndForeground, WM_NULL, 0, 0, SMTO_NORMAL, 1000, &dwResult ) == 0 ) return FALSE; int iTID = ::GetWindowThreadProcessId ( hWnd, 0 ); int iForegroundTID = ::GetWindowThreadProcessId ( hWndForeground, 0 ); AttachThreadInput (iTID, iForegroundTID, TRUE); ::SetForegroundWindow (hWnd); AttachThreadInput (iTID, iForegroundTID, FALSE); return TRUE; }
HRESULT CSysProgressDlg::ShowModeless(HWND hWndParent, BOOL immediately) { EnsureValid(); m_hWndProgDlg = nullptr; if (!IsValid()) return E_FAIL; m_hWndParent = hWndParent; auto winId = GetWindowThreadProcessId(m_hWndParent, 0); auto threadId = GetCurrentThreadId(); if (winId != threadId) AttachThreadInput(winId, threadId, TRUE); m_hWndFocus = GetFocus(); if (winId != threadId) AttachThreadInput(winId, threadId, FALSE); HRESULT hr = m_pIDlg->StartProgressDialog(hWndParent, nullptr, m_dwDlgFlags, nullptr); if(FAILED(hr)) return hr; ATL::CComPtr<IOleWindow> pOleWindow; HRESULT hr2 = m_pIDlg.QueryInterface(&pOleWindow); if(SUCCEEDED(hr2)) { hr2 = pOleWindow->GetWindow(&m_hWndProgDlg); if(SUCCEEDED(hr2)) { if (immediately) ShowWindow(m_hWndProgDlg, SW_SHOW); } } m_isVisible = true; return hr; }
void bringToFront() { #if defined(Q_WS_X11) { qDebug() << Q_FUNC_INFO; QWidget* widget = tomahawkWindow(); if ( !widget ) return; widget->show(); widget->activateWindow(); widget->raise(); WId wid = widget->winId(); NETWM::init(); XEvent e; e.xclient.type = ClientMessage; e.xclient.message_type = NETWM::NET_ACTIVE_WINDOW; e.xclient.display = QX11Info::display(); e.xclient.window = wid; e.xclient.format = 32; e.xclient.data.l[0] = 2; e.xclient.data.l[1] = QX11Info::appTime(); e.xclient.data.l[2] = 0; e.xclient.data.l[3] = 0l; e.xclient.data.l[4] = 0l; XSendEvent( QX11Info::display(), RootWindow( QX11Info::display(), DefaultScreen( QX11Info::display() ) ), False, SubstructureRedirectMask | SubstructureNotifyMask, &e ); } #elif defined(Q_WS_WIN) { qDebug() << Q_FUNC_INFO; QWidget* widget = tomahawkWindow(); if ( !widget ) return; widget->show(); widget->activateWindow(); widget->raise(); WId wid = widget->winId(); HWND hwndActiveWin = GetForegroundWindow(); int idActive = GetWindowThreadProcessId(hwndActiveWin, NULL); if ( AttachThreadInput(GetCurrentThreadId(), idActive, TRUE) ) { SetForegroundWindow( wid ); SetFocus( wid ); AttachThreadInput(GetCurrentThreadId(), idActive, FALSE); } } #endif }
/*------------------------------------------------ set keyboard focus to the main window forcedly --------------------------------------------------*/ void SetFocusTClockMain(HWND hwnd) { DWORD pid, curthread, mythread; curthread = GetWindowThreadProcessId(GetForegroundWindow(), &pid); mythread = GetCurrentThreadId(); AttachThreadInput(mythread, curthread, TRUE); SetForegroundWindow(hwnd); SetFocus(hwnd); AttachThreadInput(mythread, curthread, FALSE); }
HRESULT VegasFSRender::writeData(ISfProgress* progress) { BOOL useAudio = (m_pIAudioStream && m_pTemplate->pAudioTemplate && m_pTemplate->pAudioTemplate->cNumAStreams); BOOL useVideo = (m_pIVideoStream && m_pTemplate->pVideoTemplate && m_pTemplate->pVideoTemplate->cNumVStreams); if (!useVideo) return SF_E_NOVIDEO; HWND activewnd = GetForegroundWindow(); DWORD threadid = GetWindowThreadProcessId(activewnd, NULL); AttachThreadInput(GetCurrentThreadId(), threadid, TRUE); ZeroMemory(&FfpHeader, NUMBYTES(FfpHeader)); LPTSTR pszFileName; #ifdef UNICODE pszFileName = m_szFileName; #else TCHAR szFileName[MAX_PATH]; SfMBFromWC(szFileName, m_szFileName, MAX_PATH); pszFileName = szFileName; #endif HRESULT hr = S_OK; hr = m_pIVideoStream->GetFrameCount(&FfpHeader.Video.cfTotal); hr = m_pIVideoStream->GetFrameRate(&FfpHeader.Video.dFPS); FfpHeader.Video.ntLength = SfVideo_FramesToTime( FfpHeader.Video.cfTotal, FfpHeader.Video.dFPS); FfpHeader.Video.bih = *m_pTemplate->pVideoTemplate->pbihCodec; FfpHeader.Video.cbFrameSize = FSDibImageBytes(&FfpHeader.Video.bih); if (useAudio) { hr = m_pIAudioStream->GetSampleCount(&FfpHeader.Audio.ccTotal); FfpHeader.Audio.wfx = m_pTemplate->pAudioTemplate->wfx; hr = m_pIAudioStream->GetStreamLength(&FfpHeader.Audio.ntLength); FfpHeader.Audio.ntLength = SfAudio_CellsToTime(FfpHeader.Audio.ccTotal, FfpHeader.Audio.wfx.nSamplesPerSec); } Init(!!useAudio, FfpHeader.Audio.wfx.nSamplesPerSec, FfpHeader.Audio.wfx.wBitsPerSample, FfpHeader.Audio.wfx.nChannels, (DWORD)FfpHeader.Video.cfTotal, FfpHeader.Video.dFPS, FfpHeader.Video.bih.biWidth, FfpHeader.Video.bih.biHeight, activewnd, pszFileName); hr = S_OK; if (!Run()) hr = SF_E_CANCEL; EnableWindow(activewnd, TRUE); SetForegroundWindow(activewnd); AttachThreadInput(GetCurrentThreadId(), threadid, FALSE); return hr; }
void fsSetForegroundWindow (HWND hWnd) { HWND hFor = GetForegroundWindow (); int iMyTID = GetCurrentThreadId (); int iCurrTID = GetWindowThreadProcessId (hFor, NULL); AttachThreadInput (iMyTID, iCurrTID, TRUE); SetForegroundWindow (hWnd); AttachThreadInput (iMyTID, iCurrTID, FALSE); }
void handle_task_timer(void) { KillTimer(m_hwnd, TASK_RISE_TIMER); if (NULL == task_over) return; DWORD ThreadID1 = GetWindowThreadProcessId(GetForegroundWindow(), NULL); DWORD ThreadID2 = GetCurrentThreadId(); if (ThreadID1 != ThreadID2) { AttachThreadInput(ThreadID1, ThreadID2, TRUE); SetForegroundWindow(m_hwnd); AttachThreadInput(ThreadID1, ThreadID2, FALSE); } PostMessage(GetBBWnd(), BB_BRINGTOFRONT, 0, (LPARAM)task_over); }
void UIScreenCaptureMgr::forceForgroundWindow(__in HWND hWnd) { HWND hForegroundWnd = ::GetForegroundWindow(); DWORD dwPid = GetWindowThreadProcessId(hForegroundWnd, NULL); if (!AttachThreadInput(dwPid, GetCurrentThreadId(), TRUE) || !::SetForegroundWindow(hWnd) || !::BringWindowToTop(hWnd)) { return; } SwitchToThisWindow(hWnd, TRUE); AttachThreadInput(dwPid, GetCurrentThreadId(), FALSE); }
void SetForegroundWindowEx(HWND hWnd) { // Attach foreground window thread to our thread const DWORD foreGroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL); const DWORD currentID = GetCurrentThreadId(); AttachThreadInput(foreGroundID, currentID, TRUE); // Do our stuff here HWND lastActivePopupWnd = GetLastActivePopup(hWnd); SetForegroundWindow(lastActivePopupWnd); // Detach the attached thread AttachThreadInput(foreGroundID, currentID, FALSE); }
BOOL WindowUtil_setFocus(HWND hwnd) { BOOL ret; // Attach foreground window thread AttachThreadInput(GetWindowThreadProcessId(GetForegroundWindow(), NULL), GetCurrentThreadId(), TRUE); ret = SetForegroundWindow(hwnd); SetFocus(hwnd); // Detach the attached thread AttachThreadInput(GetWindowThreadProcessId(GetForegroundWindow(), NULL), GetCurrentThreadId(), FALSE); return ret; }
void BringWindowToTop(HWND hwnd ,DWORD type) { DWORD dwFGThreadId, dwFGProcessId,dwThisThreadId; HWND hwndForeground = ::GetForegroundWindow(); dwFGThreadId = GetWindowThreadProcessId(hwndForeground, &dwFGProcessId); dwThisThreadId = GetCurrentThreadId(); AttachThreadInput(dwThisThreadId, dwFGThreadId,TRUE); if(type != NULL) { ::ShowWindow(hwnd,type); } ::SetForegroundWindow(hwnd); ::BringWindowToTop(hwnd); AttachThreadInput(dwThisThreadId, dwFGThreadId,FALSE); }
// 最前面に来るメッセージボックスを表示する int CCustomBindStatusCallBack::_ActiveMessageBox(const CString& strText, UINT uType) { // 最前面プロセスのスレッドIDを取得する int foregroundID = ::GetWindowThreadProcessId( ::GetForegroundWindow(), NULL); // 最前面アプリケーションの入力処理機構に接続する AttachThreadInput( ::GetCurrentThreadId(), foregroundID, TRUE); // 最前面ウィンドウを変更する ::SetForegroundWindow(m_hWndDLing); int nReturn = MessageBox(m_hWndDLing, strText, NULL, uType); // 接続を解除する AttachThreadInput( ::GetCurrentThreadId(), foregroundID, FALSE); return nReturn; }
/*------------------------------------------------ WM_EXITMENULOOP message --------------------------------------------------*/ void OnExitMenuLoop(HWND hwnd) { HWND hwndBar; DWORD pid, clockthread, mythread; hwndBar = GetTaskbarWindow(); if(hwndBar) { clockthread = GetWindowThreadProcessId(hwndBar, &pid); mythread = GetCurrentThreadId(); AttachThreadInput(clockthread, mythread, TRUE); SetFocus(hwndBar); AttachThreadInput(clockthread, mythread, FALSE); } }
void __stdcall SetForegroundWindowForce(HWND hWnd) { HWND hForeground; DWORD id, foreground_id; hForeground = GetForegroundWindow(); if (hForeground == hWnd) return; foreground_id = GetWindowThreadProcessId(hForeground, NULL); id = GetWindowThreadProcessId(hWnd, NULL); if (AttachThreadInput(id, foreground_id, TRUE)) { SetForegroundWindow(hWnd); BringWindowToTop(hWnd); AttachThreadInput(id, foreground_id, FALSE); } }
//http://www.shloemi.com/2012/09/solved-setforegroundwindow-win32-api-not-always-works/ void MirandaUtils::ForceForegroundWindow(HWND hWnd) { DWORD foreThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL); DWORD appThread = GetCurrentThreadId(); if (foreThread != appThread) { AttachThreadInput(foreThread, appThread, true); BringWindowToTop(hWnd); ShowWindow(hWnd, SW_SHOW); AttachThreadInput(foreThread, appThread, false); } else { BringWindowToTop(hWnd); ShowWindow(hWnd, SW_SHOW); } }
WINBOOL SetForegroundWindowEx(HWND hWnd) { //Attach foreground window thread to our thread const DWORD ForeGroundID = GetWindowThreadProcessId(::GetForegroundWindow(), NULL); const DWORD CurrentID = GetCurrentThreadId(); WINBOOL retval; AttachThreadInput(ForeGroundID, CurrentID, TRUE); //Do our stuff here HWND hLastActivePopupWnd = GetLastActivePopup(hWnd); retval = SetForegroundWindow(hLastActivePopupWnd); //Detach the attached thread AttachThreadInput(ForeGroundID, CurrentID, FALSE); return retval; }// End SetForegroundWindowEx
static bool attachThreadToForeground() { // only attach threads if using low level hooks. a low level hook // runs in the thread that installed the hook but we have to make // changes that require being attached to the target thread (which // should be the foreground window). a regular hook runs in the // thread that just removed the event from its queue so we're // already in the right thread. if (g_hookThread != 0) { HWND window = GetForegroundWindow(); DWORD threadID = GetWindowThreadProcessId(window, NULL); // skip if no change if (g_attachedThread != threadID) { // detach from previous thread detachThread(); // attach to new thread if (threadID != 0 && threadID != g_hookThread) { AttachThreadInput(g_hookThread, threadID, TRUE); g_attachedThread = threadID; } return true; } } return false; }
void muiWindow::BringWindowToForeground() { // Windows 98 and later very much restricts what SetForegroundWindow() does - in most cases it just flashes the taskbar. // Here we will force it to actually brind the window to the foreground & get the keyboard focus HWND hwndForegroundWindow = GetForegroundWindow(); DWORD dwForegroundThreadId = GetWindowThreadProcessId(hwndForegroundWindow, NULL); DWORD dwThisThreadId = GetWindowThreadProcessId(hwnd, NULL); bool bAttachedToFgThread = (dwThisThreadId != dwForegroundThreadId) && AttachThreadInput(dwThisThreadId, dwForegroundThreadId, TRUE); SetForegroundWindow(hwnd); //BringWindowToTop(hwnd); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW); if (bAttachedToFgThread) AttachThreadInput(dwThisThreadId, dwForegroundThreadId, FALSE); }
void CSysProgressDlg::Stop() { if ((m_isVisible)&&(IsValid())) { m_pIDlg->StopProgressDialog(); // Sometimes the progress dialog sticks around after stopping it, // until the mouse pointer is moved over it or some other triggers. // We hide the window here immediately. if (m_hWndProgDlg) { // The progress dialog is handled on a separate thread, which means // even calling StopProgressDialog() will not stop it immediately. // Even destroying the progress window is not enough. // Which can cause problems with modality: if we stop the progress // dialog and immediately show e.g. a messagebox over the same // window the progress dialog has as its parent, then the messagebox // is modal first (deactivates the parent), but then a little bit // later the progress dialog finally closes properly, and by doing that // re-enables its parent window. // Which leads to the parent window being enabled even though // the modal messagebox is shown over the parent window. // This situation can even lead to the messagebox appearing *behind* // the parent window (race condition) // // So, to really ensure that the progress dialog is fully stopped // and destroyed, we have to attach to its UI thread and handle // all messages until there are no more messages: that's when // the progress dialog is really gone. AttachThreadInput(GetWindowThreadProcessId(m_hWndProgDlg, 0), GetCurrentThreadId(), TRUE); // StartProgressDialog creates a new thread to host the progress window. // When the window receives WM_DESTROY message StopProgressDialog() wrongly // attempts to re-enable the parent in the calling thread (our thread), // after the progress window is destroyed and the progress thread has died. // When the progress window dies, the system tries to assign a new foreground window. // It cannot assign to hwndParent because StartProgressDialog (w/PROGDLG_MODAL) disabled the parent window. // So the system hands the foreground activation to the next process that wants it in the // system foreground queue. Thus we lose our right to recapture the foreground window. // To fix this problem, we enable the parent window and set to focus to it here, after // we've attached to the window thread. ShowWindow(m_hWndProgDlg, SW_HIDE); EnableWindow(m_hWndParent, TRUE); if (m_hWndFocus) SetFocus(m_hWndFocus); else SetFocus(m_hWndParent); auto start = GetTickCount64(); while (::IsWindow(m_hWndProgDlg) && ((GetTickCount64() - start) < 3000)) { MSG msg = { 0 }; while (PeekMessage(&msg, m_hWndProgDlg, 0, 0, PM_REMOVE)) { } } } m_isVisible = false; m_pIDlg.Release(); m_hWndProgDlg = nullptr; } }
void BrowsePushed(LPRUNDLG_DATA lprd) { HWND hDlg = lprd->hDlg; TCHAR szText[MAX_PATH]; // Get out of the "synchronized input queues" state if (lprd->dwThreadId) { AttachThreadInput(GetCurrentThreadId(), lprd->dwThreadId, FALSE); lprd->dwThreadId = 0; } GetDlgItemText(hDlg, IDD_COMMAND, szText, ARRAYSIZE(szText)); PathUnquoteSpaces(szText); if (GetFileNameFromBrowse(hDlg, szText, ARRAYSIZE(szText), lprd->lpszWorkingDir, MAKEINTRESOURCE(IDS_EXE), MAKEINTRESOURCE(IDS_PROGRAMSFILTER), MAKEINTRESOURCE(IDS_BROWSE))) { PathQuoteSpaces(szText); SetDlgItemText(hDlg, IDD_COMMAND, szText); EnableOKButton(hDlg, szText); // place the focus on OK // SetFocus(GetDlgItem(hDlg, IDOK)); SendMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDOK), TRUE); } }
BOOL install_util::ForeGroundInstallWindow() { HWND hWnd= FindWindow(_T("#32770"), INSTALL_TITLE); if(NULL == hWnd) return FALSE; HWND hForeWnd = GetForegroundWindow(); DWORD dwCurID = GetCurrentThreadId(); DWORD dwForeID = GetWindowThreadProcessId(hForeWnd, NULL); AttachThreadInput(dwCurID, dwForeID, TRUE); ShowWindow( hWnd, SW_SHOWNORMAL ); SetWindowPos( hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE ); SetWindowPos( hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE ); SetForegroundWindow( hWnd ); AttachThreadInput(dwCurID, dwForeID, FALSE); return TRUE; }
//--------------------------------------------------------------------------- // Puts up the standard file.run dialog. // REVIEW UNDONE This should use a RUNDLG structure for all the various // options instead of just passing them as parameters, a ptr to the struct // would be passed to the dialog via the lParam. int WINAPI RunFileDlg(HWND hwndParent, HICON hIcon, LPCTSTR lpszWorkingDir, LPCTSTR lpszTitle, LPCTSTR lpszPrompt, DWORD dwFlags) { RUNDLG_DATA rd; rd.hIcon = hIcon; rd.lpszWorkingDir = lpszWorkingDir; rd.lpszTitle = lpszTitle; rd.lpszPrompt = lpszPrompt; rd.dwFlags = dwFlags; rd.hEventReady = 0; rd.dwThreadId = 0; // We do this so we can get type-ahead when we're running on a // seperate thread. The parent thread needs to block to give us time // to do the attach and then get some messages out of the queue hence // the event. if (hwndParent) { // HACK The parent signals it's waiting for the dialog to grab type-ahead // by sticking it's threadId in a property on the parent. rd.dwThreadId = (DWORD)GetProp(hwndParent, c_szWaitingThreadID); if (rd.dwThreadId) { // DebugMsg(DM_TRACE, "s.rfd: Attaching input to %x.", idThread); AttachThreadInput(GetCurrentThreadId(), rd.dwThreadId, TRUE); // NB Hack. rd.hEventReady = OpenEvent(EVENT_ALL_ACCESS, TRUE, c_szRunDlgReady); } } return DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(DLG_RUN), hwndParent, RunDlgProc, (LPARAM)(LPRUNDLG_DATA)&rd); }