Additional Product-message mechanism of "tutorial on nlp mfc"
What are messages, message processing functions, and message ing?
Simply put, a message refers to an operation to be executed by sending a command to the program by the input device. A specific operation is a series of code you write. It is called a message processing function. In SDK, messages are easy to understand. When a window is created, a function (window processing function) starts to execute a message loop. We can also clearly see the message processing context. A switch case statement can be used. The message loop ends only when a wm_quit message is encountered. All other messages are intercepted and corresponding processing functions are called. However, in the MFC that encapsulates the API, the message seems to be a little more complicated, and we cannot see the familiar switch case statement. Instead, it is something called message ing. Why does MFC introduce the message ing mechanism? You can imagine whether your program has multiple forms in the current program development activity. The main window has only one, the menus, toolbar, and controls are subwindows. How many switch cases do we need to write and assign a message processing function to each message? How complicated is this. Therefore, MFC adopts a new mechanism. Using an array, You can map window messages to the corresponding message processing functions. This is a table. This mechanism is message ing. This table is defined in the window base class cwnd. The derived class message ing table is empty if you do not have any action. That is to say, if you do not manually add a message processing function, when the derived window receives a message, it executes the message processing function of the parent class. This is obviously efficient.
Message structure provided by MFC
At the same time, MFC defines the following two main structures:
Afx_msgmap_entry
Struct afx_msgmap_entry {
Uint nmessage; // WINDOWS Message ID
Uint ncode; // Message notification Control
Uint NID; // The Message ID for Windows Control
Uint nlastid; // indicates the range in which a specified range of messages are mapped.
Uint nsig; // indicates the action ID of the message.
Afx_pmsg PFN; // pointer to the Message Processing Function
};
Afx_msgmap
Struct afx_msgmap {
# Ifdef _ afxdll
Const afx_msgmap * (Pascal * pfngetbasemap )();
# Else
Const afx_msgmap * pbasemap;
# Endif
Const afx_msgmap_entry * lpentries;
};
/// Afx_msgmap obtains the message ing entry address of the base class and the message ing entry address of the base class.
The next message processing process of MFC is generally like this.
1. _ afxcbtfilterhook intercepts messages (this is a hook function)
2. _ afxcbtfilterhook sets the Window Process to afxwndproc.
3. The function afxwndproc receives messages sent by the Windows operating system.
4. The afxwndproc function calls the afxcallwndproc function to process messages.
5. The afxcallwndproc function calls the cwnd class method windowproc for message processing.
How do I add my own messages?
We have learned about the window message mechanism. How can we add our own messages? Let's see.
A standard message processing program looks like this.
The cwnd class predefines the default handler for standard Windows messages (wm_xxxx WM is short for window messages. The class library names these handlers Based on the message name. For example, the wm_paint message handler is declared:
Afx_msg void onpaint ();
The afx_msg keyword distinguishes these handlers from other cwnd member functions to demonstrate the role of the C ++ virtual keyword. However, note that these functions are not actually virtual, but implemented through message ing. At the beginning of this article, we will explain why we should do this.
All classes that can process messages are based on the cve-target class, that is, the cve-target class is the parent class of all classes that can process messages. The csf-target class is the basis and core for MFC to process command messages.
To override the handler defined in the base class, you only need to define a function with the same prototype in the derived class and create a message ing item for this handler. We can use classwizard to create most window messages or custom messages. With classwizard, We can automatically establish message ing and the framework of message processing functions. We only need to fill in what we need to do, add your tasks to the processing function. This is very simple and I will not elaborate on it. However, we may need to add some window messages or custom messages that are not supported by classwizard. Therefore, we need to establish a framework for message ing and processing. The general steps are as follows:
Step 1: Define a message. Microsoft recommends that you customize the message at least wm_user + 100, because many new controls also use wm_user messages.
# Define wm_mymessage (wm_user+ 100)
Step 2: Implement Message processing functions. This function uses wpram and lparam parameters and returns lpesult.
Lpesult cmainframe: onmymessage (wparam, lparam)
{
// Todo: Process custom messages. Fill in the blanks here.
Return 0;
}
Step 3: Describe the message processing function in the afx_msg block of the Class header file:
// {Afx_msg (cmainframe)
Afx_msg lresult onmymessage (wparam, lparam );
//} Afx_msg
Declare_message_map ()
Step 4: Use the on_message macro command in the message block of the user class to map the message to the message processing function.
On_message (wm_mymessage, onmymessage)
We can see that the user-defined message is similar to the message we added through classwizard. It uses the on_message macro to create message ing.
In fact, message categories can be divided into multiple types. The above is just one of them. There are three main message categories: (the following part is from msdn)
1. Windows messages
Such messages include messages starting with WM _, except for wm_command. Windows messages are processed by windows and views. Such messages often contain parameters used to determine how messages are processed.
2. Control notification
Such messages include wm_command notification messages sent from controls and other subwindows to their parent windows. For example, after you perform operations that may change text in the edit control, the Edit Control) A wm_command message containing the en_change control notification code will be sent to its parent. The window handler of the message responds to the notification message in an appropriate way, for example, retrieving the text in the control.
The framework sends control notification messages like other WM _ messages. However, there is an exception, that is, the bn_clicked control notification message sent by the button when the user clicks the button. The message is specially processed as a command message and transmitted like other commands.
3. Command Message
Such messages include wm_command notification messages sent from user interface objects (menus, toolbar buttons, and shortcut keys. The Framework processes commands in a different way than other messages. You can use more types of object processing commands.
Windows messages and control notification messages are processed by Windows (windows are class objects derived from the cwnd class ). Including cframewnd, cmdiframewnd, cmdichildwnd, cview, cdialog, and your own classes derived from these base classes. These objects encapsulate the windows Windows-hwnd handles.
Command messages can be processed by a wider range of objects (documents, document templates, and application objects), not just windows and views. When a command directly affects a specific object, the object should be processed. For example, the open command in the File menu is logically associated with the application: the application will open the specified document when it receives the command. Therefore, the handler of the "open" command is a member function of the application class.
A common command message is the menu item and toolbar. You can see that its message ing macro is not the same as window message. The general form is as follows:
On_command (ID, memberfxn)
The first parameter is the command ID. One ID corresponds to one message processing. Of course, you can share multiple IDs with one processing function. Common applications such as opening document IDs and toolbar buttons in menu items use a processing function at the same time, or directly set their IDs to the same.
There is also a message called a notification message. For example, some complex controls such as tree controls need to transmit more information after clicking, such as the cursor position and a structure of the current item, therefore, MFC defines a macro for each notification message of the control, which looks like this:
On_control (en_change, ID, memberfxn)
There are also many types of messages in MFC, which have different macro definitions. You can bypass them.
There are hundreds of window messages. You can check the names starting with WM _ on msdn or the member functions of cwnd, which will list a lot of non-window messages. Raytheon cannot list them one by one, and it is not necessary. You just need to check it. However, for some commonly used, new control messages and special notification messages, I will list them in several tables for your reference.
Table 1: Common Message ing macros
Table 2: Common and common window messages
Table 3: notification messages common to Win32 new controls
Table 4: special notification messages
It is actually the beginning. There is still a lot of information about the message, so you can understand it in actual application.