📄 faq71.htm
字号:
</P>
<P>
<B>Note:</B> You can use the process handle to determine if the new process has finished running yet. The code example
below shows how you can wait for the Notepad program to terminate before proceeding with the program. The code calls
the <TT>GetExitCodeProcess</TT> API function to determine if the process is still active.
</P>
<pre>
<font color="navy">//-------------------------------------------------</font>
<font color="navy">// header file</font>
<font color="navy">// add a bool variable to the form class</font>
<b>private</b><b>:</b> <font color="navy">// User declarations</font>
<b>bool</b> bWaiting<b>;</b>
<b>...</b>
<font color="navy">//-------------------------------------------------</font>
<font color="navy">// source file</font>
<font color="navy">//</font>
<b>__fastcall</b> TForm1<b>:</b><b>:</b>TForm1<b>(</b>TComponent<b>*</b> Owner<b>)</b>
<b>:</b> TForm<b>(</b>Owner<b>)</b>
<b>{</b>
<font color="navy">// initialize the flag to false</font>
bWaiting <b>=</b> <b>false</b><b>;</b>
<b>}</b>
<font color="navy">//-------------------------------------------------</font>
<b>void</b> <b>__fastcall</b> TForm1<b>:</b><b>:</b>FormCloseQuery<b>(</b>TObject <b>*</b>Sender<b>,</b> <b>bool</b> <b>&</b>CanClose<b>)</b>
<b>{</b>
<font color="navy">// Use OnCloseQuery to prevent the form from</font>
<font color="navy">// closing while we are waiting for notepad.</font>
CanClose <b>=</b> <b>!</b>bWaiting<b>;</b>
<b>}</b>
<font color="navy">//-------------------------------------------------</font>
<b>void</b> <b>__fastcall</b> TForm1<b>:</b><b>:</b>Button3Click<b>(</b>TObject <b>*</b>Sender<b>)</b>
<b>{</b>
<font color="navy">// don't enter the function if we are already waiting</font>
<font color="navy">// for another instance of notepad to close.</font>
<b>if</b><b>(</b>bWaiting<b>)</b>
<b>return</b><b>;</b>
<b>char</b> szWindowDir <b>[</b>MAX_PATH<b>]</b><b>;</b>
GetWindowsDirectory<b>(</b>szWindowDir<b>,</b> MAX_PATH<b>)</b><b>;</b>
AnsiString strNotepad <b>=</b> AnsiString<b>(</b>szWindowDir<b>)</b> <b>+</b> <font color="blue">"\\notepad.exe"</font><b>;</b>
strNotepad <b>=</b> strNotepad <b>+</b> <font color="blue">" "</font> <b>+</b> <font color="blue">"c:\\cbuilder3\\deploy.txt"</font><b>;</b>
STARTUPINFO StartupInfo<b>;</b>
ZeroMemory<b>(</b> <b>&</b>StartupInfo<b>,</b> <b>sizeof</b><b>(</b>STARTUPINFO<b>)</b><b>)</b><b>;</b>
StartupInfo<b>.</b>cb <b>=</b> <b>sizeof</b><b>(</b>STARTUPINFO<b>)</b><b>;</b>
PROCESS_INFORMATION ProcessInfo<b>;</b>
<b>if</b><b>(</b>CreateProcess<b>(</b>NULL<b>,</b> strNotepad<b>.</b>c_str<b>(</b><b>)</b><b>,</b> NULL<b>,</b> NULL<b>,</b>
TRUE<b>,</b> NORMAL_PRIORITY_CLASS<b>,</b> NULL<b>,</b> NULL<b>,</b>
<b>&</b>StartupInfo<b>,</b> <b>&</b>ProcessInfo<b>)</b><b>)</b>
<b>{</b>
bWaiting <b>=</b> <b>true</b><b>;</b>
Label1<b>-></b>Caption <b>=</b> <font color="blue">"Waiting for Notepad to close"</font><b>;</b>
DWORD dwExitStatus <b>=</b> STILL_ACTIVE<b>;</b>
<font color="navy">// loop until Notepad closes</font>
<b>do</b>
<b>{</b>
<b>if</b><b>(</b> <b>!</b>GetExitCodeProcess<b>(</b>ProcessInfo<b>.</b>hProcess<b>,</b> <b>&</b>dwExitStatus<b>)</b><b>)</b>
<b>break</b><b>;</b>
Application<b>-></b>ProcessMessages<b>(</b><b>)</b><b>;</b>
<b>}</b> <b>while</b> <b>(</b>dwExitStatus <b>==</b> STILL_ACTIVE<b>)</b><b>;</b>
Label1<b>-></b>Caption <b>=</b> <font color="blue">"done"</font><b>;</b>
bWaiting <b>=</b> <b>false</b><b>;</b>
<font color="navy">// we dont' need the handles any more, so close them</font>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hProcess<b>)</b><b>;</b>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hThread<b>)</b><b>;</b>
<b>}</b>
<b>}</b>
</pre>
<P>
<B>Note:</B> When <TT>CreateProcess</TT> returns, you don't know what state the new process is in. It may be fully
initialized and on the screen, but it could also be invisible and without a window handle. Sometimes, it may be
beneficial to wait until the new process is fully initialized and visible on the screen. You can use the API
<TT>WaitForInputIdle</TT> function to pause your program until the new process is up and running.
</P>
<pre>
<b>if</b><b>(</b>CreateProcess<b>(</b>NULL<b>,</b> strNotepad<b>.</b>c_str<b>(</b><b>)</b><b>,</b> NULL<b>,</b> NULL<b>,</b>
TRUE<b>,</b> NORMAL_PRIORITY_CLASS<b>,</b> NULL<b>,</b> NULL<b>,</b>
<b>&</b>StartupInfo<b>,</b> <b>&</b>ProcessInfo<b>)</b><b>)</b>
<b>{</b>
<font color="navy">// wait for notepad to come up, time out after 2 seconds</font>
<font color="navy">// WaitForInputIdle returns 0 if the wait succeeds</font>
WaitForInputIdle<b>(</b>ProcessInfo<b>.</b>hProcess<b>,</b> <font color="blue">2000</font><b>)</b><b>;</b>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hProcess<b>)</b><b>;</b>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hThread<b>)</b><b>;</b>
<b>}</b>
</pre>
<P>
<B>Note:</B> You can also create a process in the suspended state by adding the <TT>CREATE_SUSPENDED</TT> value
to the creation flags parameter of <TT>CreateProcess</TT>. If you add the <TT>CREATE_SUSPENDED</TT> flag, the program
won't start running until until you call <TT>ResumeThread</TT>. Here is an example.
</P>
<pre>
<b>if</b><b>(</b>CreateProcess<b>(</b>NULL<b>,</b>
strNotepad<b>.</b>c_str<b>(</b><b>)</b><b>,</b>
NULL<b>,</b>
NULL<b>,</b>
TRUE<b>,</b>
NORMAL_PRIORITY_CLASS <b>|</b> CREATE_SUSPENDED<b>,</b>
NULL<b>,</b>
NULL<b>,</b>
<b>&</b>StartupInfo<b>,</b>
<b>&</b>ProcessInfo<b>)</b><b>)</b>
<b>{</b>
<font color="navy">// Make the user think something intense is happening</font>
Sleep<b>(</b><font color="blue">3000</font><b>)</b><b>;</b>
ResumeThread<b>(</b>ProcessInfo<b>.</b>hThread<b>)</b><b>;</b>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hProcess<b>)</b><b>;</b>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hThread<b>)</b><b>;</b>
<b>}</b>
</pre>
<P>
<B>Note:</B> The <TT>STARTUPINFO</TT> structure allows you to control the initial location and dimension of the
program's main window. You can also make the main window of the program come up hidden. Here is an example of how
to control the location of the new process. Keep in mind that some programs will ignore what you pass them.
</P>
<pre>
<b>void</b> <b>__fastcall</b> TForm1<b>:</b><b>:</b>Button6Click<b>(</b>TObject <b>*</b>Sender<b>)</b>
<b>{</b>
<b>char</b> szWindowDir <b>[</b>MAX_PATH<b>]</b><b>;</b>
GetWindowsDirectory<b>(</b>szWindowDir<b>,</b> MAX_PATH<b>)</b><b>;</b>
AnsiString strNotepad <b>=</b> AnsiString<b>(</b>szWindowDir<b>)</b> <b>+</b> <font color="blue">"\\notepad.exe"</font><b>;</b>
strNotepad <b>=</b> strNotepad <b>+</b> <font color="blue">" "</font> <b>+</b> <font color="blue">"c:\\cbuilder3\\deploy.txt"</font><b>;</b>
STARTUPINFO StartupInfo<b>;</b>
ZeroMemory<b>(</b> <b>&</b>StartupInfo<b>,</b> <b>sizeof</b><b>(</b>STARTUPINFO<b>)</b><b>)</b><b>;</b>
StartupInfo<b>.</b>cb <b>=</b> <b>sizeof</b><b>(</b>STARTUPINFO<b>)</b><b>;</b>
StartupInfo<b>.</b>dwX <b>=</b> <font color="blue">0</font><b>;</b>
StartupInfo<b>.</b>dwY <b>=</b> <font color="blue">0</font><b>;</b>
StartupInfo<b>.</b>dwXSize <b>=</b> Screen<b>-></b>Width <b>/</b><font color="blue">3</font><b>;</b>
StartupInfo<b>.</b>dwYSize <b>=</b> Screen<b>-></b>Height <b>/</b><font color="blue">3</font><b>;</b>
StartupInfo<b>.</b>dwFlags <b>=</b> STARTF_USEPOSITION <b>|</b> STARTF_USESIZE<b>;</b>
PROCESS_INFORMATION ProcessInfo<b>;</b>
<b>if</b><b>(</b>CreateProcess<b>(</b>NULL<b>,</b> strNotepad<b>.</b>c_str<b>(</b><b>)</b><b>,</b> NULL<b>,</b> NULL<b>,</b>
TRUE<b>,</b> NORMAL_PRIORITY_CLASS<b>,</b> NULL<b>,</b> NULL<b>,</b>
<b>&</b>StartupInfo<b>,</b> <b>&</b>ProcessInfo<b>)</b><b>)</b>
<b>{</b>
<font color="navy">// we must close the handles returned in ProcessInfo.hProcess</font>
<font color="navy">// we can close the handle at any time, might as well close it now</font>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hProcess<b>)</b><b>;</b>
CloseHandle<b>(</b>ProcessInfo<b>.</b>hThread<b>)</b><b>;</b>
<b>}</b>
<b>}</b>
</pre>
</TD> </TR>
</TABLE>
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -