使用Qt嵌入外部exe,拖动窗口后出现窗口绘制残留问题

现象

        通过Qt提供的QWidget::createWindowContainer()方法得到外部exe的QWidget容器,添加到自己程序的主窗口中,成功实现exe的嵌入,鼠标交互与页面都没有问题,但是在改变主窗口大小后,外部嵌入的窗口绘制出现了残留,现象代码如下:

WId Id = (WId)FindWindowA("外部exe类名","外部exe名");
ui.wWindow = QWindow::fromWinId(Id);
if(wWindow)
{
    wContainer = QWidget::createWindowContainer(wWindow,this);
}
if(wContainer)
{
    ui.dockwidget->setWidget(wContainer);
}

解决方案

1.Qt提供方案(未能解决本人问题,大家可自行尝试)

// 使用Qt的窗口容器API
QWindow *externalWindow = QWindow::fromWinId((WId)hwndChild);
QWidget *container = QWidget::createWindowContainer(externalWindow, this);

// 关键设置
container->setAttribute(Qt::WA_TranslucentBackground);
container->setAttribute(Qt::WA_OpaquePaintEvent, false);
container->setAttribute(Qt::WA_NoSystemBackground, true);
container->setContentsMargins(0, 0, 0, 0);

// 重要:启用持续更新
container->setUpdatesEnabled(true);

2.仅适用于Windows平台,使用Windows提供的API设置窗口属性后,再利用Qt做嵌入(成功解决窗口重绘的问题,但是影响了鼠标缩放功能,鼠标点击事件的响应也变得卡顿)

WId Id = (WId)FindWindowA("外部exe类名","外部exe名");
ui.wWindow = QWindow::fromWinId(Id);
if(wWindow)
{
    HWND hwndAdView = (HWND) Id;
    SetWindowLongPtr((HWND)Id,
                  GWL_STYLE,GetWindowLongPtr((HWND)Id,GWL_STYLE) | WS_CLIPCHILDREN);
    LONG_PTR exStyle = GetWindowLongPtr(hwndAdView, GWL_EXSTYLE);
    SetWindowLongPtr(hwndAdView,GWL_EXSTYLE, exStyle | WS_EX_COMPOSITED);
    LONG style = GetWindowLong(hwndAdView, GWL_STYLE);
    SetWindowLong(hwndAdView, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME));
    wContainer = QWidget::createWindowContainer(wWindow,this);
}
if(wContainer)
{
    ui.dockwidget->setWidget(wContainer);
}

3.鼠标缩放事件不响应排查后确定为窗口样式导致,在2所示的代码中,去掉窗样式WS_EX_COMPOSITED,改为SetWindowLongPtr(hwndAdView,GWL_EXSTYLE, exStyle);鼠标的缩放功能可以用了,完美解决。

       但目前博主并未找到更好的跨平台方法,如有其他更好的方法请各位大神指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值