oracle3001
oracle3001

Reputation: 1100

Displaying a QT Widget on / overlaying a 3rd Party Window (in Windows)

This is not something I have tried before and am a complete newbie to the likes of HWND, hooking etc.

Basically, I would like to display / overlay a QT Widget on top of a window of a 3rd party application (which I have no control over, I only know very basic information like window title / caption and its class name) and I have absolutely no idea how one would go about this. I also want the QT Widget to remain in it relative location to the window of the 3rd party application, even if that window is moved around the screen.

Upvotes: 2

Views: 5044

Answers (1)

Pavel Strakhov
Pavel Strakhov

Reputation: 40502

WinAPI part

  1. Use FindWindow function to obtain HWND of the target window.
  2. Use GetWindowRect to obtain current position of the window.

Qt part

  1. Make your top level QWidget or QMainWindow frameless and make it to stay on top using window flags Qt::FramelessWindowHint and Qt::WindowStaysOnTopHint.
  2. Make it transparent using attribute Qt::WA_TranslucentBackground.
  3. Setup a QTimer to request window rect periodically and adjust the widget position.

Example code (tested)

Add in header:

private:
  HWND target_window;

private slots:
  void update_pos();

Source:

#include "Windows.h"
#include <QDebug>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
  setAttribute(Qt::WA_TranslucentBackground);
  // example of target window class: "Notepad++"
  target_window = FindWindowA("Notepad++", 0); 
  if (!target_window) {
    qDebug() << "window not found";
    return;
  }
  QTimer* timer = new QTimer(this);
  connect(timer, SIGNAL(timeout()), this, SLOT(update_pos()));
  timer->start(50); // update interval in milliseconds 
}

MainWindow::~MainWindow() {
  delete ui;
}

void MainWindow::update_pos() {
  RECT rect;
  if (GetWindowRect(target_window, &rect)) {
    setGeometry(rect.left, rect.top, rect.right - rect.left, 
                rect.bottom - rect.top);
  } else {
    //maybe window was closed
    qDebug() << "GetWindowRect failed";
    QApplication::quit();
  }
}

Upvotes: 5

Related Questions