Generic way to include QtGui/<QTVER>/QtGui/qpa/qplatformnativeinterface.h
-
Is there a generic way to include
qplatformnativeinterface.h
that doesn't involveQT += 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 toQPlatformNativeInterface
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. -
Hi,
Isn't QWindow::winId what you are looking for ?
-
@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.
-
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 innativeResourceForWindow()
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 isHWND 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.
-
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 ofQWindow::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.