Microsoft Cloud Authors: Pat Romanski, Andreas Grabner, Nick Basinger, Kevin Benedict, Liz McMillan

Related Topics: Microsoft Cloud

Microsoft Cloud: Article

Microsoft .NET Feature Story - Powerful Forms Interaction

Receiving obscure Windows messages

Microsoft Windows provides great power in manipulating the forms in your application, however, the .NET Framework masks a lot of what can be done to your forms for consistency and ease of use.

You have probably seen applications that control their size and positions with greater fluidity than you can get with normal .NET Forms, such as maintaining an aspect ratio while resizing, or docking to the side of a screen. Thankfully there are ways of gaining access to the more powerful aspects of Windows, but they are a bit ugly. In this article, I want to help you write a subclass of Form, which has greater power over its position - namely, I would like to keep the form from ever leaving the screen, not even a part of the side. In the process, we will explore ways to find out about the messages that Windows sends to forms, and how to retrieve their extra data and process those messages in custom ways.

The code in this article was written using C# and Visual Studio 2005. This code can be converted to VB and created using Visual Studio 2002 and 2003.

Appearance While Forms Move
As you move a form around, Windows can do one of two things, depending on how it is configured:

  • Appearance (A): Windows will move the form with your mouse.
  • Performance (B): Windows will give you an outlined preview of where the form will be placed and will move the form only when the mouse is released.
You should test your code in both configurations to see how it works. In Windows XP, switching configurations is straightforward:
  1. Right-click on "My Computer" and select "Properties."
  2. Go to the "Advanced" tab.
  3. Under "Performance" click "Settings."
  4. Select "Adjust for best performance" or "Adjust for best appearance," depending on which you would prefer.
  5. Click "OK."
Windows will take a moment to switch between visual styles. For quicker switching, you may want to choose "Custom" and check and uncheck "Show window contents while dragging." This "windows contents" effect is the only important effect for positioning forms.

Pure .NET Approach
To keep a form on the screen using a typical approach in C#, we would create a form and in the OnMove method we would write the code in Listing 1.

Depending on whether you have Windows, move window contents with your mouse (A), or not, (B), and you will see two different effects:

  • A: As you move the form outside the bounds of the screen, it will flicker back and forth between where Windows wants to put it, and where you want to put it.
  • B: The preview outline will go outside the screen, and on mouse-up, the form will appear inside the screen.
Neither of these effects is very desirable. Although option B is a little better, you do not have control over the user's environment to force that effect. Unfortunately, the .NET Framework does not naturally provide a way for you to improve these effects. Windows (Win32) does provide ways for you to control these effects, though. But before we can delve too much into Win32 code (which is a little ugly and nasty compared to .NET code), we need to get a little history lesson.

A Message-Based OS
Win32 is a message-based operating system. The Move event we caught in Listing 1 was the result of a common message that Win32 generates for us. The process of how this event is normally handled by programmers is illustrated in Figure 1. Windows first generates the "move" message, which is defined by a constant called WM_MOVE, and places that message into the "message queue" of your application (step 1). At the root of all Windows applications is a special piece of code called the "message pump" (see figure 1) which continually grabs and processes messages from the queue. In this case, it takes the WM_MOVE message (step 2) and hands it off to the WndProc method of the form that needs to process it (step 3). We will further explore the WndProc method later. The .NET Framework then processes the message and ultimately calls the OnMove method. This method raises the Move event, which calls all registered Move event handlers (step 4). In one of these handlers, programmers typically perform custom processing relevant to that event. To save some time, we subclassed Form directly, then performed an override of the OnMove method, which is where we put our custom code - the style of programming to use when catching events on the object that raises them. You should always call the base implementation of all OnWhatever methods you override so the base class can raise the associated event for any listeners. Catching events through event handlers is usually best for external classes being notified when things happen. For example, a form will register for a Button Click event because the Form class is external to the Button class.

Every time you press a button on your keyboard, Win32 typically generates three messages that get processed by your application: a WM_KEYDOWN, WM_KEYUP, and WM_CHAR. Pressing mouse buttons typically generates two other messages (e.g., WM_LBUTTONDOWN and WM_LBUTTONUP). As an application is moved on the screen, properties are changed, or painting needs to occur, dozens to hundreds of messages are generated. Across the life of an application, thousands of messages are generated and passed to your application, and sometimes from your application back to Windows.

Your application even generates messages and sends them to itself. All these messages must be processed by the message pump, and can only be generated by the thread the message pump is on; otherwise Win32 cannot keep messages and their data synchronized. As a result, alternate threads that try to alter properties on a Form must do so by using the Control.Invoke method. I bring this up to warn and inform you about the legacy of Win32 code: you will have to read up on the details of that method on your own.

Microsoft has thousands of different messages defined for different events that occur in Win32. These messages are the common ones, such as painting a form, typing characters, and mouse movements. There are also exotic messages such as tree-view node expansion, click or collapse, and logon/logoff events. If you want a look at some of these messages, search for and open the "WinUser.h" file on your computer: it will be deep inside the "Program Files" directory, wherever you have installed the Visual C++ (VC7 or VC8), if you have it installed. This file contains many of the messages that Win32 will process. Here is a taste of the contents of this file:

#define WM_KEYDOWN 0x0100
#define WM_KEYUP 0x0101
#define WM_CHAR 0x0102

There are a lot of #define statements in this file; some of them are messages, and others are constants related to these messages. Thankfully, Microsoft is a very rigid company when it comes to their coding standards. Once you know some key things about reading their source code, you can read just about anything written there. For example, many of the messages sent by Win32 start with WM_, which is short for "Windows Message." Constants that are related all start with the same characters, followed by an underscore. If you have your MSDN documents installed and unfiltered, you can type in one of these message names into the index and read all about that message. For example, type in WM_SIZE, and you can find out about the Size event, and the different constants that can be passed in with it (each constant starts with SIZE_).

The WndProc method
The message pump is the core piece of code that grabs messages from the OS and dispatches them to your application, but the WndProc method is where all the magic happens. This method is one giant switch statement that takes in the message and then runs the appropriate code. With each message, there are usually pieces of information passed along that give more details, like which key was pressed, the device context (Graphics object) to paint your form in, or the bounds of where your form is supposed to be placed.

The WndProc method is where we will concentrate our efforts because there are messages it receives, but that the .NET Framework does not pass to us. One of these is a message called WM_MOVING (which is different from WM_MOVE, which we handled earlier). This message does three things for us:

  1. It tells our form that it is going to be moved.
  2. It tells our form where it will be moved to.
  3. It gives our form the chance to tell Windows to move our form somewhere else.

More Stories By Richard Arthur

Richard Arthur is currently an instructor of C# at Northface University (www.northface.edu) in Salt Lake City, Utah. He has gained extensive experience doing Automation of MS Office products through VBA and COM at previous jobs.
In his spare time he learns about the inner workings of many current and future .NET Technologies, including Windows Forms, ASP.NET, Generics, P/Invoke, and COM Interoperability.
If anyone has any questions regarding this article, please contact Richard at [email protected]

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

IoT & Smart Cities Stories
Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.