原]如何隐藏system函数的窗口


修改浏览权限 | 删除


由于一直在写控制台的程序,对于MFC并不是很熟。这次写osg<——>ive格式转换器这个小工具的时候,涉及到使用setlocale函数来设置本地资源,不知道为什么在MFC中无法生效,于是只好写了一个带命令行参数的控制台程序,希望通过MFC这个界面传递参数来使用这个控制台程序。

最先想到的是system函数,因为可以通过system(const char*)函数启动另外一个程序,其实这么解决已经很好了,但是有一个小问题,就是每次执行system函数的时候,都会弹出dos窗口(命令行嘛~~~),有没有什么方法能够让我调用的程序在后台执行呢?

百度之后,发现好像无法隐藏system函数的窗口,不过有另外一种选择,就是在MFC界面中开启另外一个进程,其方法主要有三:
1. WinExec(LPCSTR, UInt)函数
其第一个参数相当于system函数的参数,第二个参数可以设置窗口是否显示,SW_HIDE这个宏表示隐藏窗口,例如:
WinExec(cmd.c_str(),SW_HIDE);//cmd(string类型)中为我们要调用的程序名及其参数, 如 “dir *.exe ”
但是这个有一个问题,这个函数创建完这个进程后就返回了,也就是说它返回后,该进程不一定已经结束,这个就有点和system不一样了,在这里我无法使用这个函数了~~~

2.ShellExecuteEx(SHELLEXECUTEINFO*)函数
其参数是一个结构体,具体作用还是类似于system的参数,使用例子:

SHELLEXECUTEINFO ShExecInfo = {0}; 
  
 ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); 
  
 ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; 
  
 ShExecInfo.hwnd = NULL; 
  
 ShExecInfo.lpVerb = NULL; 
  
 ShExecInfo.lpFile = cmd.c_str();//调用的程序名 
  
 ShExecInfo.lpParameters = par.c_str();//调用程序的命令行参数 
  
 ShExecInfo.lpDirectory = NULL; 
  
 ShExecInfo.nShow = SW_HIDE;//窗口状态为隐藏 
  
 ShExecInfo.hInstApp = NULL; 
  
 ShellExecuteEx(&ShExecInfo);


但是这个还是有问题,同1中一样,无法确定该进程是否结束~~~

3.CreateProcess函数,这个的用法可以去百度一下~~~

最后,问题归结于有没有办法使得主程序在其启动的子程序结束之前一直保持暂停状态,百度真是个好东西,几个关键词进去一搜就出来了,使用
WaitForSingleObject(HANDLE,DWORD)函数
例子:
在2的代码下加一行:WaitForSingleObject(ShExecInfo.hProcess,INFINITE);等到该进程结束

因此,我们完全可以把上述代码片段封装成一个小的函数,来代替system函数

void mySystem(const string& cmd, const string& par, int nShow) 
  
 { 
  
 SHELLEXECUTEINFO ShExecInfo = {0}; 
  
 ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); 
  
 ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; 
  
 ShExecInfo.hwnd = NULL; 
  
 ShExecInfo.lpVerb = NULL; 
  
 ShExecInfo.lpFile = cmd.c_str();//调用的程序名 
  
 ShExecInfo.lpParameters = par.c_str();//调用程序的命令行参数 
  
 ShExecInfo.lpDirectory = NULL; 
  
 ShExecInfo.nShow = SW_HIDE;//窗口状态为隐藏 
  
 ShExecInfo.hInstApp = NULL; 
  
 ShellExecuteEx(&ShExecInfo); 
  
 WaitForSingleObject(ShExecInfo.hProcess,INFINITE);等到该进程结束 
  
 }