View Full Version : Using WinAPI FindWindow with Qt
emostar
9th July 2009, 07:33
Not sure if this is the right forum or not, but thought I would try asking here.
I have an application that I want to send messages via the WinAPI, so I need to get the HWND of some buttons and controls. I took a look at Spy++ to see how I can find the class names and captions to use with FindWindow, but it doesn't let me select the children of the main window. I only get one QWidget, which is the main window. I tried FindWindowEx to enumerate the children windows, but it doesn't report any.
How exactly can I find these HWNDs with the WinAPI?
Thanks!
wysota
9th July 2009, 08:03
Set a Qt::WA_NativeWindow attribute for each widget you want to have access to or call its QWidget::winId() method which will return you the handle (and create it before doing that).
emostar
9th July 2009, 08:06
Set a Qt::WA_NativeWindow attribute for each widget you want to have access to or call its QWidget::winId() method which will return you the handle (and create it before doing that).
Thanks for your reply. How would I do this when the application is a 3rd party application? My application is also in Qt, but I don't think there is anything other than the WinAPI for this kinda stuff, right?
See QxtWindowSystem (http://doc.libqxt.org/tip/classQxtWindowSystem.html).
emostar
9th July 2009, 08:28
See QxtWindowSystem (http://doc.libqxt.org/tip/classQxtWindowSystem.html).
From my understanding, this is just a wrapper around the WinAPI. So I should be able to do the same thing within my own application. If I'm not able to call FindWindow to get a button's HWND, then neither can QxtWindowSystem.
wysota
9th July 2009, 08:58
The button doesn't have a handler. If you can't rebuild the other application (or run it with Qt 4.3 or less), I'm afraid there is nothing you can do.
emostar
9th July 2009, 08:59
The button doesn't have a handler. If you can't rebuild the other application (or run it with Qt 4.3 or less), I'm afraid there is nothing you can do.
Was afraid of that :(
What about giving this a try?
http://www.qtsoftware.com/products/appdev/add-on-products/catalog/4/Windows/qtwinmigrate/
Do you think there is anything I can do with this?
Thanks.
again.. if you do not have the source .. you cant do anything
wysota
9th July 2009, 09:04
Was afraid of that :(
What about giving this a try?
http://www.qtsoftware.com/products/appdev/add-on-products/catalog/4/Windows/qtwinmigrate/
Do you think there is anything I can do with this?
Thanks.
What exactly are you trying to achieve?
emostar
9th July 2009, 09:12
What exactly are you trying to achieve?
To get data from a 3rd party application that is written in Qt. I need to iterate what looks like a QTreeList, but the application doesn't expose these qwidget's as native windows.
If this isn't possible with the normal WinAPI, I'm guessing I will have to go to a lower level to be able to extract this information.
wysota
9th July 2009, 09:20
The top level window has a handler. If you're able to calculate offsets of widgets you need to access from the top level window, you can send input events there.
emostar
9th July 2009, 09:22
The top level window has a handler. If you're able to calculate offsets of widgets you need to access from the top level window, you can send input events there.
Yes, that will work for input, but I still will have to use other means to read the text in the QTreeList, right?
One way could be to inject some code to Qt and run the application against your modified Qt. I assume this is the way for example Squish works.
emostar
9th July 2009, 11:49
One way could be to inject some code to Qt and run the application against your modified Qt. I assume this is the way for example Squish works.
Yes, code injection or api redirection appears to be the only ways possible. And I can't tell yet if Qt is using the basic WinAPI for drawing.. it appears to be Direct3D or DirectDraw on Win platforms.
wysota
9th July 2009, 12:00
One way could be to inject some code to Qt and run the application against your modified Qt. I assume this is the way for example Squish works.
The easiest way would be to run the application against a Qt that doesn't support "aliens" at all. This way the application would possibly run slower but all widgets would have real handles. I'm also wondering if there is a commandline switch disabling aliens completely for an application (turning on the opengl rendering system could also do it as opengl needs real handles, as far as I remember).
emostar
11th July 2009, 00:48
The easiest way would be to run the application against a Qt that doesn't support "aliens" at all. This way the application would possibly run slower but all widgets would have real handles. I'm also wondering if there is a commandline switch disabling aliens completely for an application (turning on the opengl rendering system could also do it as opengl needs real handles, as far as I remember).
Found it. The QT_USE_NATIVE_WINDOWS environment variable must be set to a positive integer.
I also implemented an application that injects a dll I made into the Qt application, and I am able to convert the HWND to QWidget*, cast it to the proper control and use it as necessary. The dll locks up the application when I call QMessageBox::information(), so I guess something with the event loop processing isn't working correctly.
wysota
11th July 2009, 09:27
You can't inject objects (such as events) into the other application because of different address spaces. The only thing you may do is to implement a "server" dll that can be instrumented from outside of the process (i.e. using a socket or a pipe) to do tasks from inside the process address space.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.