Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Generic way to include QtGui/<QTVER>/QtGui/qpa/qplatformnativeinterface.h



  • Is there a generic way to include qplatformnativeinterface.h that doesn't involve QT += gui-private? We're using Visual Studio to develop, so PRO files are not an option.

    The reason we need to include that header at all is because of this line in QWinWidget.cpp:
    HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", window));

    For some infathomable reason QGuiApplication only has a forward declaration to QPlatformNativeInterface instead of including the proper header.

    Right now we need to remember to change the path whenever we upgrade Qt. This is getting somewhat tiresome. Hence my initial question.

    If there is a way to rewrite the line depending on QPlatformNativeInterface that would be a solution as well.


  • Lifetime Qt Champion

    Hi,

    Isn't QWindow::winId what you are looking for ?


  • Lifetime Qt Champion

    @marcbf said in Generic way to include QtGui/<QTVER>/QtGui/qpa/qplatformnativeinterface.h:

    For some infathomable reason QGuiApplication only has a forward declaration to QPlatformNativeInterface instead of including the proper header.

    Because the header is private.

    We're using Visual Studio to develop, so PRO files are not an option.

    So how do you create your solution files? There you also have to add your include path to the private QtGui headers.



  • @Christian-Ehrlicher Thanks for your reply. As far as I can tell that would just move the problem from the source file to the project file. It would also open up to include bits that shouldn't be included.


  • Lifetime Qt Champion

    Hi,

    Isn't QWindow::winId what you are looking for ?



  • @SGaist Thank you for your suggestion. I had been contemplating something similar. I was thrown off by the code in QWinWidget.cpp (part of QWinMigrate in the Qt Solutions). Otherwise why would there be a need to write the respective code like this:

    #if QT_VERSION >= 0x050000
            QWindow *window = windowHandle();
            window->setProperty("_q_embedded_native_parent_handle", (WId)hParent);
            HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()->
                                    nativeResourceForWindow("handle", window));
            SetParent(h, hParent);
            window->setFlags(Qt::FramelessWindowHint);
    #else
            SetParent(winId(), hParent);
    #endif
    

    Now, digging into the Windows implementation of nativeResourceForWindow() in qwindowsnativeinterface.cpp it seems that for resource type "handle" simply a handle is returned:

    void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
    {
        ...
        QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
        int type = resourceType(resource);
        if (type == HandleType)
            return bw->handle();
        ...
    }
    

    if I contrast this with the implementation of QWindow::winId() and, by extension, QWindows(Base)Window::winId(), which is what is called by the former, it seems the same id/handle as in nativeResourceForWindow() is returned.

    Indeed, a quick test reveals it to be the same value, but can I be certain this generally will be the case? Specifically, why would such a roundabout way be chosen in QWinWidget if a simple call to QWindow::winId() would suffice? That is

    HWND h = (HWND)window->winId();
    

    instead of

    HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", window));
    

    I'm sorry to pose these probably dumb questions, but I have absolutely no knowledge of the inner workings of the Qt Platform Abstraction framework.


  • Lifetime Qt Champion

    Good question and I currently don't know. However note that this class is pretty old so it might be something that has evolved in between.



  • Yeah, it's a pretty old class, but it has continually been updated (the latest version I have is from 2017). The QPA-related code was added specifically for Qt 5 (obviously :-). Qt 5 also introduced the QWindow class, which begs the question it wasn't used. Could be as simple as the developer not being aware of the implementation of QWindow::winId(). Could also be that it just doesn't quite do what it is supposed to do in this context.

    I'm going to accept your suggestion as the answer. I'm still not certain everything will work as intended, but it seems so. I guess that's as far as I'm going to get with this issue.


Log in to reply