⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cb200004mt_f.asp.htm

📁 C++builder学习资料C++builder
💻 HTM
📖 第 1 页 / 共 2 页
字号:


<HTML>

  <HEAD>

  <TITLE>What's Running? </TITLE>

    

  </HEAD>

  <BODY>

   <TABLE border=0 width="100%" cellpadding=0 cellspacing=0>

<TR valign=top>

<TD width="100%">





<p class=ColumnTitle><font size="2">The API 

Calls</font></p> 

 

<p class=ColumnSubtitle>Win32 

/ ToolHelp32 / Windows 95 / Windows 98</p> 

 

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

 

<p class=Byline>By Matt  

Telles</p>  

  

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

  

<p class=StoryTitle><font size="2">What's  

Running?</font> </p>  

  

<p class=StorySubtitle><font size="2">A Task  

Manager Clone for Windows 95 and 98</font></p>  

  

<p class=BodyText> <font size="2"> &nbsp;</font> </p> 

 

<p class=BodyText> I've  

been working on a project in C++Builder, and I needed the functionality  

presented in the Task Manager in Windows NT. (Windows 95 and 98 have similar  

lists of tasks available to them, which come up when you press  [Ctrl][Alt][Delete].) The specific application would  

allow users to create a "Project" of different applications that they want to  

launch at the same time. </p>  

  

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

  

<p class=BodyText> I wanted  

the ability to show users all of the programs that were running - to capture a  

"snapshot" of the current machine state. The idea is to allow people to set up  

lists of applications they tend to run together, e.g. I run C++Builder,  

Microsoft Word, my screen image capture program, and a few utilities. I'd like  

to be able to tell Windows to just start up all of those applications at one  

time. Unfortunately, there is no simple way to do this (except at Windows  

startup), hence the QuikLaunch application. </p>  

  

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

  

<p class=BodyText> Back to  

the problem at hand. In Windows NT, it's relatively easy to get a list of the  

currently running applications. However, in Windows 95 and 98, it's a bit more  

difficult. You need to use the ToolHelp32 library for help. Before we delve too  

deeply into the application code, a little background information about how  

Task Manager "knows" what applications are running is in order. </p>  

  

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

  

<p class=BodyText> In  

Windows, each application has a "main" window (also known as a top-level  

window) and a series of child windows. When I say application, I mean only  

those applications that can show themselves on the screen. This is the same  

list that Task Manager presents. To find an application, Task Manager first  

lists all of the windows on the screen that the system knows about. It then examines  

each window to see if it's a top-level window. Once the window qualifies as a  

top-level window, the system retrieves the name of the window (the title in the  

title bar) and presents it to the user. If this were all I needed, it would be  

a simple task. Just loop through all of the windows on the screen, and display  

those that are top-level (we will discover exactly how to determine if it's a  

top-level window shortly). </p>  

  

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

  

<p class=BodyText> Unfortunately,  

I needed a little more than just that. Because I wanted to be able to launch  

each one of the applications, I needed to know the actual executable file the  

program used to launch the application. This turned out to be a little more  

complicated. Let's start with the simplest of problems: listing all of the  

top-level windows. </p>  

  

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

  

<p class=Subheads>Working  

with the API</p>  

  

<p class=BodyText> C++Builder  

VCL components don't provide a way to discover the currently running windows in  

the system. In cases like this, the next most natural thing to do is use the  

underlying Windows API. Although the VCL provides a nice level of abstraction  

and insulation from the ugliness that is the Windows kernel, sometimes you need  

to roll up your sleeves and get into it. Fortunately, as Windows API tasks go,  

this is a fairly easy one. </p>  

  

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

  

<p class=BodyText> If you  

simply want to see the names of all of the windows on the screen, here's a  

simple sample program to do just that. Create a new form in C++Builder, and put  

a single list box on it. Use the default names for the list box and the form,  

i.e. <i>ListBox1</i> and <i  

style='mso-bidi-font-style:normal'>Form1</i>, respectively. Then add the code  

shown in Figure 1 to the <i>FormCreate</i> event of the form. </p>  

  

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

  

<p class=Code><span class=Code><i><span Class=CodeBlue>// CallBack function for the EnumWindows Windows API  

function. </span></i></span></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; </span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Make sure this is a visible, or iconized, parent window. </span></i></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;<i> <span Class=CodeBlue>// Get the window title. </span></i></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;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// Only add non-blank titles. This will prevent invisible</span></i></span></p>  

  

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

from showing up. Also eliminates pop-ups. </span></i></span></p>  

  

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

(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;Form1-&gt;ListBox1-&gt;Items-&gt;Add(szBuffer); </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;<i> <span Class=CodeBlue>// You return TRUE from a callback function to continue</span></i></span></p>  

  

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

enumerating. </span></i></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=Code><span class=Code>&nbsp; </span></p>  

  

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

style='mso-bidi-font-weight:normal'>__fastcall</b> TForm1::FormCreate(TObject  

*Sender) </span></p>  

  

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

  

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Enumerate all windows. </span></i></span></p>  

  

<p class=Code><span class=Code>&nbsp;&nbsp;EnumWindows((WNDENUMPROC)EnumWindowsProc,  

0); </span></p>  

  

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

  

<p class=Captions><b>Figure  

1: </b>Building a list  

of all top-level windows. </p>  

  

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

  

<p class=BodyText> Now what  

is going on here? Well, within our <i>FormCreate</i> method, we're going to  

call the <i>EnumWindows</i> API function.  

This function will loop through every open window (top-level or not) on the  

desktop, and pass the window handle and a user-defined parameter to a callback  

function. A callback function is a function in your application to which you  

pass a pointer that Windows "calls back" when it wants to let you know about  

something. You can think of it as a sort of event handler like the VCL  

components use. </p>  

  

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

  

<p class=BodyText> In this  

case, the function we're passing to the API function is called <i  

style='mso-bidi-font-style:normal'>EnumWindowsProc</i> (that's sort of the  

default function name for this particular usage). You'll notice it's defined as  

BOOL CALLBACK. Of course, the BOOL part means you must return the Windows  

constant True or False. If you return True, the <i>EnumWindows</i> function knows you want to continue processing the  

windows. If you return False, the <i>EnumWindows</i>  

function knows you're done and stops processing windows. This is handy if you  

want to process only a few of the windows. </p>  

  

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

  

<p class=BodyText> Your  

callback function will be passed two arguments. The first is the handle of the  

window being processed. This is a standard HWND, which is the same as the <i>Handle</i>  

property of a VCL window. The second parameter is whatever you passed to the <i  

style='mso-bidi-font-style:normal'>EnumWindows</i> API function as the second  

parameter. It's called a user-defined parameter. You can store anything here,  

as long as it fits into a long value. Any address in Windows will fit here. </p>  

  

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

  

<p class=BodyText> Once we  

have the window handle passed to us, we need to see whether this fits the  

criteria of a "top-level window." The window doesn't need to have parents (the <i  

style='mso-bidi-font-style:normal'>GetWindowLong</i> call), be visible (the <i  

style='mso-bidi-font-style:normal'>IsWindowVisible</i> and <i>IsWindowIconic</i> calls), or have a title in its title bar. Once it  

passes all of these tests, we'll simply store the name of the window in our  

list box. </p>  

  

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

  

<p class=BodyText> Figure 2  

shows typical output. As you can see, the list box shows a number of windows,  

indicating the programs I happen to have running at that particular instant. </p>  

  

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

  

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

<b>Figure 2: </b>A list box shows the currently  

running applications. </p>  

  

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

  

  

  

<p class=Subheads>Getting the  

Executable Name</p>  

  

<p class=BodyText> Now  

we're down to the last problem: getting the actual executable file name so that  

⌨️ 快捷键说明

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