In-depth introduction to C # message (transfer)

Source: Internet
Author: User

This article is from the 2002 issue of computer programming skills and maintenance.

1. Message Overview

In Windows, the execution of applications is message-driven. Message is the working engine of the entire application. We need to understand how the programming language we use encapsulates messages.

1. What is a message)

Messages are notifications and commands. In the system. Windows. Forms namespace in the. NET Framework class library, Microsoft redefined the message in the form of objects. The common attributes of the new message structure are basically the same as those of earlier versions, but they are oriented to objects.
Public attributes:

Hwnd obtains or sets the Message Processing Function
MSG obtains or sets the Message ID.
Lparam specifies the lparam field of the message
Wparam specifies the wparam field of the message
Result indicates the value returned to the OS in response to the message processing function.

2. Message-driven process

All external events, such as keyboard input, mouse movement, and mouse movement, are converted from the OS to the corresponding message queue sent to the application. Each application has a piece of corresponding program code to retrieve and distribute these messages to the corresponding form, which is then processed by the form processing function.

Ii. encapsulation of messages in C #

C # re-encapsulate messages to objects. in C #, messages are encapsulated into events.
The system. Windows. Forms. Application class has methods for starting and stopping applications and threads and processing Windows messages.
Call run to start the application message loop on the current thread, and you can choose to make its form visible.
Call exit or exitthread to stop the message loop.
C # The application class is used to process the receiving and sending of messages. It is responsible for the message loop.
In essence, each form generally corresponds to a form process handler. So how does a form instance (equivalent to a form) in C # process messages after receiving messages? In fact, the analysis of this problem shows the message encapsulation principle of C.

Implement the response (wm_lbuttondown) of the message with the left mouse click)

This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown1 );
This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown2 );

Private void form1_mousedown1 (Object sender, system. Windows. Forms. mouseeventargs E)
{
If (E. Button = system. Windows. Forms. mousebuttons. Left)
System. Windows. Forms. MessageBox. Show ("The message is returned by the form1_mousedown1 function ");
}

Private void form=mousedown2 (Object sender, system. Windows. Forms. mouseeventargs E)
{
If (E. Button = system. Windows. Forms. mousebuttons. Left)
System. Windows. Forms. MessageBox. Show ("The message is returned by the form1_mousedown2 function ");
}

Above this. mousedown is an event in C. It is defined as follows:

Public event mouseeventhandler mousedown;

The definition of mouseeventhandler is as follows:

Public Delegate void mouseeventhandler (Object sender, mouseeventargs E );

In fact, the above defines a delegate type: mouseeventhandler. Commissioned a solution that enables function pointers in other programming languages. Unlike C ++ function pointers, delegation is fully object-oriented and encapsulates object instances and methods. Essentially, a delegate encapsulates an instance and the method functions on the instance into an callable object, which is object-oriented and secure.

We can
This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown1 );
This statement adds a function pointer to this. mousedown.

An event is a message sent by an object to send a notification. The object that triggers an event is called the event sender. The object that captures the event and responds to the event is called the event receiver. In event communication, the event sender class does not know which object or method will receive (process) the event it raises. It is necessary to have a media (like a pointer mechanism) between the sender and the receiver ).. The. NET Framework defines a special type (delegate) that provides the function pointer function. In this way, the delegate is equivalent to a type-safe function pointer or a callback function.

We added two delegates to the this. mousedown event.
This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown1 );
This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown2 );
As a result, the form1_mousedown1 and form1_mousedown2 functions are called when we click the left mouse button, and the call order is the same as the order in which we add the delegate.

The wm_lbuttondown message is first retrieved from the application message queue by the application class and then distributed to the corresponding form. The form uses the function pointer in the mousedown event to call the added response function. Therefore, the event field in C # is essentially a function pointer list, which is used to maintain the address of the response function when a message arrives.

Iii. Conclusion

C # message workflow:

The messages in C # are retrieved by the application class from the application message queue and then distributed to the corresponding form of the message, the first response function of the form object is protected override void wndproc (Ref system. windows. forms. message e) method.
It then calls the default message response function (such as onmousedown) based on the message type, the default response function then according to the event field of the object (such as this. the list of function pointers in mousedown, which calls the user's added response functions (such as form1_mousedown1 and form1_mousedown2), and the call sequence is the same as the user's add sequence.

4. Let's look back at the application class.

The application class has a static method of addmessagefilter, through which we can add a message filter to view these messages when passing Windows messages to the target.
Use message filters to prevent the occurrence of a specific event, or use message filters to perform special operations on an event before it is passed to the event handler. We must provide an implementation of the imessagefilter interface before using the message filter. The following sample code demonstrates how to intercept a message before it is sent to a form. We intercepted the wm_lbuttondown message.


Using system;
Using system. drawing;
Using system. collections;
Using system. componentmodel;
Using system. Windows. forms;
Using system. Data;

Namespace messagemech3
{
// Implement the message filter Interface
Public class clbuttondownfilter: imessagefilter
{
Public bool prefiltermessage (ref message m)
{
If (M. MSG = 0x0201) // wm_lbuttondown
{
System. Windows. Forms. MessageBox. Show ("press the left mouse button in the app ");
// The return value is true, indicating that the message has been processed and cannot be passed back. Therefore, the message is intercepted.
// If the returned value is false, the message is not processed and needs to be passed back. Therefore, the message is not intercepted.
Return true;
}
Return false;
}
}


/// <Summary>
/// Summary description for winform.
/// </Summary>
Public class winform: system. Windows. Forms. Form
{
/// <Summary>
/// Required designer variable.
/// </Summary>
Private system. Windows. Forms. Label label1;
Private system. componentmodel. Container components = NULL;

Public winform ()
{
//
// Required for Windows Form Designer support
//
Initializecomponent ();

//
// Todo: add Any constructor code after initializecomponent call
//
// Install your own Filter
Clbuttondownfilter myfilter = new clbuttondownfilter ();
System. Windows. Forms. application. addmessagefilter (myfilter );
}

/// <Summary>
/// Clean up any resources being used.
/// </Summary>
Protected override void dispose (bool disposing)
{
If (disposing)
{
If (components! = NULL)
{
Components. Dispose ();
}
}
Base. Dispose (disposing );
}

# Region windows Form Designer generated code
/// <Summary>
/// Required method for designer support-do not modify
/// The contents of this method with the code editor.
/// </Summary>
Private void initializecomponent ()
{
This. label1 = new system. Windows. Forms. Label ();
This. suspendlayout ();
//
// Label1
//
This. label1.backcolor = system. Drawing. color. transparent;
This. label1.dock = system. Windows. Forms. dockstyle. Top;
This. label1.forecolor = system. Drawing. color. darkviolet;
This. label1.name = "label1 ";
This. label1.size = new system. Drawing. Size (440, 32 );
This. label1.tabindex = 0;
This. label1.text = "demonstrate how to process messages in an app object. Please click the left button ";
This. label1.textalign = system. Drawing. contentalignment. bottings enter;
//
// Form1
//
This. autoscalebasesize = new system. Drawing. Size (7, 22 );
This. backcolor = system. Drawing. color. whitesmoke;
This. clientsize = new system. Drawing. Size (440,273 );
This. Controls. addrange (new system. Windows. Forms. Control [] {This. label1 });
This. font = new system. drawing. font (" 文 ", 15f, system. drawing. fontstyle. regular, system. drawing. graphicsunit. point, (system. byte) (134 )));
This. Name = "winform ";
This. Text = "winform ";

// The Call Sequence of the message response function is the same as that of the add delegate function.
// The following command calls form1_mousedown1 and form1_mousedown2.

// Add your own mouse by entrusting the message response function 1
This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown1 );
// Add your own mouse to the Message response function 2
This. mousedown + = new system. Windows. Forms. mouseeventhandler (this. form1_mousedown2 );

This. resumelayout (false );
}
# Endregion

/// <Summary>
/// Main entry point of the application.
/// </Summary>
[Stathread]
Static void main ()
{
Application. Run (New winform (); // start the application message loop on the current form thread
}

// Key 1
// Use the event interface provided by C # To add the response function of your mouse button event
//
Private void form1_mousedown1 (Object sender, system. Windows. Forms. mouseeventargs E)
{
If (E. Button = system. Windows. Forms. mousebuttons. Left)
System. Windows. Forms. MessageBox. Show ("The message is returned by the form1_mousedown1 function ");

}
Private void form=mousedown2 (Object sender, system. Windows. Forms. mouseeventargs E)
{
If (E. Button = system. Windows. Forms. mousebuttons. Left)
System. Windows. Forms. MessageBox. Show ("The message is returned by the form1_mousedown2 function ");

}
// Key 2
// Trigger the function to intercept messages by overwriting basic events
//
Protected override void onmousedown (mouseeventargs E)
{
If (E. Button = system. Windows. Forms. mousebuttons. Left)
System. Windows. Forms. MessageBox. Show ("The message is returned by the onmousedown function ");

// If You Want To intercept a message, comment out the base. onmousedown (E); statement.
Base. onmousedown (E );
}
// Key 3
// Intercept messages by overwriting form functions of the base class
//
Protected override void wndproc (Ref system. Windows. Forms. Message E)
{
// If You Want To intercept a message,
// If (E. MSG = 0x0201) // wm_lbuttondown
// System. Windows. Forms. MessageBox. Show ("The message is responded by the wndproc function ");
// Else
// Base. wndproc (ref E );

// If the message does not need to be intercepted
If (E. MSG = 0x0201) // wm_lbuttondown
System. Windows. Forms. MessageBox. Show ("The message is responded by the wndproc function ");
Base. wndproc (ref E );
}

}
}

The above code first uses the clbuttondownfilter class to implement the imessagefilter interface. We installed the message Filter during winform initialization. When the program is actually executed, When you click the left mouse button, the program will only pop up a message box "press the left mouse button in the app. Because the message is intercepted before it is sent to the form, the form cannot receive the wm_lbuttondown message.
If we set

If (M. MSG = 0x0201) // wm_lbuttondown
{
System. Windows. Forms. MessageBox. Show ("press the left mouse button in the app ");
Return true;
}
Change

If (M. MSG = 0x0201) // wm_lbuttondown
{
System. Windows. Forms. MessageBox. Show ("press the left mouse button in the app ");
Return false;
}
Then, after the application class processes the message, the message will continue to be sent to the form. The form function can process the message. The program execution result is that five message boxes are displayed in sequence.
1: <left mouse click in the app>
2: <the message is responded by the wndproc function>
3: <response of the message to the onmousedown function>
4: <response from the message form1_mousedown1 function>
5: <response of the message form=mousedown2 function>
There are two main ways to filter
First:
Protected override void wndproc (ref message m)
{
If (M. MSG = 0x0201)
Return;
Else
Base. wndproc (ref m );
}
Second
Do not override wndproc

// Implement the message filter Interface
Public class clbuttondownfilter: imessagefilter
{
Public bool prefiltermessage (ref message m)
{
If (M. MSG = 0x0201) // wm_lbuttondown
{
// The return value is true, indicating that the message has been processed and cannot be passed back. Therefore, the message is intercepted.
// If the returned value is false, the message is not processed and needs to be passed back. Therefore, the message is not intercepted.
Return true;
}
Return false;
}
}

Clbuttondownfilter myfilter = new clbuttondownfilter ();
System. Windows. Forms. application. addmessagefilter (myfilter );

 

Source: http://blog.csdn.net/acupofnescafe/archive/2009/01/13/3768944.aspx

In-depth introduction to C # message (transfer)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.