Получить HWND на окнах с Qt5 (из WId)
Я пытаюсь преобразовать приложение Qt4 в Qt5.
Единственное, что я не мог понять, - это получить HWND виджета.
Программа использует EcWin7, чтобы показать прогресс на значке панели задач на выигрыше 7+, но ожидает HWND. Сам lib, похоже, компилируется после изменения Q_WS_WIN на Q_OS_WIN)
В Qt4 на Windows WId был всего лишь typedef для HWND, поэтому это не проблема.
В Qt5 это уже не так.
Я нашел рассылку рассылки, которая могла бы дать ключ, но похоже, что QPlatformNativeInterface больше не является частью публичного API Qt5.
Программа вызывает EcWin7.init(this- > winId()); и мне нужно каким-то образом преобразовать этот идентификатор в идентификатор HWND или каким-либо другим способом, чтобы получить это.
Ответы
Ответ 1
В Qt5 winEvent
был заменен на nativeEvent
:
bool winEvent(MSG* pMsg, long* result)
теперь
bool nativeEvent(const QByteArray & eventType, void * message, long *result)
И в EcWin7::winEvent
вам нужно отбрасывать void
в MSG
:
bool EcWin7::winEvent(void * message, long * result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
if (msg->message == mTaskbarMessageId)
{
...
Мне удалось заставить приложение работать! Просто замените:
mWindowId = wid;
с
mWindowId = (HWND)wid;
Ответ 2
#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;
}
Ответ 3
Вы можете попробовать:
(HWND)QWidget::winId();
Ответ 4
Я искал целый день для выяснения этой проблемы. В основном я нахожу три предложенных решения:
Во-первых:
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)
{
QPlatformNativeInterface* interfacep = QGuiApplication::platformNativeInterface();
return static_cast<HWND>(interfacep->nativeResourceForWindow(QByteArrayLiteral("handle"), window));
}
return 0;
}
Во-вторых:
HWND getHWNDForWidget(const QWidget* widget)
{
QWindow* window = ::windowForWidget(widget);
if (window)
{
QPlatformNativeInterface* interfacep = QGuiApplication::platformNativeInterface();
return static_cast<HWND>(interfacep->nativeResourceForWindow(QByteArrayLiteral("handle"), window));
}
return 0;
}
Третье:
HWND hWnd = (HWND)this->winId();
В моем ноутбуке с Win8 64x, VS2010, QT5.0.1, я пробовал все это, но только третий может получить правильный HWND. Я проверил возвращенный HWND, распечатав связанный идентификатор процесса и сравнил его с показанным в диспетчере задач Windows, используя следующий код:
GetWindowThreadProcessId(hWnd, &dwWndProcID);
printf("WinID %d\n", dwWndProcID);
Однако, когда я пытался использовать этот HWND для отправки для отправки сообщений Windows из других функций. Я не могу получать сообщения в
bool winEvent(MSG* pMsg, long* result)
Это означает, что сообщение Windows никогда не работает. Есть ли у кого-нибудь представление о том, как заставить его работать?
Ответ 5
winId() работал у меня на Qt 5.1
по крайней мере, он имеет то же значение, когда я использую
bool Widget::nativeEvent(const QByteArray & eventType, void * message, long * result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
qDebug() << msg->hwnd;
return false;
}
и
qDebug() << winId();
Ответ 6
Попробуйте эту функцию: QWindowsNativeInterface::nativeResourceForWindow