PDA

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?

jpn
9th July 2009, 08:22
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.

nish
9th July 2009, 09:03
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?

jpn
9th July 2009, 11:19
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.