📄 cb200004mt_f.asp.htm
字号:
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> </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> PROCESSENTRY32 process; </span></p>
<p class=Code><span class=Code> HANDLE hSnap; </span></p>
<p class=Code><span class=Code> BOOL f; </span></p>
<p class=Code><span class=Code> </span></p>
<p class=Code><span class=Code> szBuffer[0] = 0; </span></p>
<p class=Code><span class=Code> </span></p>
<p class=Code><span class=Code> <i> <span Class=CodeBlue>// Get a "snapshot" of the currently running
processes</span></i></span></p>
<p class=Code><span class=Code><i><span Class=CodeBlue> // in the
system. </span></i></span></p>
<p class=Code><span class=Code> hSnap =
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); </span></p>
<p class=Code><span class=Code> <b> if</b>
(hSnap == NULL) </span></p>
<p class=Code><span class=Code> <b> return</b>;</span></p>
<p class=Code><span class=Code> <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> // the
enumeration functions know which version of the</span></i></span></p>
<p class=Code><span class=Code><i><span Class=CodeBlue> // structure
they're working with. </span></i></span></p>
<p class=Code><span class=Code> process.dwSize = <b>sizeof</b>(PROCESSENTRY32); </span></p>
<p class=Code><span class=Code> f = Process32First(hSnap, &process); </span></p>
<p class=Code><span class=Code> </span></p>
<p class=Code><span class=Code> <i> <span Class=CodeBlue>// Loop through all processes running in this snapshot. </span></i></span></p>
<p class=Code><span class=Code> <b> while</b>
(f) </span></p>
<p class=Code><span class=Code> { </span></p>
<p class=Code><span class=Code> <i> <span Class=CodeBlue>// Is this ours? </span></i></span></p>
<p class=Code><span class=Code> <b> if</b>
(process.th32ProcessID == idProc) </span></p>
<p class=Code><span class=Code> { </span></p>
<p class=Code><span class=Code> <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> CloseHandle(hSnap); </span></p>
<p class=Code><span class=Code> strcpy(szBuffer, process.szExeFile); </span></p>
<p class=Code><span class=Code> <b> return</b>;</span></p>
<p class=Code><span class=Code> } </span></p>
<p class=Code><span class=Code> f = Process32Next(hSnap, &process); </span></p>
<p class=Code><span class=Code> } </span></p>
<p class=Code><span class=Code> <i> <span Class=CodeBlue>// Make sure the handle is closed. </span></i></span></p>
<p class=Code><span class=Code> 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> </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> </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> </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> </p>
<p class=BodyText> One last
note on this code. To make this compile, you will need to use: </p>
<p class=BodyText> </p>
<p class=Code><span class=Code><span Class=CodeGrn>#include
<tlhelp32.h> </span></span></p>
<p class=BodyText> <span Class=CodeGrn> </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> </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> </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> <b> char</b>
szBuffer[ 256 ]; </span></p>
<p class=Code><span class=Code> <b> char</b>
szFileName[ 256 ]; </span></p>
<p class=Code><span class=Code> <b> if</b>
((GetWindowLong(hwnd,GWL_HWNDPARENT)==0) && </span></p>
<p class=Code><span class=Code> (IsWindowVisible(hwnd) ||
IsIconic(hwnd))) </span></p>
<p class=Code><span class=Code> { </span></p>
<p class=Code><span class=Code> GetWindowText(hwnd, szBuffer, 256); </span></p>
<p class=Code><span class=Code> </span></p>
<p class=Code><span class=Code> DWORD pid; </span></p>
<p class=Code><span class=Code> GetWindowThreadProcessId(hwnd, &pid); </span></p>
<p class=Code><span class=Code> ExePathFromProcID(pid, szFileName); </span></p>
<p class=Code><span class=Code> </span></p>
<p class=Code><span class=Code> <b> if</b>
(strlen(szFileName) && strlen(szBuffer)) </span></p>
<p class=Code><span class=Code> { </span></p>
<p class=Code><span class=Code> AnsiString s = szBuffer; </span></p>
<p class=Code><span class=Code> s += " : "; </span></p>
<p class=Code><span class=Code> s += szFileName; </span></p>
<p class=Code><span class=Code> Form1->ListBox1->Items->Add(s.c_str());</span></p>
<p class=Code><span class=Code> } </span></p>
<p class=Code><span class=Code> } </span></p>
<p class=Code><span class=Code> <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> </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> </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> </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> </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> </p>
<p class=Biotext> </p>
<p class=Biotext> </p>
<p class=BodyText> </p>
</td>
</TR>
</TABLE>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -