1. 程式人生 > >Windows 程式設計: 將目標視窗顯示在最頂端

Windows 程式設計: 將目標視窗顯示在最頂端

1. [BUG Backgroud]

  1. 使用SetForegroundWindow(hwnd) 不能將目標視窗彈到頂端.
  2. Win7 中使用WIN鍵後出現的BUG.

最終成功測試程式碼:

BOOL MyClass::PutMyWindowToTop(
) {
  OutputDebugString("In function PutMyWindowToTop!");
  HWND hwnd = FindWindow(NULL, L"MyWindow");
  if (hwnd == NULL) {
      OutputDebugString("Failed to get hwnd of MyWindow!"
); return FALSE; } else { OutputDebugString("Success get hwnd of MyWindow before switch to window"); } if (!::IsWindow(hwnd)) { OutputDebugString("hwnd is not a valid window's handler!"); return FALSE; } try { DWORD lock_timeout = 0; DWORD lock_timeout_after =
0; HWND current_hwnd = ::GetForegroundWindow(); DWORD dw_this_tid = ::GetCurrentThreadId(); DWORD dw_current_tid = ::GetWindowThreadProcessId(current_hwnd, 0); if (dw_this_tid != dw_current_tid) { ::AttachThreadInput(dw_this_tid, dw_current_tid, TRUE); ::
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lock_timeout, 0); if (lock_timeout >= 100) { ::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); if (0 == ::AllowSetForegroundWindow(dw_this_tid)) { OutputDebugString("Failed to AllowSetForegoundWindow!"); } else { OutputDebugString("Successed in AllowSetForegoundWindow!"); } ::SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lock_timeout_after, 0); } } char temp_s[60] = { 0 }; sprintf(temp_s, "lock_timeout: %u, after: %u", lock_timeout, lock_timeout_after); OutputDebugString(temp_s); //Test SetWindows position. if (0 == ::ShowWindow(hwnd, SW_SHOWNORMAL)) { OutputDebugString("ShowWindow return window was previously hidden!"); } else { OutputDebugString("ShowWindow return window was previously visible!"); } if (0 == ::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE)) { OutputDebugString("SetWindowPos first time was failed!"); } else { OutputDebugString("SetWindowPos first time was succeed!"); } if (0 == ::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE)) { OutputDebugString("SetWindowPos second time was failed!"); } else { OutputDebugString("SetWindowPos second time was succeed!"); } if (0 == ::SetForegroundWindow(hwnd)) { OutputDebugString("Failed to set this window to foreground!"); } else { OutputDebugString("Success in set this window to foreground!"); } if (dw_this_tid != dw_current_tid) { ::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (PVOID)lock_timeout, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); ::AttachThreadInput(dw_this_tid, dw_current_tid, FALSE); } } catch (...) { OutputDebugString("Failed to put MyWindow window to top!"); } OutputDebugString("End function PutMyWindowToTop!"); return TRUE; }

2. 最終分析

通過最後的除錯結果來看, 設定不設定Foreground time out 引數對結果沒有影響. 相應的程式碼可以去掉. 這個感覺是個老問題, 在論壇上找到了好多的討論, 但是並不知道為什麼. 這個還得大神來.

另外: SetActiveWindow是幹什麼的? 獲取輸入佇列?

related website:

3. others:

  1. 在pdf, EXCEL 檔案中設定超連結時, 路徑上不能有#字元.
  2. CSDN的MarkDown 編輯介面好用了一些, 但是為什麼程式碼段用黑色背景, 感覺不配啊! (雖然我在編輯程式碼的時候用黑色的! 哼!)