How can I simulate mouse input in Internet Explorer without requiring the window to have focus?
I am working on a browser automation framework, one of the main tenets of which is to interact with the browser as closely as possible to the way a user would without requiring the browser window to have focus. In order to simulate clicking on, hovering on, and dragging and dropping of elements, I need to perform those events using native OS-level mechanisms rather than 开发者_开发技巧simulated JavaScript events. To that end, I'm looking for the best method for getting IE to respond properly to the simulated mouse events.
Using JavaScript or COM methods to simulate the mouse input is problematic as they may block if, for example, a JavaScript alert() or a file selection dialog is displayed.
Using the SendMessage API is unreliable. This Raymond Chen blog post talks about keyboard input, but is equally applicable to mouse input. Using SendMessage (or PostMessage) may appear to work at first, but things like hovering on elements will not work for more than a fraction of a second.
The SendInput API is designed to cleanly simulate input to the mouse and keyboard event input queues, but does so at a very low level. As such, it requires the IE window to have focus in order to receive the mouse input.
Is there a reliable way to simulate mouse input in IE using OS-level events without requiring the window to have focus? If the answer truly is, "No, there is no way to accomplish what you want," I would appreciate a pointer to an authoritative source describing why this is so for IE.
If your testing is going to require modifier keys like ALT and CTRL then SendInput is the only way. Raymond's article makes this quite clear.
I assume this is in regards to your work with Selenium. I had to do a very very similar thing at some point. As far as I'm aware this is not possible without giving the window focus and then simulating real mouse events with SendInput(). When I looked into this I ave up after a few days of investigation and resorted to an extremely hacky solution. Probably you don't want to do this but as a last resort I reverse-engineered part of IE and found the handler which mapped to the event I wanted. I then wrote code which scanned for a certain byte signature that corresponded to this handler. Fortunately it so happened that this particular piece of code didn't change much over the versions of IE I needed to test for. I then injected a DLL into IE which scanned for this signature at runtime to dynamically get the address of the handler. The DLL used IPC to take commands from another executable which would call these handlers appropriately.
I very strongly advise against this method unless you really have no alternative though because of how hacky it is and even though it might work currently there is no guarantee at all it would keep working for future updates of IE. Of course I don't need to tell you this ; )
PS. I don't know if you'll have any luck with AttachThreadInput() although I think you'll find you still will have issues with window focus.
精彩评论