It is about the communication two Qt programs under Windows. One program, let's call him Client, The other program, called Server. The situation: I want to place the Client inside a QWidget of the server. Windows already supplies some nice methods for removing the decoration (border,title bar etc..) and change the parent of a window so repainting, resizing, window activation is all taken care by Windows. When I start my Client using a QProcess I wait for it to be launched, so that there is a window I can talk to. Then I remove the decoration and set the QWidget of the Server as parent. All done with this code:
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);
}
This all works perfectly, my Client is nicely placed on top of my tab and all the repainting etc. is working perfect. BUT, The problem I'm facing is that sometimes (not always!) the servers' buttons become not responding. I noticed that when such a case happens, the buttons don't respond as long as they are located in the middle of the screen. but, the weirdest thing is that if i move the whole window so the buttons are located close to the edge of the screen - they work! if i move it back to the center - they stop working again. any idea?? someone?
I tried also the following code:
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);
with this solution, the GUI didn't freeze but the keyboard doesn't work now in the client's window - in the internal window. for example - if the internal window is notepad - i cannot type inside it but i can use the mouse. any idea what can be done?
You may try to do this by obtaining a QWindow
for the native window, and then creating a QWidget
wrapper for it. This needs at least Qt 5.2.
For example:
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.
You need to ask the winHandle
about its minimum and maximum size and pass those onto the widget
. You also need to allow the widget
to be focusable if you intend to interact with it.