这段代码是用C++编写的,涉及启动外部进程(CoppeliaSimEdu.exe)并将其窗口嵌入Qt应用程序。让我们分解成两个主要的函数:Pid2Wid 和 start_App。
Pid2Wid 函数:
WId Widget::Pid2Wid(quint64 procID, const char *lpszClassName)
{
char szBuf[256];
HWND hWnd = GetTopWindow(GetDesktopWindow());
while (hWnd)
{
DWORD wndProcID = 0;
GetWindowThreadProcessId(hWnd, &wndProcID);
if (wndProcID == procID)
{
GetClassName(hWnd, szBuf, sizeof(szBuf));
if (strcmp(szBuf, lpszClassName) == 0)
{
return (WId)hWnd;
}
}
hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
}
return 0;
}
这个函数接受进程ID(procID)和窗口类名(lpszClassName)作为参数。它迭代遍历桌面上所有顶级窗口,比较它们的进程ID和类名与提供的参数。如果找到匹配,返回该窗口的窗口句柄(WId);否则返回0。
start_App 函数:
void Widget::start_App()
{
QProcess *pProc = new QProcess(this);
connect(qApp, &QApplication::aboutToQuit, [pProc]() {
pProc->kill();
pProc->waitForFinished();
});
pProc->setProcessChannelMode(QProcess::ForwardedErrorChannel);
pProc->start("C:/Program Files/CoppeliaRobotics/CoppeliaSimEdu/coppeliaSim.exe", QStringList() << "");
pProc->waitForStarted();
pProc->waitForFinished(8000);
WId wid = Pid2Wid(pProc->processId(), "Qt5150QWindowIcon");
QWindow *pWin = QWindow::fromWinId(wid);
pWin->setFlags(pWin->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
if (pWin != NULL)
{
QWidget *pWid = QWidget::createWindowContainer(pWin, this, Qt::Widget);
Sleep(200);
pWid->setMinimumSize(100, 100);
m_Layout.addWidget(pWid);
m_Layout.update();
}
}
这个函数创建了一个新的QProcess,命名为 pProc,并连接了一个lambda函数到应用程序的aboutToQuit信号,确保外部进程在Qt应用程序即将退出时被终止。
然后,设置了进程通道模式,启动外部进程(CoppeliaSimEdu),并等待其启动和完成(最多等待8000毫秒)。
之后,使用 Pid2Wid 函数检索窗口句柄(WId),从窗口句柄创建一个 QWindow,对窗口设置了一些标志,并创建了一个 QWidget 来将窗口嵌入到Qt应用程序中。该小部件被添加到一个布局(m_Layout)中并进行更新。