它是关于Windows下的两个Qt程序的通信。 一个程序,让我们称他为Client,另一个程序叫做Server。 情况: 我想将客户端放在服务器的QWidget中。 Windows已经提供了一些很好的方法来删除装饰(边框,标题栏等)并更改窗口的父级,因此重新绘制,调整大小,窗口激活都由Windows完成。 当我使用QProcess启动我的客户端时,我等待它启动,以便有一个我可以与之交谈的窗口。然后我删除装饰并将服务器的QWidget设置为父级。 完成所有这些代码:
winHandle = ::FindWindowA(NULL, "My Client");//get clients window id
if(winHandle != NULL)
{
::ShowWindow(winHandle, SW_HIDE);
// Remove the window border
LONG lStyle = GetWindowLong(winHandle, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
::SetWindowLong(winHandle, GWL_STYLE, lStyle);
::SetParent(winHandle, (HWND)(ui->widget->effectiveWinId()));//set the server's widget to be the parent of the client win
::SetWindowPos(winHandle, HWND_TOP, ui->widget->pos().x(), ui->widget->pos().y(), 0, 0 , SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_ASYNCWINDOWPOS);
::UpdateWindow(winHandle);
::ShowWindow(winHandle, SW_SHOW);
}
这一切都很完美,我的客户很好地放在我的标签上,所有重新绘制等都很完美。 但是,我面临的问题是,有时(并非总是!)服务器按钮无响应。 我注意到,当发生这种情况时,只要它们位于屏幕中间,按钮就不会响应。但是,最奇怪的是,如果我移动整个窗口使按钮靠近屏幕边缘 - 它们可以工作!如果我把它移回中心 - 他们会再次停止工作。 任何的想法??有人?
我还尝试了以下代码:
QWindow * window = QWindow::fromWinId((WId) winHandle);
QWidget * widget = QWidget::createWindowContainer(window);
widget->setParent( ui->widget);
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(widget);
ui->widget->setLayout(layout);
使用此解决方案, GUI未冻结但键盘现在无法在客户端窗口中工作 - 在内部窗口中。 例如 - 如果内部窗口是记事本 - 我不能在里面键入,但我可以使用鼠标。 知道可以做什么吗?
答案 0 :(得分:0)
您可以尝试通过为本机窗口获取QWindow
,然后为其创建QWidget
包装器来执行此操作。这至少需要Qt 5.2。
例如:
HWND winHandle = ::FindWindowA(NULL, "My Client");
if (! winHandle) return;
QWindow * window = QWindow::fromWinId((WId)winHandle);
if (! window) return;
QWidget * widget = QWidget::createWindowContainer(window);
if (! widget) return;
// At this point you can use Qt to change window flags, reparent/embed, etc.
您需要询问关于its minimum and maximum size的winHandle
并将其传递到widget
。如果您打算与widget
进行交互,还需要允许{{1}}成为焦点。
答案 1 :(得分:0)
清除要重新分配的窗口的WS_POPUP样式,并改为设置WS_CHILD位。否则,我认为SetParent实际上建立了一个所有者/拥有的关系,而不是父/子关系。
当你重新定位孩子时,它应该在父母的客户坐标中。您使用屏幕坐标的事实是一个很好的暗示,您没有正确的父/子关系。 (这也与在屏幕左上角附近工作的UI一致,屏幕坐标非常靠近客户坐标。)
尽管有负面评论,但可以使所有内容与跨进程父/子窗口一起使用。也就是说, 可能难以做到正确。