16,201
社区成员
发帖
与我相关
我的任务
分享
#include <QWidget>
#include <windows.h>
class EmbedExternalWindow : public QWidget
{
Q_OBJECT
public:
HANDLE m_hRead;
HANDLE m_hWrite;
static HANDLE handle;//process handle
static HWND apphwnd;//window handle
HANDLE hProcess;//cygwin process
HANDLE hThread; //cygwin thread
explicit EmbedExternalWindow(QWidget *parent = 0);
~EmbedExternalWindow();
static int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param);
HANDLE StartProcess(LPCTSTR program);
void terminateCygwin();
void closeCygwinBash();
int CreateEmbedWindow(char* showName,char* processPath,char *params);
virtual void resizeEvent(QResizeEvent *);
virtual void closeEvent(QCloseEvent *);
public slots:
void executeCmdSlot();
};
#include <windows.h>
#include <winuser.h>
#include <Tlhelp32.h>
#include <QMouseEvent>
#include <QDebug>
#include "EmbedExternalWindow.h"
EmbedExternalWindow::EmbedExternalWindow(QWidget *parent) : QWidget(parent)
{
resize(800, 500);
setMinimumHeight(200);
}
HANDLE EmbedExternalWindow::handle = 0;//process handle
HWND EmbedExternalWindow::apphwnd = 0;//window handle
EmbedExternalWindow::~EmbedExternalWindow()
{
closeCygwinBash();//terminate the process;
}
int CALLBACK EmbedExternalWindow::EnumWindowsProc(HWND hwnd, LPARAM param)
{
DWORD pID;
DWORD TpID = GetWindowThreadProcessId(hwnd, &pID);//get process id
if (TpID == (DWORD)param)
{
EmbedExternalWindow::apphwnd=hwnd;//hwnd is the window handle
return false;
}
return true;
}
int EmbedExternalWindow::CreateEmbedWindow(char* showName,char* processPath,char*params)
{
// char ch[1024] = "C:\\cygwin64\\bin\\mintty.exe";
int num = MultiByteToWideChar(0,0,processPath,-1,NULL,0);
wchar_t *path = new wchar_t[num];
MultiByteToWideChar(0,0,processPath,-1,path,num);
// char ch1[1024] = "";
int num1 = MultiByteToWideChar(0,0,params,-1,NULL,0);
wchar_t *param = new wchar_t[num1];
MultiByteToWideChar(0,0,params,-1,param,num1);
// EmbedExternalWindow::handle = StartProcess(path, param);
EmbedExternalWindow::handle = onPipeCreate(path);
QRect rect = this->geometry();
// HWND wnd = GetActiveWindow();
if(EmbedExternalWindow::apphwnd!=NULL)
{
::SetParent(EmbedExternalWindow::apphwnd,(HWND)this->winId());
SetWindowLong(EmbedExternalWindow::apphwnd, GWL_STYLE, WS_VISIBLE);
// SetWindowLong(EmbedExternalWindow::apphwnd, GWL_STYLE, WS_BORDER);
::MoveWindow(EmbedExternalWindow::apphwnd, 0, 0,rect.width(), rect.height(), true);
this->show();
}
setWindowTitle(showName);
return 0;
}
void EmbedExternalWindow::resizeEvent(QResizeEvent *)
{
QRect rect;
rect = geometry();
// ::MoveWindow(EmbedExternalWindow::apphwnd, -8, -30,rect.width()+18, rect.height()+40, true);
::MoveWindow(EmbedExternalWindow::apphwnd, 0, 0, rect.width(), rect.height(), true);
// ShowWindow(EmbedExternalWindow::apphwnd, SW_SHOWMINIMIZED);
}
void EmbedExternalWindow::closeEvent(QCloseEvent *)
{
CloseWindow(EmbedExternalWindow::apphwnd);
CloseHandle(EmbedExternalWindow::handle);
closeCygwinBash();//terminate the process;
}
HANDLE EmbedExternalWindow::StartProcess(LPCTSTR program)
{
// HANDLE hProcess = NULL;
hProcess = NULL;
PROCESS_INFORMATION processInfo;
STARTUPINFO startupInfo;
::ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;
if(::CreateProcess(NULL, (LPTSTR)program,
NULL, // process security
NULL, // thread security
FALSE, // no inheritance
0, // no startup flags
NULL, // no special environment
NULL, // default startup directory
&startupInfo,
&processInfo))
{
Sleep(1000);
::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);//Iterate all windows
hProcess = processInfo.hProcess;
hThread = processInfo.hThread;
}
return hProcess;
}
void EmbedExternalWindow::terminateCygwin()
{
HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//-----we get info of all the process here;
//-----get data from hSnapShot into PROCESSENTRY32 structure;
//-----this structure is a process which is apart of ToolHelp32 API
//use Process32First() && Process32Next()to get process
//here we use Process32Next():
//BOOL WINAPI Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
PROCESSENTRY32* processInfoNew=new PROCESSENTRY32;
//-----set PROCESSENTRY32 's variable dwSize;
processInfoNew->dwSize=sizeof(PROCESSENTRY32);
int index=0;
int ID = 0;
while(Process32Next(hSnapShot,processInfoNew)!=FALSE)
{
index++;
int size=WideCharToMultiByte(CP_ACP,0,processInfoNew->szExeFile,-1,NULL,0,NULL,NULL);
char *ch=new char[size+1];
if(WideCharToMultiByte(CP_ACP,0,processInfoNew->szExeFile,-1,ch,size,NULL,NULL))
{
if(strstr(ch,"bash.exe"))//this is the name of process;
{
ID = processInfoNew->th32ProcessID;
// qDebug()<<"ID ="<<ID;
HANDLE hProcess;
// use TerminateProcess() to terminate the process
// here use : PROCESS_ALL_ACCESS
hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,ID);
TerminateProcess(hProcess,0);
CloseHandle(hProcess);
}
}
}
CloseHandle(hSnapShot);
delete processInfoNew;
}
void EmbedExternalWindow::closeCygwinBash()
{
// ExitProcess(processInfo.dwProcessId);
// ExitThread(processInfo.dwThreadId);
//-----only can close process "mintty", cannot close bash;
//-----now is used 'terminateCygwin()' to close bash;
TerminateProcess(hProcess,0);
CloseHandle(hProcess);
TerminateThread(hThread, 0);
CloseHandle(hThread);
}
//界面中:
void MainWindow::setupUi()
{
//------have to add a " -" after cygwin path, otherwise
//all the command in the '/bin' cannot be used;
// QString cygWinPath = "C:\\cygwin\\bin\\bash.exe --login -i";
// QString cygWinPath = "C:\\Qt\\Qt5.4.0\\Tools\\QtCreator\\bin\\qtcreator.exe";
QString cygWinPath = "cmd.exe";
EmbedExternalWindow *embedWd = new EmbedExternalWindow();
embedWd->CreateEmbedWindow(QString("Cygwin").toLatin1().data(),
QString("%1").arg(cygWinPath).toLatin1().data(),
QString("").toLatin1().data());
QWidget *centralWgt = new QWidget(this);
centralWgt->setContentsMargins(0, 0, 0, 0);
QVBoxLayout *verticalLyt = new QVBoxLayout();
verticalLyt->setContentsMargins(0, 0, 0, 0);
QPushButton *cmdBtn = new QPushButton("pwd", this);
cmdBtn->setMaximumWidth(50);
connect(cmdBtn, SIGNAL(clicked()), embedWd, SLOT(executeCmdSlot()));
verticalLyt->addWidget(cmdBtn);
verticalLyt->addWidget(embedWd);
centralWgt->setLayout(verticalLyt);
setCentralWidget(centralWgt);
}