1

我的情况:浏览器显示由本地运行的网络服务器提供的网页。当用户单击页面上的按钮时,我想跳转到另一个可能已经在运行的应用程序。在 Windows 上工作时,我考虑在本地运行的网络服务器中处理按钮单击,然后查找相应HWND的调用SetForegroundWindow它。

但是,就目前而言,本地运行的网络服务器没有足够的权限来SetForegroundWindow. 这些限制是有道理的,但我认为单击是一个足以证明跳转到另一个应用程序的独特事件。

我阅读了一些技术来规避这个限制并强制一个窗口进入前台:

  • AttachThreadInput:似乎是个坏主意
  • 发送热键:似乎被Chromium 项目使用,但涉及创建自己的消息循环。它的作者说它可能是一个 Windows 错误(即使旧的新事物在没有明确警告的情况下提到它)。此外,如果另一个已经调用的应用程序注册了这个热键,它就不能可靠地工作。
  • 启动一个独立的包装器(从而希望给它足够的权限SetForegroundWindow),它的唯一任务是切换到另一个应用程序:看起来很重量级,但可能比其他解决方案更容易。

以上没有一个看起来对我特别有吸引力。我有更好的选择吗?

4

1 回答 1

2

首先调用SetForegroundWindowGetForegroundWindow检查您是否获得前台状态。

如果没有,检查是否按下鼠标按钮或按下 Alt、Ctrl、Shift 或 Windows 键是可行的。在这种情况下,您不应中断用户操作(例如拖放)。

当您决定继续时,除了热键方法之外,您还有两个可行的解决方案:

1. SwitchToThisWindow,是的“此功能不适合一般使用。在Windows的后续版本中可能会更改或不可用”等,但它可以工作。

SwitchToThisWindow( hwnd, TRUE );
Sleep( 100 );
SetForegroundWindow( hwnd );

没有Sleep. 使用 TRUE,因为 FALSE 隐藏当前前景窗口。

2. 最小化/恢复。动画效果有点烦人。您可以在 DWM 处于活动状态时关闭动画

BOOL    flag = TRUE;
DwmSetWindowAttribute( hwnd, DWMWA_TRANSITIONS_FORCEDISABLED, &flag, sizeof(flag) );
ShowWindow( hwnd, SW_MINIMIZE );
ShowWindow( hwnd, SW_RESTORE );
flag = FALSE;
DwmSetWindowAttribute( hwnd, DWMWA_TRANSITIONS_FORCEDISABLED, &flag, sizeof(flag) );
SetForegroundWindow( hwnd );
于 2019-07-12T12:45:19.287 回答