C++ 在第三方窗口上显示/覆盖QT小部件(在Windows中)

C++ 在第三方窗口上显示/覆盖QT小部件(在Windows中),c++,qt,winapi,overlay,hook,C++,Qt,Winapi,Overlay,Hook,这不是我以前尝试过的东西,我对HWND、钩拳等完全是新手 基本上,我想在第三方应用程序的窗口上显示/覆盖一个QT小部件(我无法控制,我只知道非常基本的信息,如窗口标题/标题及其类名),我完全不知道该怎么做。我还希望QT小部件保持在相对于第三方应用程序窗口的位置,即使该窗口在屏幕上移动。WinAPI部分 使用函数获取目标窗口的HWND 用于获取窗口的当前位置 Qt部分 使用Qt::FramelessWindowHint和Qt::WindowStaysOnTopHint使顶级QWidget或QMai

这不是我以前尝试过的东西,我对HWND、钩拳等完全是新手

基本上,我想在第三方应用程序的窗口上显示/覆盖一个QT小部件(我无法控制,我只知道非常基本的信息,如窗口标题/标题及其类名),我完全不知道该怎么做。我还希望QT小部件保持在相对于第三方应用程序窗口的位置,即使该窗口在屏幕上移动。

WinAPI部分
  • 使用函数获取目标窗口的HWND
  • 用于获取窗口的当前位置
  • Qt部分
  • 使用
    Qt::FramelessWindowHint
    Qt::WindowStaysOnTopHint
    使顶级
    QWidget
    QMainWindow
    无框架,并使其保持在顶级
  • 使用
    Qt::WA_TranslucentBackground
    使其透明
  • 设置
    QTimer
    定期请求窗口rect并调整小部件位置
  • 示例代码(已测试) 外接程序标题:

    private:
      HWND target_window;
    
    private slots:
      void update_pos();
    
    资料来源:

    #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();
      }
    }
    
    #包括“Windows.h”
    #包括
    #包括
    主窗口::主窗口(QWidget*父窗口):
    QMainWindow(父级),
    用户界面(新用户界面::主窗口)
    {
    用户界面->设置用户界面(此);
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_半透明背景);
    //目标窗口类示例:“记事本++”
    target_window=FindWindowA(“记事本++”,0);
    如果(!目标窗口){
    qDebug()start(50);//更新间隔(毫秒)
    }
    MainWindow::~MainWindow(){
    删除用户界面;
    }
    void主窗口::更新位置(){
    RECT-RECT;
    if(GetWindowRect(目标窗口和rect)){
    setGeometry(rect.left、rect.top、rect.right-rect.left、,
    矩形底部-矩形顶部);
    }否则{
    //也许窗户是关着的
    
    qDebug()我终于开始尝试你的建议,我发现发生的是Qt::WindowStaysOnTopHint,结果当然是Qt窗口始终位于顶部,但也允许第三个窗口在中间移动。我如何修改此代码,以便覆盖层刚好覆盖已识别的winapi窗口,第三个窗口是否应该是dra用QT覆盖在目标窗口上,它是位于顶部的,反之亦然,也就是说,QT覆盖在目标窗口上方的一层上总是按z顺序渲染。我不确定,但我认为这是不可能的。