35

I am trying to convert a Qt4 Application to Qt5. The only thing I couldn't figure out is how to get the HWND of a Widget. The program uses EcWin7 to show the progress on the taskbar icon on win 7+ but expects a HWND. The lib itself seems to compile fine after changing Q_WS_WIN to Q_OS_WIN) In Qt4 on Windows WId was just a typedef for HWND, so this was no problem. In Qt5 this is not the case anymore. I found some mailing list posting that could give a clue but it seems QPlatformNativeInterface is not part of the public API of Qt5 anymore.

The program calls EcWin7.init(this->winId()); and I need to some way to convert this ID into the HWND id or some other way to get this.

Josef
  • 1,467
  • 2
  • 24
  • 40
  • 3
    Well, that's strange. [QWidget::winId()](http://qt-project.org/doc/qt-5.0/qtwidgets/qwidget.html#winId) should return HWND on Windows, as it was in Qt4. – Maciej Dec 27 '12 at 09:22

5 Answers5

26

In Qt5 winEvent was replaced by nativeEvent:

bool winEvent(MSG* pMsg, long* result)

is now

bool nativeEvent(const QByteArray & eventType, void * message, long *result)

And in EcWin7::winEvent you have to cast void to MSG:

bool EcWin7::winEvent(void * message, long * result)
{
    MSG* msg = reinterpret_cast<MSG*>(message);
    if (msg->message == mTaskbarMessageId)
    {
      ...

I was able to get the application to work! Just replace:

 mWindowId = wid;

with

 mWindowId = (HWND)wid;
Strigoides
  • 4,329
  • 5
  • 23
  • 25
MrElmar
  • 288
  • 3
  • 6
  • Unfortunatly, there are a lot of bugs. Not all events are passed to real widget, a lot of them are passed to top-level widget. – Dmitry Sazonov Mar 19 '15 at 13:25
11
#include <QtGui/5.0.0/QtGui/qpa/qplatformnativeinterface.h>

static QWindow* windowForWidget(const QWidget* widget) 
{
    QWindow* window = widget->windowHandle();
    if (window)
        return window;
    const QWidget* nativeParent = widget->nativeParentWidget();
    if (nativeParent) 
        return nativeParent->windowHandle();
    return 0; 
}

HWND getHWNDForWidget(const QWidget* widget)
{
    QWindow* window = ::windowForWidget(widget);
    if (window && window->handle())
    {
        QPlatformNativeInterface* interface = QGuiApplication::platformNativeInterface();
        return static_cast<HWND>(interface->nativeResourceForWindow(QByteArrayLiteral("handle"), window));
    }
    return 0; 
}
KindDragon
  • 6,558
  • 4
  • 47
  • 75
  • 3
    corroboration, and further details how to get this to compile: http://lists.qt-project.org/pipermail/interest/2013-June/007650.html – David Burson Feb 21 '14 at 18:06
3

You may try:

(HWND)QWidget::winId();
kmatyaszek
  • 19,016
  • 9
  • 60
  • 65
TheFox
  • 39
  • 1
2

Try this function: QWindowsNativeInterface::nativeResourceForWindow

2

winId() worked for me on Qt 5.1 at least it has the same value when I'm using

bool Widget::nativeEvent(const QByteArray & eventType, void * message, long * result)
{
    MSG* msg = reinterpret_cast<MSG*>(message);
    qDebug() << msg->hwnd;

    return false;
}

and

qDebug() << winId();