Qt嵌入透明窗口

本文介绍了如何在Qt应用程序中使用C++和WindowsAPI来查找窗口,并演示了如何通过设备像素比调整和自定义图形区域来实现窗口内的图像动态显示。工具MainWindow类处理了窗口位置设置、图像区域创建以及状态切换时的图形更新。
摘要由CSDN通过智能技术生成

主类:

    //要嵌入的窗口
    HWND h = FindWindow(TEXT(""), TEXT(""));
    if(h == NULL){
        QMessageBox::information(this, QString::fromUtf8("信息"), QString::fromUtf8("无法找到窗口"));
        return;
    }
    WId wid = WId(h);
    toolMainWindow->setProperty("_q_embedded_native_parent_handle", QVariant(wid));
    toolMainWindow->move(10, 0);
    toolMainWindow->show();

子类:

toolmainwindow.h

#ifndef TOOLMAINWINDOW_H
#define TOOLMAINWINDOW_H

#include <QMainWindow>
#include <Windows.h>

namespace Ui {
class ToolMainWindow;
}

class ToolMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit ToolMainWindow(QWidget *parent = nullptr);
    ~ToolMainWindow();

protected:
    void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;

private slots:
    void on_checkBoxSwitch_toggled(bool checked);

private:
    Ui::ToolMainWindow *ui;

    HRGN hRgnOn;
    HRGN hRgnOff;

    bool bNeedRefreshRgn = true;
    qreal scale = 1;

private slots:
    void on_ReCreateRgn();
};

#endif // TOOLMAINWINDOW_H

toolmainwindow.cpp

#include "toolmainwindow.h"
#include "ui_toolmainwindow.h"
#include <QTimer>
#include <QWindow>

ToolMainWindow::ToolMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ToolMainWindow)
{
    ui->setupUi(this);

    scale = window()->devicePixelRatioF();

    on_ReCreateRgn();
}

ToolMainWindow::~ToolMainWindow()
{
    DeleteObject(hRgnOn);
    DeleteObject(hRgnOff);
    delete ui;
}

void ToolMainWindow::paintEvent(QPaintEvent* event)
{
    static volatile qreal ratio = windowHandle()->devicePixelRatio();
    static QSize size0(size());

    static volatile bool bResize = false;
    if (size() != size0) {
        if(!bResize){
            QTimer::singleShot(10, this, [this](){setFixedSize(size0);});
            bResize = true;
        }
        else{
            setFixedSize(size0);
        }
    }

    if (ratio != windowHandle()->devicePixelRatio()) {;
        setFixedSize(size0.width(), size0.height() + 1);
        ratio = windowHandle()->devicePixelRatio();
    }

    if(bNeedRefreshRgn){
        if(ui->checkBoxSwitch->isChecked()){
            HRGN rgnTemp = CreateRectRgn(0, 0, width() * scale, height() * scale);
            CombineRgn(rgnTemp, hRgnOn, rgnTemp, RGN_AND);
            SetWindowRgn((HWND)winId(), rgnTemp, TRUE);
            DeleteObject(rgnTemp);
        }
        else{
            HRGN rgnTemp = CreateRectRgn(0, 0, width() * scale, height() * scale);
            CombineRgn(rgnTemp, hRgnOff, rgnTemp, RGN_AND);
            SetWindowRgn((HWND)winId(), rgnTemp, TRUE);
            DeleteObject(rgnTemp);
        }
        bNeedRefreshRgn = false;
    }

    return QMainWindow::paintEvent(event);
}

void ToolMainWindow::on_checkBoxSwitch_toggled(bool checked)
{
    bNeedRefreshRgn = true;
    ui->widget->setVisible(checked);
}

void ToolMainWindow::on_ReCreateRgn()
{
    hRgnOn = CreateRectRgn(0, 0, 0, 0);
    hRgnOff = CreateRectRgn(0, 0, 0, 0);
    HRGN rgnTemp;
    
    //凸区域
    QImage image1(":/images/stand1.png");
    for(int y = 0; y < image1.height(); ++y){
        int min = image1.width();
        int max = -1;

        for(int x = 0; x < image1.width(); ++x){
            if(image1.pixel(x, y) != 0){
                if(min == image1.width())
                    min = x;

                max = x;
            }
        }

        if(max >= min){
            rgnTemp = CreateRectRgn((ui->checkBoxSwitch->geometry().left() + min) * scale, y * scale, (ui->checkBoxSwitch->geometry().left() + max + 1) * scale, (y + 1) * scale);
            CombineRgn(hRgnOn, hRgnOn, rgnTemp, RGN_OR);
            CombineRgn(hRgnOff, hRgnOff, rgnTemp, RGN_OR);
            DeleteObject(rgnTemp);
        }
    }
    
    //凹区域
    QImage image2(":/images/stand2.png");
    for(int y = 0; y < image2.height(); ++y){
        int min = image2.width();
        int max = -1;

        for(int x = 0; x < image2.width(); ++x){
            if(image2.pixel(x, y) != 0){
                if(min == image2.width())
                    min = x;

                if(max == x - 1){
                    ++max;
                }else{
                    if(max >= min){
                        rgnTemp = CreateRectRgn(min * scale, (y + ui->widget->geometry().top()) * scale, (max + 1) * scale, (y + 1 + ui->widget->geometry().top()) * scale);
                        CombineRgn(hRgnOn, hRgnOn, rgnTemp, RGN_OR);
                        DeleteObject(rgnTemp);
                    }
                    min = x;
                    max = x;
                }
            }
        }

        if(max >= min){
            rgnTemp = CreateRectRgn(min * scale, (y + ui->widget->geometry().top()) * scale, (max + 1) * scale, (y + 1 + ui->widget->geometry().top()) * scale);
            CombineRgn(hRgnOn, hRgnOn, rgnTemp, RGN_OR);
            DeleteObject(rgnTemp);
        }
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值