I have this problem. I have an handler to the mainWindow of a certain application, and I want to simulate a keypress on that application...
我有这个问题。我有一个特定应用程序的mainWindow的处理程序,我想在该应用程序上模拟一个按键...
I'm using sendMessage/postMessage api calls to do this. The reason why I don't use the .Net SendKeys function or the keybd_event of the win32 api, is that they simulate the keypress at a global level. In my case, I may have the application minimized and still want the keypress to be simulated.
我正在使用sendMessage / postMessage api调用来执行此操作。我之所以不使用.Net SendKeys函数或win32 api的keybd_event,是因为它们在全局范围内模拟了按键。就我而言,我可能会将应用程序最小化,并且仍然希望模拟按键。
The problem with sendMessage and postMessage is that you must pass the handler of the exact childwindow where you want the key to be pressed. For example, in notepad, if I send the key to the mainWindow, nothing happens, I have to send the key to the child window that basically consists of the white canvas where you can write.
sendMessage和postMessage的问题在于您必须传递精确子窗口的处理程序,您希望按下该键。例如,在记事本中,如果我将密钥发送到mainWindow,则没有任何反应,我必须将密钥发送到子窗口,该窗口基本上由可以编写的白色画布组成。
With msPaint for example, if a user creates a new document, and opens a textbox in that drawing, and I want to simulate a keypress there, I have to get the childwindow of the childwindow of the mainwindow for it to works.
以msPaint为例,如果用户创建一个新文档,并在该图形中打开一个文本框,并且我想在那里模拟一个按键,我必须得到主窗口的子窗口的子窗口才能工作。
So I found a way that seemed to work for every situation, basically, I used getWindow with the parameter GW_CHILD, to get the child-window with the highest z-value. Then I do it again for the child window and continue doing it until a certain childWindow has no more childWindows..
所以我找到了一种似乎适用于所有情况的方法,基本上,我使用带有参数GW_CHILD的getWindow来获取具有最高z值的子窗口。然后我再次为子窗口做这个并继续这样做直到某个childWindow没有更多的childWindows ..
And it seemed to work and I was very happy!
它似乎工作,我很高兴!
However... I found cases where this does not work. Firefox is one of them. Firefox has the mainWindow, and then has a childWindow that's pretty much the same as the mainWindow and then it has another childWindow which is the website area, ie, the area under the address bar and menus. If I am on www.google.com for example, and I want to simulate a keypress in the focused search box, it works, cause getting the child-window of the child-window gives me the correct childWindow. However, if the user clicks on the address bar for example, nothing changes in the way the getWindow works. It will still eventually get the childwindow that's under the address bar, doing nothing, instead of simulating the keypress on the address bar.
但是......我发现这种情况不起作用的情况。 Firefox就是其中之一。 Firefox有mainWindow,然后有一个与mainWindow几乎相同的childWindow,然后它有另一个childWindow,即网站区域,即地址栏和菜单下的区域。例如,如果我在www.google.com上,并且我想在焦点搜索框中模拟按键,它可以工作,因为获取子窗口的子窗口会给我正确的childWindow。但是,如果用户单击地址栏,则getWindow的工作方式没有任何变化。它最终仍会获得地址栏下的子窗口,什么都不做,而不是模拟地址栏上的按键。
The thing is that I haven't found a way of getting the active child window of a certain application. I can only use the GetWindow method to get the child window of a certain window and do it until I find a child window with no childs. However, as you've seen in the firefox case, the active window is actually the parent of the child window that I get in the end.
问题是我还没有找到获取某个应用程序的活动子窗口的方法。我只能使用GetWindow方法获取某个窗口的子窗口,直到找到没有子窗口的子窗口。但是,正如您在firefox中看到的那样,活动窗口实际上是我最终得到的子窗口的父窗口。
I've tried other api calls like getTopWindow but I had no luck..
我尝试过像getTopWindow这样的其他api调用,但我没有运气..
Anyone can put some light on this issue? Thanks!
任何人都可以对这个问题有所了解吗?谢谢!
2 个解决方案
#1
If the application violates the windowing rules of windows, you'll need an exception.
如果应用程序违反了windows的窗口规则,则需要例外。
In Mozilla, it's like this (IIRC):
在Mozilla中,就像这样(IIRC):
- There's this 'god' window of the class
MozillaUIWindowClass
and with the "- Mozilla Firefox" string in its window text. - If you know the position of the address bar you can use the following function:
这是MozillaUIWindowClass类的“上帝”窗口,窗口文本中有“ - Mozilla Firefox”字符串。
如果您知道地址栏的位置,可以使用以下功能:
And provide it with the HWND
of the 'god' window and the position of the address bar.
并提供“神”窗口的HWND和地址栏的位置。
HWND ChildWindowFromPoint(HWND, POINT);
There is probably a better solution, I came up with this since I needed to automate mouse, which is position based.
可能有一个更好的解决方案,我提出这个,因为我需要自动化鼠标,这是基于位置。
For more information you might need to consult the sources of particular software, or spend whole day in Spy+. :>
有关更多信息,您可能需要查阅特定软件的来源,或在Spy +中度过一整天。 :>
#2
You can use GetGUIThreadInfo
to get info about the UI of a particular process.
您可以使用GetGUIThreadInfo获取有关特定进程的UI的信息。
If you have the main window you can call GetWindowThreadProcessId
to obtain the process thread id. Then you can call GetGUIThreadInfo
to get info about the active/focused windows, etc.
如果您有主窗口,则可以调用GetWindowThreadProcessId来获取进程线程ID。然后,您可以调用GetGUIThreadInfo来获取有关活动/聚焦窗口等的信息。
I also have to point that some applications only have one window and all its controls are windowsless (like Windows Live Messenger).
我还必须指出,某些应用程序只有一个窗口,其所有控件都是无窗口的(如Windows Live Messenger)。
#1
If the application violates the windowing rules of windows, you'll need an exception.
如果应用程序违反了windows的窗口规则,则需要例外。
In Mozilla, it's like this (IIRC):
在Mozilla中,就像这样(IIRC):
- There's this 'god' window of the class
MozillaUIWindowClass
and with the "- Mozilla Firefox" string in its window text. - If you know the position of the address bar you can use the following function:
这是MozillaUIWindowClass类的“上帝”窗口,窗口文本中有“ - Mozilla Firefox”字符串。
如果您知道地址栏的位置,可以使用以下功能:
And provide it with the HWND
of the 'god' window and the position of the address bar.
并提供“神”窗口的HWND和地址栏的位置。
HWND ChildWindowFromPoint(HWND, POINT);
There is probably a better solution, I came up with this since I needed to automate mouse, which is position based.
可能有一个更好的解决方案,我提出这个,因为我需要自动化鼠标,这是基于位置。
For more information you might need to consult the sources of particular software, or spend whole day in Spy+. :>
有关更多信息,您可能需要查阅特定软件的来源,或在Spy +中度过一整天。 :>
#2
You can use GetGUIThreadInfo
to get info about the UI of a particular process.
您可以使用GetGUIThreadInfo获取有关特定进程的UI的信息。
If you have the main window you can call GetWindowThreadProcessId
to obtain the process thread id. Then you can call GetGUIThreadInfo
to get info about the active/focused windows, etc.
如果您有主窗口,则可以调用GetWindowThreadProcessId来获取进程线程ID。然后,您可以调用GetGUIThreadInfo来获取有关活动/聚焦窗口等的信息。
I also have to point that some applications only have one window and all its controls are windowsless (like Windows Live Messenger).
我还必须指出,某些应用程序只有一个窗口,其所有控件都是无窗口的(如Windows Live Messenger)。