1

我有这个问题。我有一个特定应用程序主窗口的处理程序,我想模拟该应用程序上的按键...

我正在使用 sendMessage/postMessage api 调用来执行此操作。我不使用 .Net SendKeys 函数或 win32 api 的 keybd_event 的原因是它们在全局级别模拟按键。就我而言,我可能已将应用程序最小化,但仍希望模拟按键。

sendMessage 和 postMessage 的问题在于,您必须传递要按下键的确切子窗口的处理程序。例如,在记事本中,如果我将密钥发送到主窗口,没有任何反应,我必须将密钥发送到基本上由白色画布组成的子窗口,您可以在其中进行书写。

以 msPaint 为例,如果用户创建一个新文档,并在该绘图中打开一个文本框,并且我想在那里模拟按键,我必须获取主窗口的子窗口的子窗口才能使其工作。

所以我找到了一种似乎适用于所有情况的方法,基本上,我使用带有参数 GW_CHILD 的 getWindow 来获取具有最高 z 值的子窗口。然后我为子窗口再次执行此操作并继续执行此操作,直到某个 childWindow 没有更多 childWindows..

它似乎奏效了,我很高兴!

但是......我发现这不起作用的情况。火狐就是其中之一。Firefox 有 mainWindow,然后有一个与 mainWindow 几乎相同的 childWindow,然后它还有另一个 childWindow,即网站区域,即地址栏和菜单下方的区域。例如,如果我在 www.google.com 上,并且我想在焦点搜索框中模拟按键,它会起作用,因为获取子窗口的子窗口会给我正确的 childWindow。但是,例如,如果用户单击地址栏,getWindow 的工作方式不会发生任何变化。它最终仍然会得到地址栏下的子窗口,什么都不做,而不是模拟地址栏上的按键。

问题是我还没有找到获取某个应用程序的活动子窗口的方法。我只能使用GetWindow方法来获取某个窗口的子窗口,直到找到没有子窗口的子窗口。但是,正如您在 firefox 案例中看到的那样,活动窗口实际上是我最终得到的子窗口的父级。

我尝试过其他 api 调用,如 getTopWindow 但我没有运气..

任何人都可以对这个问题有所了解吗?谢谢!

4

2 回答 2

0

您可以使用它GetGUIThreadInfo来获取有关特定进程的 UI 的信息。

如果您有主窗口,则可以调用GetWindowThreadProcessId以获取进程线程 ID。然后您可以调用GetGUIThreadInfo以获取有关活动/聚焦窗口等的信息。

我还必须指出,一些应用程序只有一个窗口,并且它的所有控件都是无窗口的(如 Windows Live Messenger)。

于 2009-05-06T20:43:02.063 回答
0

如果应用程序违反了窗口的窗口规则,您将需要一个例外。

在 Mozilla 中,它是这样的(IIRC):

  • 有这个类的“上帝”窗口,MozillaUIWindowClass在其窗口文本中带有“-Mozilla Firefox”字符串。
  • 如果您知道地址栏的位置,您可以使用以下函数:

并提供HWND“上帝”窗口的位置和地址栏的位置。

HWND ChildWindowFromPoint(HWND, POINT);

可能有一个更好的解决方案,我想出了这个,因为我需要自动化鼠标,这是基于位置的。

如需更多信息,您可能需要查阅特定软件的来源,或在 Spy+ 中度过一整天。:>

于 2009-05-06T20:25:24.367 回答