QWidget overlay stops responding after HWND parent minimizes/restores
-
I know mixing Qt and native Win32 spells trouble, but controlling a transparent QWidget on top of a another program is just cool.
The example code puts a button and movable ellipse in a QGraphicsScene and sets notepad as its parent HWND.
It works great untill notepad is minimized/restored. The overlay shows up, but does not respond anymore to (mouse) events.
How to avoid this issue?Running Windows 7x64/Aero
mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QWidget>
#include <QtWidgets>
#include <QDebug>
#include <windows.h>class Overlay : public QWidget
{
Q_OBJECT
public:
explicit Overlay(QWidget *parent = 0) {
UNREFERENCED_PARAMETER(parent);
scene = new QGraphicsScene(this);
view = new QGraphicsView(this);
view->setScene(scene);
view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
if (!FindParentHwnd()) return;
Reposition();
TransparentThis();
setVisible(true);
HookHwnd();
InitItems();
view->setVisible(true);
}void TransparentThis() {
this->setAttribute(Qt::WA_NoSystemBackground, true);
this->setAttribute(Qt::WA_TranslucentBackground, true);
this->setAttribute(Qt::WA_ShowWithoutActivating);
this->setStyleSheet("background-color: transparent");
view->setFrameShape(QFrame::NoFrame);
this->setAutoFillBackground(true);
this->setWindowFlags(Qt::FramelessWindowHint| Qt::WindowDoesNotAcceptFocus);
}void InitItems() {
ellipse = new QGraphicsEllipseItem(0, 0, 100, 50);
QBrush redBrush(QColor(255, 0, 0, 128));
QPen blackPen(Qt::black);
blackPen.setWidth(2);
ellipse->setBrush(redBrush);
ellipse->setPen(blackPen);
ellipse->setFlag(QGraphicsItem::ItemIsMovable);
ellipse->setScale(1);
scene->addItem(ellipse);stats = new QPushButton("Button");
stats->setGeometry(QRect(0, 0, 45, 20));
stats->setMaximumSize(QSize(45, 20));
scene->addWidget(stats);
}bool FindParentHwnd()
{
ParentHwnd = FindWindow(NULL, L"Untitled - NotePad");
if (!ParentHwnd) {
qDebug() << "Failed to Find Window";
return false;
}
return true;
}bool HookHwnd()
{
LONG RetValue = SetWindowLong((HWND)effectiveWinId(), GWL_HWNDPARENT,(LONG)ParentHwnd);
if (GetLastError() && !RetValue)
{
qDebug() << QString("Overlay failed for window: %1, Error: %2").arg((DWORD)ParentHwnd).arg(GetLastError());
return false;
}
qDebug() << QString("Overlay attached to window: %1").arg((DWORD)ParentHwnd);
return true;
}void Reposition()
{
RECT lpRect;
POINT client_top_left = { 0, 0 };
GetClientRect(ParentHwnd, &lpRect);
ClientToScreen(ParentHwnd, &client_top_left);
resize(lpRect.right - lpRect.left, lpRect.bottom - lpRect.top);
move(client_top_left.x, client_top_left.y);
}private:
QGraphicsScene * scene;
QGraphicsView * view;
QGraphicsEllipseItem *ellipse;
QPushButton *stats;
HWND ParentHwnd;
QRect RectParent;protected:
void resizeEvent(QResizeEvent* event) {
view->resize(event->size());
view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
}
void showEvent(QShowEvent* event) {
UNREFERENCED_PARAMETER(event);
scene->setSceneRect(view->viewport()->rect());
}};
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();private:
Ui::MainWindow *ui;
};#endif // MAINWINDOW_H
@main.cpp
@#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Overlay O;
MainWindow w;
w.show();
return a.exec();
}MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}MainWindow::~MainWindow()
{
delete ui;
}
@ -
Hi, and welcome to the Qt Dev Net!
I'm afraid I don't know how to solve your particular problem, but I do know that there are multiple other issues related to interacting with foreign windows in Qt. Here's a compilation of issues I've found: https://bugreports.qt-project.org/browse/QTBUG-40320
Numerous other users have asked for help with working with foreign windows too, so we know that there is demand for such features. If you're willing to open a new bug report at https://bugreports.qt-project.org/ and refer to the one above, that will help build a picture of what developers are looking for. Hopefully, this will lead to better support for foreign windows.
-
Thanks.
Realizing it might be a bug I came across this report:
https://bugreports.qt-project.org/browse/QTBUG-38856
The suggested QAbstractNativeEventFilter/WM_SHOWWINDOW workaround might just work for me.