cb200004mt_f.asp.htm

来自「C++builder学习资料C++builder」· HTM 代码 · 共 497 行 · 第 1/2 页

HTM
497
字号
the program can be "launched" by QuikLaunch. To do this, we need to delve into  

the innards of the Windows API, specifically the ToolHelp32 library. The  

ToolHelp32 library is a library of "helper" functions (hence the name) that  

provide the programmer with access to some of the internal functionality that  

Windows provides. Figure 3 shows the function that retrieves the name of the  

program that launches a window. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=Code><span class=Code><b>void</b>  

ExePathFromProcID(DWORD idProc, <b>char</b>  

*szBuffer) </span></p>  

  

<p class=Code><span class=Code>{</span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;PROCESSENTRY32 process; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hSnap; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;BOOL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f; </span></p>  

  

<p class=Code><span class=Code>&nbsp; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;szBuffer[0] = 0; </span></p>  

  

<p class=Code><span class=Code>&nbsp; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Get a &quot;snapshot&quot; of the currently running  

processes</span></i></span></p>  

  

<p class=Code><span class=Code><i><span Class=CodeBlue>&nbsp;&nbsp;// in the  

system. </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;hSnap =  

CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<b> if</b>  

(hSnap == NULL) </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> return</b>;</span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Very important!! Set the size of the structure so</span></i></span></p>  

  

<p class=Code><span class=Code><i><span Class=CodeBlue>&nbsp;&nbsp;// the  

enumeration functions know which version of the</span></i></span></p>  

  

<p class=Code><span class=Code><i><span Class=CodeBlue>&nbsp;&nbsp;// structure  

they're working with. </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;process.dwSize = <b>sizeof</b>(PROCESSENTRY32); </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;f = Process32First(hSnap, &amp;process); </span></p>  

  

<p class=Code><span class=Code>&nbsp; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Loop through all processes running in this snapshot. </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<b> while</b>  

(f) </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// Is this ours? </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> if</b>  

(process.th32ProcessID == idProc) </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;{ </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// Yes. Get the name of it and get out of here. </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hSnap); </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(szBuffer, process.szExeFile); </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b> return</b>;</span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;f = Process32Next(hSnap, &amp;process); </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Make sure the handle is closed. </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;CloseHandle(hSnap); </span></p>  

  

<p class=Code><span class=Code>}</span></p>  

  

<p class=Captions><b>Figure  

3: </b>Retrieving  

running applications' names. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> As you  

can see, the code itself isn't very complex. In fact, it's an awful lot like  

the <i>EnumWindows</i> function we looked at  

earlier. The difference is that, in this case, we're doing the enumeration with  

no callback function. Nobody has ever accused the Windows API of being  

consistent! </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> In  

ToolHelp parlance, the processes in the system represent a state of being.  

Because there's no way to guess how long the processing of these process  

entries will take, ToolHelp provides the notion of a "snapshot." This snapshot  

is a state of the system frozen in time so that, no matter how long it takes to  

process each entry, the entries in the snapshot won't change so you always have  

a reproducible state. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> The  

function in Figure 3 uses a process identifier to find and return a string  

representing the name of the executable file that launched that process. A  

structure in the ToolHelp API named PROCESSENTRY32 contains information about  

the process, including the executable name. (The "32" part of the file name  

indicates a 32-bit function; ToolHelp also existed in the old 16-bit Windows  

3.x days.) This particular bit is stored in the <i>szExeFile</i> entry, which is what we hold onto in our code. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> One last  

note on this code. To make this compile, you will need to use: </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=Code><span class=Code><span Class=CodeGrn>#include  

&lt;tlhelp32.h&gt; </span></span></p>  

  

<p class=BodyText> <span Class=CodeGrn>&nbsp; </span></p>  

  

<p class=BodyText> This is  

where the PROCESSENTRY32 structure is defined, as well as the <i  

style='mso-bidi-font-style:normal'>Process32First</i> and <i>Process32Next</i> functions. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> The only  

remaining issue, then, is how to get the process identifier for each window  

we're processing. It turns out there's a simple API function to do just that.  

The <i>GetWindowThreadProcessID</i> function  

will return the process identifier associated with a window handle. We can now  

modify the window enumeration function to read as shown in Figure 4. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=Code><span class=Code>BOOL CALLBACK  

EnumWindowsProc(HWND hwnd, LPARAM lParam) </span></p>  

  

<p class=Code><span class=Code>{</span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<b> char</b>  

szBuffer[ 256 ]; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<b> char</b>  

szFileName[ 256 ]; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<b> if</b>  

((GetWindowLong(hwnd,GWL_HWNDPARENT)==0) &amp;&amp; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (IsWindowVisible(hwnd) ||  

IsIconic(hwnd))) </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;GetWindowText(hwnd, szBuffer, 256); </span></p>  

  

<p class=Code><span class=Code>&nbsp; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;DWORD pid; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;GetWindowThreadProcessId(hwnd, &amp;pid); </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;ExePathFromProcID(pid, szFileName); </span></p>  

  

<p class=Code><span class=Code>&nbsp; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<b> if</b>  

(strlen(szFileName) &amp;&amp; strlen(szBuffer)) </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;{ </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AnsiString s = szBuffer; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += &quot; : &quot;; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s += szFileName; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Form1-&gt;ListBox1-&gt;Items-&gt;Add(s.c_str());</span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;} </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<b> return</b>  

TRUE; </span></p>  

  

<p class=Code><span class=Code>}</span></p>  

  

<p class=Captions><b>Figure  

4: </b>This modified  

window enumeration function obtains the process identifier for each window.<b></b></p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> That's  

all there is to it. If you run the program now, you should see a display  

similar to the one shown in Figure 5. </p>  

  

<p class=Subheads>&nbsp; </p>  

  

<p class=Captions><img src="images/cb200004mt_f_image004.jpg"> <br>  

<b>Figure 5: </b>The Task Manager Clone on display. </p>  

  

<p class=Subheads>&nbsp; </p>  

  

  

  

<p class=Subheads>Conclusion</p>  

  

<p class=BodyText> Congratulations.  

You have just written a simple TaskManager clone for the Windows 95 system. You  

can now view all of your running applications with their executable file names. </p>  

  

<p class=BodyText> &nbsp; </p>  

  

<p class=BodyText> <i>The  

files referenced in this article are available for <a href="download/cb200004mt_f.zip" tppabs="http://www.cbuilderzine.com/features/2000/04/cb200004mt_f/cb200004mt_d.asp">download</a>. </i></p> 

 

<p class=BodyText> &nbsp; </p> 

 

<p class=Biotext> </p> 

 

<p class=Biotext>&nbsp; </p> 

 

<p class=BodyText> &nbsp; </p> 

 

</td> 

</TR> 

</TABLE> 

 

 

</BODY> 

</HTML> 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?