本次项目中需要在客户端程序中加入3DAI进程,同时要求课固定的位置以固定的比例加载到UI界面的控件上进行使用,实现方式如下:
启动进程:
void Utils::startExe()
{
//创建进程
QString cmd = qApp->applicationDirPath() + "/test.exe -nolog";
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = true;
m_isExeStart = CreateProcess(
NULL,
(LPWSTR)cmd.toStdWString().c_str(),
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL, &si, &m_pi);
qDebug() << "-----------------------startExe CreateProcess" << m_isExeStart;
}
终止进程:
void Utils::termiateExe()
{
sendMessage("Unity application quit,");
// sendMessage(QString("ParentHandle,%1,").arg((int)m_WId));
qDebug() << "termiateExe ----- Unity application quit,";
if ( m_pi.hProcess && m_pi.hThread )
{
DWORD dwEC = 0;
BOOL b = GetExitCodeProcess(m_pi.hProcess, // handle to the process
&dwEC // termination status
);
if (b) {
TerminateProcess( m_pi.hProcess, dwEC );
}
// Close process and thread handles.
CloseHandle( m_pi.hProcess );
CloseHandle(m_pi.hThread);
qDebug() << "termiateExe";
}
}
获取外部进程WID,并通过消息通知加入到界面中:
void ExeUtil::initWindowList()
{
#ifdef Q_OS_WIN
::EnumWindows(window_callback, (LPARAM)this);
#endif
}
BOOL ExeUtil::window_callback(HWND hwnd, LPARAM lParam)
{
ExeUtil *data = (ExeUtil*)lParam;
if (!IsWindowVisible(hwnd)) {
return TRUE;
}
TCHAR title[256];
title[255] = '\0';
GetWindowText(hwnd, title, 255);
QString windowName = QString::fromStdWString(title);
if (windowName.isEmpty()) {
return TRUE;
}
if (windowName == QStringLiteral("Avater")) {
// WId a = (WId)hwnd;
// data->showExeWindow(a);
data->doShowExeWid((WId)hwnd);
}
return TRUE;
}
void ExeUtil::doShowExeWid(WId hwnd)
{
qDebug() << __FUNCTION__ << hwnd;
emit showExeWid((WId)hwnd);
}
void ReadingPage::showExeWindow(WId wid) { m_wid = wid; ::SetParent((HWND)wid, (HWND)(ui->widget_exe->winId())); QRect rect = ui->widget_exe->geometry(); ::SetWindowPos((HWND)wid, HWND_TOP, 0, 0, rect.width(), rect.height(), SWP_NOREDRAW); }
这样即可将制定的外部应用程序加载到我们自己的窗体中进行操作。