如何获取应用程序的活动ChildWindow?

时间:2009-05-07 12:42:49

标签: c# winapi user32 childwindow

我有这个问题:我有一个特定应用程序的mainWindow的处理程序,我想在该应用程序上模拟一个按键...

我正在使用sendMessage / postMessage api调用来执行此操作。我之所以不使用.Net SendKeys函数或win32 api的keybd_event,是因为它们在全局范围内模拟了按键。就我而言,目标应用程序不是最活跃的应用程序(其他应用程序可能在更高的z级别运行,因此覆盖了目标应用程序)。

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

获取活动子窗口的处理程序是个问题。在开始时,我使用GetTopWindow或GetWindow(GW_CHILD)api调用,因为它返回最活跃的子窗口。我正在做的是继续调用GetWindow(GW_CHILD),直到我得到一个没有更多childWindows的childwindow。这适用于记事本或油漆等应用。但是,在某些情况下(例如firefox),它不起作用。原因是父窗口具有整个firefox区域,其子窗口具有打开的WebPage(如google)。因此,当我要求mainWindow最活跃的子窗口时,它返回它所拥有的唯一子窗口,这是与网页区域对应的窗口。它仅在活动窗口是那个窗口时才有效(就像用户在某个页面的文本框上写东西一样)。但是,如果活动的是,地址栏,它不起作用,因为活动窗口不是子窗口,但实际上是父窗口......我无法以编程方式获取此信息。

我实际上找到了一种方法,使用GetGUIThreadInfo api调用,使用以下代码:

    // get thread of the main window handle of the process
    var threadId = GetWindowThreadProcessId(firefox.MainWindowHandle, IntPtr.Zero);

    // get gui info
    var info = new GUITHREADINFO();
    info.cbSize = (uint)Marshal.SizeOf(info);
    if (!GetGUIThreadInfo(threadId, out info))
        throw new Win32Exception();

    // send the letter W to the active window
    PostMessage(info.hwndActive, WM_KEYDOWN, (IntPtr)Keys.W, IntPtr.Zero);

它运作良好:如果地址栏处于活动状态,它会向地址栏发送一个“W”字母。如果谷歌的搜索文本框是活动的,它会向它发送“W”字母...完美!但是,我无法使用此方法的原因很简单: 如果目标应用程序不是操作系统的活动窗口,则ThreadInfo结构将为空。例如,如果我的目标是firefox,它会在firefox处于活动状态时运行(最顶级的应用程序,聚焦/活动的应用程序),但是,如果,假设记事本位于firefox之上,它就不起作用了,它无法获取活动窗口处理程序。

我知道我可以通过使用setForegroundWindow api调用来激活目标应用程序然后捕获活动子窗口的处理程序来解决这个问题,但我不想将目标应用程序带到前台。

我也尝试了其他技术,如AttachThreadInput()和GetFocus()api调用,这也有效,但是有同样的问题:如果目标应用程序不是活动的Windows应用程序,它就不起作用。

所以基本上我需要找到一种方法来将处理程序放到应用程序的活动子窗口中,即使该应用程序不是最活跃的应用程序。

有什么想法吗? 感谢

2 个答案:

答案 0 :(得分:1)

您可能需要查看EnumChildWindows功能。

答案 1 :(得分:0)

如果其他一切都失败了,这是另一个想法:您可能想要考虑使用WH_CBT或WH_CALLWNDPROC挂钩来监视目标线程的哪个子窗口最后聚焦。

安装CBT挂钩(WH_CBT)并侦听HCBT_SETFOCUS通知。 或者使用WH_CALLWNDPROC挂钩并侦听WM_SETFOCUS消息。

不要在hook proc中做太多事情,否则你会占用系统资源。只需保存所需的信息,然后发布自定义消息以便稍后处理。