Windows, event, message)
Most of us use Microsoft windows OS. windows is a window, a form. its biggest feature is that almost all operations are graphic interfaces. in object-oriented development, everything is an object, and in windows operations, everything is a form. the message mechanism is corresponding to the form. it is based on messages and event-driven. the form is a graphical interface that we can see with our eyes. Almost any entity that can be displayed is a window. Sometimes the pop-up dialog box is a small form, and a button is also a form. A single interface can be composed of multiple forms. the event represents all the operations, such as a mouse, a click, a window widening, text box input, and so on... after an event occurs, it is sent to the corresponding function of the application in the form of a message. therefore, the relationship between the form, event, and message is that the operation on the form is an event, and the event will generate a message.
Windows OS is event-driven, and most applications running on it are also event-driven. most of the time, the application is dumb, so you can only click it to start and perform the corresponding operations. of course, some applications may have some background operations, such as setting a clock, automatically refresh every time, or do some other operations.
I think people are actually a bit like an event-driven machine. we accept various internal or external stimuli and then generate various responses. even when you go to bed, you are receiving the stimulus to make some instinctive responses. the behavioral psychology school believes that people do not have the so-called free will, and they only know how to respond through some stimuli. however, various stimuli are very complicated and the response is also a series of chain reactions, so we are not easy to feel. of course, the views held by various psychology schools are different, and those theories are difficult to prove. similar to the famous NP-hard problem in the algorithm, we don't know if the NP-hard problem can be solved. it cannot prove that it can solve or prove that it cannot solve.
Message controls are generally divided into three layers.
The first layer is windows kernel. it maintains a message queue, such as the mouse, keyboard, and other IO devices that do not directly send events to the application, but are first processed by the operating system and converted into "messages ". because an application handle is specified when a form is created, the operating system knows which messages belong to the application when a form is generated, the operating system maintains a message queue for each application.
The second layer is the application. in windows API programming, A while LOOP is usually used to obtain messages in the message queue using GetMessage or PeekMessage. however, this information is only equivalent to raw materials and needs further processing. you can use TranslateMessage to further process and perform some conversions, or ignore useless messages. after processing, the information is re-transmitted to the operating system through DispatchMessage. each message is actually a struct with some related information, which contains a form handle. in this way, we will know which form the message is generated.
The third layer is the form process (windows procedure). When creating a form, a form process is specified, which is actually a function corresponding to the form to process messages. after the application resends the message to the operating system. the operating system then sends the message to the window. The window process makes some judgments based on some information in the message and performs different processing.
C # Event Processing Mechanism
A lot of encapsulation is made in C #, so we cannot see the message processing process at all. by encapsulating layers, we can only see the concept of event. in C #, event is a keyword and can be considered as a type. when you perform some operations on the form, events can be generated one by one. for example, if you click btnOK, the corresponding event is btnOK. click. (Click is a previously defined event in C #. We only need to use it .) in fact, we can simply understand that in the three-tier structure of message control, all the previous operations are encapsulated for you until you finally specify the form processes one by one, in addition, the form process corresponding to different messages is specified. the process is null, which is a bit equivalent to a function pointer. You need to specify a specific function by yourself. there is no pointer in C #, but there is a concept called a proxy (delegate), which is similar to a function pointer. the event is equivalent to encapsulation of the proxy, or an application of the proxy. proxy can also be used in many other places.
For example, event Click is defined in this way.
(1) public event EventHandler Click; // The EventHandler is a proxy type. the standard format for defining an event is to use the keyword event and then add the proxy type, and then add the variable name. the format for defining the EventHandler proxy is as follows.
(2) public delegate void EventHandler (object sender, EventArgs e); // It indicates that EventHandler can point to any function with the object and EventArgs as the parameter, and the return type is void. as we mentioned earlier, event Click is only equivalent to an empty form process. then how can we specify specific functions. we can specify an event handler by using the keyword "+ =. for example
(3) btnOK. Click + = new System. EventHandler (btnOK_Click); // Where btnOK_Click is the function name, you can also take any other name. Then define the function anywhere in the class.
And bind multiple strings to add them directly like + =. when an event is bound to multiple functions, multiple functions are executed when the event is triggered. of course, we can also unbind a function with the keyword "-=.
Void btnOK_Click (object sender, EventArgs e)
{
// Operation code
}
All the events related to Windows or controls in C # are encapsulated and used directly. You only need to bind a specific function. in addition, the function type bound to the event is generally two parameters, the first of which is the object sender, which indicates which form object triggers the event. if it is a button, you can convert this object to a button object, and then obtain other button information (button) sender. another parameter is EventArgs. In fact, this parameter is sometimes different. If it is a keyboard-triggered event, it is KeyPressEventArgs. It carries other information, such as which button is pressed by the keyboard.
But in fact, we rarely use these two parameters, so that they don't matter, just write other code in the function.
Custom events
In addition to pre-defined events that can be used directly, we can also define some events by ourselves, using the same syntax format. A custom event is not necessarily a form event. It can be any other event. for example, an event is triggered when the value of a variable is reached.
How to trigger the execution of a custom event is invisible because it has been encapsulated. However, if it is a custom event, you must specify how to execute it. Let's take a simple example.
Public delegate void SayHello (string str); // declare a proxy
Public event SayHello onSayHello; // defines an event onSayHello
The code that triggers the event execution is
String msg = "arwen ";
OnSayHello (msg); // it seems that it is no different from calling a function. of course, you have to bind a function to it before calling it. Otherwise, an error will occur. therefore, if (onSayHello! = Null) in this way, if the event is not bound to any function, it is null.
Now that all the events are similar to calling functions, it is better to call functions or call agents directly. Why bother with this? The whole event.
There are two possible reasons for using custom events. Of course, this is my own guess.
1. It represents a design mode and a subscriber mode.
Second, the encapsulation principle should be embodied.
For example, if a class wants to call a function in another class and does not want to call it directly or declare the function as private, it can be called indirectly through event. because delegate is equivalent to a pointer to a function, and event is equivalent to the encapsulation of delegate. then you may ask what the encapsulation is. This may be a design idea. It will be useful for expanding functions or doing some additional processing in the future. otherwise, as we encapsulate all fields in the class into properties, most of the time we cannot see what is useful. Instead, we feel a little more involved, it is better to directly use fields to use other attributes. but it is especially useful if we sometimes want to do some extra processing in the attribute. for example, you can only read the field value without assigning values, or vice versa.
A simple example of calling private functions in other classes using custom events.
In class A, the private function sayHello. In class B, we certainly cannot directly call sayHello. Of course, we also need to assume that B is used in class.
Delegate void DelegateSayHello (string name); // it can be viewed as a special class somewhere outside the class. It can also be defined in a class.
Public class
{
B sb;
Sb. HowAreYou + = new DelegateSayHello (sayHello );
Private void sayHello (string name)
{
Console. WriteLine ("Hello," + name );
}
}
Public class B
{
Public event DelegateSayHello HowAreYou;
String name = "arwen ";
Private void DoSomething ()
{
HowAreYou (name); // The private function sayHello in class A is called here.
}
}