[Interest] Showing QGuiApplication/QML application on a given HWND ref.

Bo Thorsen bo at vikingsoft.eu
Wed Jun 3 12:15:28 CEST 2015


Hi Nuno,

Den 03-06-2015 kl. 11:59 skrev Nuno Santos:
> Is it possible that you can provide further details about this technic?

Sure. I have the following code to do this:

     void updateGeometry() {
         // Get the current window size
         RECT windowRect;
         GetWindowRect(mWindowID, &windowRect);
         setPosition(QPoint(windowRect.left, windowRect.top));
         setSize(QSize(windowRect.right - windowRect.left + 1, 
windowRect.bottom - windowRect.top + 1));
     }

     bool registerOverlayWidget(QWidget* widget) {
         SetLastError(0);
         const HWND oldHWND = parentHWND(widget);
         qDebug() << "old hwnd" << oldHWND;
         if (SetWindowLongPtr ((HWND)widget->winId(), GWLP_HWNDPARENT, 
(LONG_PTR) mWindowID) == 0 && GetLastError() != 0) {
             // This is unreliable. Don't know why
             //qDebug() << "SetWindowLongPtr failed" << ::getLastError();
         }

         // Make sure the window has the proper size
         updateGeometry();

         const HWND newHWND = parentHWND(widget);
         qDebug() << "new hwnd" << newHWND;

         return newHWND != oldHWND;
     }

The place that does the swallow into the window of the other application 
is the SetWindowLongPtr() call. The mWindowID is the HWND of the window 
that you want to swallow into.

You have to set windows hooks to get updates on geometry changes in the 
parent window and resize the qwidget yourself. You should of course also 
listen to destroyed events.

> Do you think this technic will also be possible on Mac?

Definitely not this code. It's Windows specific. I don't know if there 
is a way to do the same on mac with another piece of code. My project is 
windows only for now. If you do figure this out, I'd love to hear about 
it, though.

> My window content will be Qml. Initially my approach was starting a
> QQmlApplicationEngine.
>
> Now, I was considering using a QWidget to takeover the give pointer
> window and instantiate a QDeclarativeView inside of it in order to have
> Qml inside the QWidget.
>
> With your suggestion, I believe you are getting the window id from the
> already created QWidget or QQmlApplicationEngine. My question is how do
> you get the window pointer from an already instantiated Qt window in
> order to try this approach?

I actually use whatever HWND is given to this. It can be a Qt window or 
any native Windows window.

>> On 03 Jun 2015, at 10:48, Bo Thorsen <bo at vikingsoft.eu
>> <mailto:bo at vikingsoft.eu>> wrote:
>>
>> Den 03-06-2015 kl. 08:56 skrev Nuno Santos:
>>> When we start a new QGuiApplication, it handles the Window creation
>>> on each platform.
>>>
>>> Now imagine that someone would give us a window ref and we wanted to
>>> put our Qt application running on it.
>>>
>>> Is this possible?
>>>
>>> I’m building a plugin for an host program that provides the window
>>> for the plugin to be shown, but Qt already opens an window.
>>>
>>> Apparently it is not possible to control if that window is provide or
>>> not. It seems to be always provided.
>>
>> In one of my projects I use the Windows setParent() function to inject
>> my window over the other applications native window. My window is a
>> transparent overlay over the other window. Works perfectly.
>>
>> Bo Thorsen,
>> Director, Viking Software.
>>
>> --
>> Viking Software
>> Qt and C++ developers for hire
>> http://www.vikingsoft.eu
>> _______________________________________________
>> Interest mailing list
>> Interest at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/interest
>

Bo Thorsen,
Director, Viking Software.

-- 
Viking Software
Qt and C++ developers for hire
http://www.vikingsoft.eu



More information about the Interest mailing list