Using VS - DevSource
DevSource: Microsoft Developer Resource DevSource Home Sponsored by Microsoft Home Add Ons Architecture Languages Techniques Using VS Forums
Home arrow Using VS arrow Page 4 - Working with Windows Messages in .NET
Working with Windows Messages in .NET
By John Mueller

Rate This Article: Add This Article To:

Working with Windows Messages in .NET - ' Generating Windows Messages '
( Page 4 of 4 )

Generating Windows Messages

Windows provides a number of ways to generate messages. The method you use depends on the kind of message that you want to send.

ADVERTISEMENT

This article won't discuss all of the messages, but it does examine the most common method, PostMessage().

You use the PostMethod Win32 API function to send a message to a particular window, to the current thread, or to all of the top-level windows (generally, applications and background processes such as services) in the current session.

Here's the definition for the PostMessage() method:


// Define the external function for posting a message.
[DllImport("User32.DLL", SetLastError = true)]
public static extern Boolean PostMessage(
   IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);

Of course, you need to decide on a reason for posting a message instead of simply using the functionality that the .NET Framework provides. The WM_QUIT message can be an important message when you have multiple applications that cooperate or rely on each other. This message tells other applications that the current application is ending. The .NET Framework provides three methods of ending the application:

Close();
Application.Exit();
Environment.Exit(0);

None of these three methods generates the WM_QUIT message, so no one knows that the application is terminating. Fortunately, you can create the WM_QUIT message by using the PostMessage() approach like this.

PostMessage(this.Handle, WM_QUIT, 1, 0);

You always want to provide the application handle so that other applications know which application is ending. The WM_QUIT message has a value of 0x0012. One handy way to find this value is to open a command prompt at the \Program Files\Microsoft Visual Studio 8 folder. Use the FindStr /s "WM_QUIT" *.h command to locate the value of WM_QUIT in the C++ header files that you installed to use the techniques described in this article. The WParam argument contains the exit code for this application, making this technique similar to the Environment.Exit() method. In this case, the application exits with a code of 1.

Interestingly enough, all you have to do is post the WM_QUIT message, and your .NET application will exit, just as if you had used one of the standard .NET Framework methods. However, if you watch the application from Spy++, you'll see that it now generates the WM_QUIT message so that other applications can trap it.

Sometimes you can post messages without using a function such as PostMessage() or SendMessage(). For example, the PostQuitMessage() function is an alternative for using the PostMessage() function. Listing 3 shows the same exit code using PostQuitMessage().

Listing 3: Exiting a .NET Application Using PostQuitMessage()

// Define the PostQuitMessage() function.
[DllImport("User32.DLL")]
public static extern void PostQuitMessage(Int32 nExitCode);

private void btnQuit_Click(object sender, EventArgs e)
{
   // Output a WM_QUIT message and exit the application.
   PostQuitMessage(1);
}

Unfortunately, using this approach has three limitations for .NET applications. First, the handle you see isn't the application handle; it's the CLR handle. Consequently, you know that something had posted a WM_QUIT message, but may not know what. Second, the visibility of the message is different. You can see it in Spy++ only if you choose to view all of the windows that are currently running in Windows. Third, the exit code gets lost. This function always posts a value of 0 as the exit code.

Consequently, I recommend testing all alternatives before you use them to verify that they'll work as anticipated with .NET. In this case, you should probably use the PostMessage() function instead of the PostQuitMessage() shortcut to ensure you get the desired results.

A Final Spy++ Trick

Every time you start your application, Windows assigns the windows it creates a different handle. Consequently, the message logging you set up won't work, because the window handle is wrong. You can overcome this problem for simple setups by tracking all of the windows. However, you also have access to a simple method for changing the message logging options. Click Start | Stop Logging (the button that has the stoplight icon) on the toolbar. Select the Messages | Logging Options command to display the Message Options dialog box. Use the Finder Tool to locate the new window and click OK. You're ready to monitor the new instance of the application.

Messages are an essential part of working with Windows. However, the .NET Framework hides the entire concept of messages from view because Microsoft deemed them too difficult for many developers to understand and use. The system of objects and events does work very well and you generally don't need to worry about messages at all. However, some situations require that you work with messages directly because the .NET Framework (understandably) doesn't monitor them all. This article demonstrates just two of many cases where knowing about messages can be useful.

This is the first in a series of articles that explore the concepts of windows and messages as they apply to Windows. You might be surprised at some of the extreme programming tasks you can perform by understanding these two concepts. Of course, you need to have those C++ tools available to make working with windows and messages easy.



 
 
>>> More Using VS Articles          >>> More By John Mueller
 



HD VOIP Has Arrived (with Tony Konstner)

Play Video >

All Videos >

Google and blonde jokes?

Read now >

Favorite books!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.