简体   繁体   中英

create QWidget width HWND parent

OS Windows. Qt 5.5.1 I made library (dll) with GUI on Qt. I connected it to new project. I have parent's hwnd. How to set parent for library-window (Qwidget)? If use winapi SetParent(), then child window does not leave bounds the parent window. I tried QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow), but it is not working, because according to documentation the parameter window is ignored in Qt 5.

Unfortunately, this is a long-running issue with Qt on Windows (and other platforms). You'll have to find a way to hook into the parent window to catch mouse and keyboard events, etc. to propagate to your Qt child window. The internal Qt code for this is perpetually a work in progress.

There's a good page about these issues and the subject in general here . Here's the bug report discussing the issue, as well.

Note: QAxWidget isn't exactly helpful, either. It looks promising, but suffers the same issues with event propagation.

I found a way that works, but there are unknown messages on the screen

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

Let a parent window be an ownerWin, and a child one QWidget-window named childWin;

If to use SetWindowLongPtr, the desirable result is achieved (the child window overlaps the parent one), but the child window still is in the memory when the parent window closes.

To fix a problem I create one more child window (middleWin with a parent ownerWin.) using WinApi. After wrapping this window with QWidget using createWindowContainer() it stops working normally. Then using standard Qt methods we can link our QWidget window. So we have three windows: parent, intermediate and mine. Then I close middleWin using close().All that manipulations needs to insure that when ownerWin closes, also childWin closes as well. If SetWindowLongPtr is used, then childWin will always be above the parent window, but it works only if called after function show() in child window.

Below are the functions I use. First call setWinParent(), then showWindow(). In setWinParent() lines 1 through 5 is "black box" for me. I don't know why window is created that way.

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);
}

The parameter window is ignored in Qt 5. Please use QWindow::fromWinId() to create a QWindow wrapping a foreign window and pass it to QWidget::createWindowContainer() instead.

What's unclear about the Qt documentation?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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