创建QWidget宽度HWND父级

时间:2018-04-05 06:24:37

标签: c++ qt

OS Windows。 Qt 5.5.1 我在Qt上用GUI制作了库(dll)。 我将它连接到新项目。我有父母的骄傲。如何为库窗口(Qwidget)设置父级? 如果使用winapi SetParent(),则子窗口不会离开父窗口的边界。 我尝试了QWidget :: create(WId window,bool initializeWindow,bool destroyOldWindow),但它无法正常工作,因为根据文档,Qt 5中忽略了参数窗口。

3 个答案:

答案 0 :(得分:0)

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

关于这些问题和一般主题here,这是一个很好的页面。这里也是讨论这个问题的bug report

注意:QAxWidget也不是很有帮助。它看起来很有希望,但遇到与事件传播相同的问题。

答案 1 :(得分:0)

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

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,子窗口名为childWin的一个QWidget窗口;

如果要使用SetWindowLongPtr,则会实现所需的结果(子窗口与父窗口重叠),但父窗口关闭时,子窗口仍在内存中。

要解决问题,我使用WinApi再创建一个子窗口(middleWin with parent ownerWin。)。使用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);
}

答案 2 :(得分:-1)

  

Qt 5中忽略参数窗口。请使用   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...
}