1

我正在使用语音操作软件(来自 Nuance 的 Dragon,或者可能是 Windows Speech Recognition(尚未尝试过))。

在操作中,用户(我)发出语音命令以使某事发生。对于这个问题,我正在尝试编写代码来启动一个简单的应用程序,例如记事本或写字板,以便它可以接收听写。另一种形式的语音命令切换应用程序以将后台应用程序(邮件、浏览器、电子表格等)带到前台,以便它可以接收语音输入。所以这不是一个“窃取焦点”的恶意软件场景;它是用户驱动的,但来自麦克风而不是键盘或鼠标。

我有一个 C# 应用程序(我们称之为 Creator),它创建了一个运行 WordPad 的新进程。我希望新创建的写字板实例在屏幕上显示为顶部窗口,就好像它是从“开始”菜单中创建的一样。

只要在创建写字板进程时 Creator 应用程序是前台应用程序,一切都会正常工作。在这种情况下,WordPad 实例按预期按 Z 顺序显示在 Creator 进程上方。

但是,如果 Creator 窗口在创建 WordPad 进程和实例时不是前台窗口,则新创建的 WordPad 实例不会出现在 Z 顺序的顶部。它出现在创建者窗口的顶部,但在创建写字板进程时,在 Z 顺序中创建者进程上方的任何其他窗口下方。

我已经阅读了很多帖子,并尝试了 , , , 和 的许多序列和变体SetForegroundWindowSetWindowPosShowWindow没有WindowRestore成功Focus。新创建的写字板实例始终创建在 Creator 窗口上方但在 Creator 窗口顶部的所有窗口下方。

我究竟做错了什么?

var proc = Process.Start(WordPadExepath);
if (proc != null) {
    // no permutation of these calls works reliably
    // rarely and randomly, the WordPad instance sometimes appears on top
    ShowWindow (proc.Handle, 1);
    Win32.SetForegroundWindow(proc.Handle);
    WinFuns.WindowRestore(new WindowHandle(proc.Handle));
    SetWindowPos (proc.Handle, new IntPtr(0), 0, 0, 0, 0, 3);
}

我理解焦点窃取的问题,下面的一位评论者提供了一个有用的链接,指向陈的一篇旧帖子。然而,Dragon 语音软件以某种方式完成了我想做的事情。“DragonBar”应用程序始终位于所有其他窗口的顶部,但允许我移动焦点并使用鼠标切换应用程序。(推断在顶部独立于作为前台应用程序是否正确?)

目前,我可以在我的应用程序中接收用户的语音请求。我的问题是如何实现用户的请求以启动新进程(和写字板)并将它们从我的小 Creator 应用程序带到前台?只要在我收到用户请求时我的 Creator 应用程序是前台/顶级应用程序,一切都很好。但是,如果我在 Creator 不是前台应用程序时收到语音请求,我将无法执行用户请求的操作。谢谢你。

4

1 回答 1

0

首先,确保进程具有当前前台窗口的前台激活权限。

根据文件SetForegroundWindow

只有当下列条件之一为真时,进程才能设置前台窗口:

  • 该进程是前台进程。
  • 该进程由前台进程启动。
  • 进程收到最后一个输入事件。
  • 没有前台进程。
  • 正在调试进程。
  • 前台进程不是现代应用程序或开始屏幕。
  • 前景未锁定(请参阅 LockSetForegroundWindow)。
  • 前台锁定超时已过期(请参阅 SystemParametersInfo 中的 SPI_GETFOREGROUNDLOCKTIMEOUT)。
  • 没有菜单处于活动状态。

其次,Process.Handle不是窗口句柄,你可以尝试使用Process.MainWindowHandle属性。

第三,如果您不确定或没有前台激活权限,您需要生成 Windows 通知,以便用户自己决定将窗口置于前台。

您可以参考以下文档:

从桌面 C# 应用发送本地 toast 通知

于 2020-02-12T08:35:14.317 回答