繁体   English   中英

创建QWidget宽度为HWND的父对象

[英]create QWidget width HWND parent

操作系统Windows。 Qt 5.5.1我在Qt上使用GUI制作了库(dll)。 我将其连接到新项目。 我有父母的房子。 如何设置库窗口(Qwidget)的父级? 如果使用winapi SetParent(),则子窗口不会超出父窗口的范围。 我尝试了QWidget :: create(WId window,bool initializeWindow,bool destroyOldWindow),但是它不起作用,因为根据文档,在Qt 5中会忽略参数window。

不幸的是,这是Windows(和其他平台)上Qt的长期运行问题。 您将必须找到一种挂接到父窗口的方法,以捕获鼠标和键盘事件等,以传播到Qt子窗口。 内部的Qt代码永远都在进行中。

关于这些问题和总体主题, 这里有一个不错的页面。 这也是讨论该问题的错误报告

注意: QAxWidget也不完全有用。 它看起来很有希望,但是在事件传播方面也遇到了同样的问题。

我找到了一种可行的方法,但是屏幕上有未知消息

windowsProc: No Qt Window found for event 0x24 (WM_GETMINMAXINFO), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x83 (WM_NCCALCSIZE), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x5 (WM_SIZE), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x3 (WM_MOVE), hwnd=0x0x110956.
setGeometryDp: Unable to set geometry 640x480+0+0 on QWindow/''. Resulting geometry:  640x480+-760+-370 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 0x0, maximum size: 16777215x16777215).
setGeometryDp: Unable to set geometry 640x480+0+0 on QWindow/''. Resulting geometry:  640x480+-760+-370 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 0x0, maximum size: 16777215x16777215).
listLabels.size() 4

假设父窗口为ownerWin,子窗口为QWidget窗口,名为childWin;

如果使用SetWindowLongPtr,则可以达到预期的效果(子窗口与父窗口重叠),但是当父窗口关闭时,子窗口仍在内存中。

为了解决问题,我使用WinApi创建了另一个子窗口(带有父ownerWin的MiddleWin)。 使用createWindowContainer()使用QWidget包装此窗口后,它将停止正常工作。 然后,使用标准的Qt方法,我们可以链接我们的QWidget窗口。 因此,我们有三个窗口:父窗口,中间窗口和我的窗口。 然后我使用close()关闭middleWin。所有这些操作都需要确保ownerWin关闭时,childWin也关闭。 如果使用SetWindowLongPtr,则childWin将始终位于父窗口上方,但仅在子窗口中的函数show()之后调用时,它才起作用。

以下是我使用的功能。 首先调用setWinParent(),然后调用showWindow()。 在setWinParent()中,第1到5行对我来说是“黑匣子”。 我不知道为什么以这种方式创建窗口。

void setWinParent(HWND ownerWin)
{
    HWND hwnd = (HWND)this->winId();
    DWORD exStyle = GetWindowLong(hwnd, GWL_EXSTYLE) ;//1
    DWORD style   = GetWindowLong(hwnd, GWL_STYLE);//2
    WCHAR className[256];//3
    GetClassName(hwnd, className,256);//4
    HWND newHwnd = CreateWindowEx(exStyle, className, NULL, style,//5
                                  CW_USEDEFAULT, CW_USEDEFAULT,
                                  CW_USEDEFAULT, CW_USEDEFAULT,
                                  ownerWin, NULL, qWinAppInst(), NULL);
    QWindow *qw=QWindow::fromWinId((WId)newHwnd);
    QWidget* qWidget = createWindowContainer(qw);
    qWidget->show();
    this->setParent(qWidget);
    this->setWindowFlags(Qt::Window);
    qWidget->close();    
}
void showWindow(HWND ownerHwnd)
{
    show();
    SetWindowLongPtr((HWND)this->winId(), GWLP_HWNDPARENT, (LONG)ownerHwnd);
}

Qt 5中将忽略参数window。请使用QWindow :: fromWinId()创建一个包装外部窗口的QWindow,并将其传递给QWidget :: createWindowContainer()。

Qt文档尚不清楚吗?

QWindow *wndParent = QWindow::fromWinId(hwnd); // hwnd - your WId
if(wndParent) 
{
    QWidget *parent = QWidget::createWindowContainer(wndParent);
    if(parent)
        // ...
}
else
{
    // unsupported window...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM