c++ 创建QWidget宽度HWND父级

9gm1akwq  于 2023-03-25  发布在  其他
关注(0)|答案(4)|浏览(216)

操作系统Windows. Qt 5.5.1我在Qt上用GUI做了库(dll)。我把它连接到了新项目。我有parent的hwnd。如何为库窗口(Qwidget)设置parent?如果使用winapi SetParent(),那么子窗口不会离开父窗口的边界。我尝试了QWidget::create(WId window,bool initializeWindow,bool destroyOldWindow),但它不起作用,因为根据文档,参数window在Qt 5中被忽略了。

n3h0vuf2

n3h0vuf21#

我找到了一个有效的方法,但是屏幕上有未知的信息

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和一个父窗口ownerWin.)。在使用createWindowContainer()用QWidget Package 这个窗口后,它停止正常工作。然后使用标准的Qt方法,我们可以链接我们的QWidget窗口。所以我们有三个窗口:parent,intermediate和mine。然后我使用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);
}
oyxsuwqo

oyxsuwqo2#

不幸的是,这是一个长期运行在Windows(和其他平台)上的Qt问题。你必须找到一种方法来挂钩到父窗口,以捕捉鼠标和键盘事件,等等,以传播到你的Qt子窗口。内部Qt代码为此是一个永远在进行中的工作。
有一个很好的页面介绍了这些问题和一般的主题here,这里也有讨论这个问题的bug report
注意:QAxWidget也不是很有帮助,它看起来很有前途,但是在事件传播方面也有同样的问题。

elcex8rz

elcex8rz3#

在Windows上的pyqt4中你可以使用这个。当然你可以在c++中找到一些东西

import win32gui
from PyQt4.QtGui import QDialog
    
class MyCustomDialog(QDialog):
    def __init__(self, parent):
        if isinstance(parent, int):
            QDialog.__init__(self, None)
            win32gui.SetParent(self.winId(), parent) #<-this set the parent window
        else:
            QDialog.__init__(self, parent)
wz3gfoph

wz3gfoph4#

在Qt 5中,参数window被忽略。请使用QWindow::fromWinId()创建一个 Package 外部窗口的QWindow,并将其传递给QWidget::createWindowContainer()。
Qt文档有什么不清楚的地方?

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

相关问题