| Language: | C |
| Category: | System |
| Date: | 2009-04-06 |
| Author: | Flenov |
Create a new Win32 Project in your Visual C++ and create a menu item in it to run the program that implements our task.
Add the following code handling the menu item to the WndProc function:
case ID_MYCOMMANDS_ISEEYOU:
while (TRUE)
{
EnumWindows(&EnumWindowsWnd, 0);
}
In this code, ID_MYCOMMANDS_ISEEYOU, is the menu item identifier.
The while loop is infinite (its condition, TRUE, will never become FALSE). Inside the loop, the EnumWindows function is called. This is a WinAPI function used to enumerate all opened windows. Its first parameter should be the address of another function that will be called each time a running window is detected. The second parameter is a number passed to the callback function.
As a callback function, the EnumWindowsWnd function is used. Therefore, every time the EnumWindows function is found, the code of the EnumWindowsWnd function will be executed. It looks like follows:
BOOL CALLBACK EnumWindowsWnd(
HWND hwnd, // handle to parent window
LPARAM lParam // application-defined value
)
{
SendMessage(hwnd, WM_SETTEXT, 0,LPARAM(LPCTSTR("I See You")));
return TRUE;
}
The number and types of the parameters and the return type should be the following:
If you change anything, the function will become incompatible with EnumWindows. To avoid mistakes, I copy the function name and its parameters from the WinAPI help file to my code. I prefer this to looking for a misprint or an accidental mistake later. I recommend you to act in a similar fashion. In this case, open the help file in the EnumWindows and follow the link that points to the format of the callback function.
Well, you have the handle for a found window. We have already used it many times when hiding or a moving window. Now learn how to change the window caption. To do this, use the SendMessage function already familiar to you that sends Windows messages. Here are its parameters:
For the program to continue looking for a next window, this function should return TRUE.
Let's make the example a little more complicated. First, change the EnumWindowsWnd function as follows:
BOOL CALLBACK EnumWindowsWnd(
HWND hwnd, // handle to parent window
LPARAM lParam // application-defined value
)
{
SendMessage(hwnd, WM_SETTEXT, 0,LPARAM(LPCTSTR("I See You")));
EnumChildWindows(hwnd,&EnumChildWnd,0);
return TRUE;
}
In this code, the EnumChildWindows function is called after sending the message. It detects all windows belonging to the main window. The function takes three parameters:
You might have noticed that the EnumChildWnd function works similarly to EnumWindowsWnd. Whereas the latter looks for all windows in the system, the first searches within the specified window.
This function also changes the caption of a found window. To continue searching, we assign TRUE to the output parameter.
Well, the program can be considered completed, but it has a flaw that I cannot keep silent about. Suppose the program found a window and started enumerating its child window, but the user suddenly closed the window. The program tries to send the message to the found window to change its caption, but the window doesn't exist any longer, and a run-time error occurs. To avoid this, check the validity of the obtained window handle:
if (h==0) return TRUE;
Now the program is finished and operable.
Remember that there are no extra checks. If you want your code to be reliable, you should check every point that might cause problems. In this book, I'll sometimes ignore this rule to avoid a complicated and entangled code. However, I'll point to those spots in the code that require special attention.