Windows 编程: 将目标窗口显示在最顶端
Posted 轩辕泪1020
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows 编程: 将目标窗口显示在最顶端相关的知识,希望对你有一定的参考价值。
1. [BUG Backgroud]
- 使用
SetForegroundWindow(hwnd)
不能将目标窗口弹到顶端. - 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. 最终分析
SetForegroundWindow
其实并不进行窗口z-order 次序的更改, 它所做的事就是像人一样在任务栏上点击了一下程序. https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow
通过最后的调试结果来看, 设置不设置Foreground time out 参数对结果没有影响. 相应的代码可以去掉. 这个感觉是个老问题, 在论坛上找到了好多的讨论, 但是并不知道为什么. 这个还得大神来.
另外: SetActiveWindow
是干什么的? 获取输入队列?
related website:
- 将后台窗口激活到前台的方法(使用AttachThreadInput和SetForegroundWindow两个API)–>这个在大多数情况下都是可以的, 但是在少数特定情况下不知道为什么不可以.
- SetForegroundWindow的正确用法 --> 就是按照这个来的, 恕我愚钝, 没有看出来原因.
- SetForegroundWindow、SetActiveWindow、SetFocus 如何将一个某个窗口提到最顶层
3. others:
- 在pdf, EXCEL 文件中设置超链接时, 路径上不能有
#
字符. - CSDN的MarkDown 编辑界面好用了一些, 但是为什么代码段用黑色背景, 感觉不配啊! (虽然我在编辑代码的时候用黑色的! 哼!)
以上是关于Windows 编程: 将目标窗口显示在最顶端的主要内容,如果未能解决你的问题,请参考以下文章
Windows API一日一练 38 SetWindowPos函数