“This is the 10th day of my participation in the First Challenge 2022. For details: First Challenge 2022”
Under the MFC framework, there are many system-defined messages, such as ON_WM_LBUTTONDOWN(), ON_WM_MBUTTONDOWN(), and so on. When we use it, we just need to declare and call it, the simplest way to use it.
A bit more difficult to use is to set up their own custom messages, and a bit more difficult is how to simulate the system messages, under normal circumstances just do ordinary project development functions are not used.
Here, I first explain how to achieve a custom message, and then in-depth on how to simulate the system message, there is a need to understand the yo ~
Custom message
In some cases, the message defined by the system can not fully meet the application of the program, at this time, the message needs to be customized, so how to achieve the custom message?
Step 1: Define a custom message name and ID
Under the MFC framework, messages after WM_USER is assigned are message ids that developers can customize.
Suppose we define a selected trigger message:
#define WM_USER_CLICKED WM_USER+1
Copy the code
This means a custom message is defined. The message name is WM_USER_CLICKED and the message ID is WM_USER+1
In order to facilitate the management of custom messages in large drawing development programs, it is generally not used to increment the number of WM_USER directly. Instead, it is used to replace WM_USER with a custom macro. For subsequent management, the format is as follows:
#define UIXML_WM_BASE WM_USER + 20000 #define WM_USER_CLICKED1 UIXML_WM_BASE +0 #define WM_USER_CLICKED2 UIXML_WM_BASE+1 #define WM_USER_CLICKED3 UIXML_WM_BASE+2 #define WM_USER_CLICKED4 UIXML_WM_BASE+3Copy the code
If you only have one or two custom messages in your application, there is no need to write them in this format.
Benefits of this format:
Custom message areas can be divided based on functionality. Suppose you are currently developing a framework class for internal use in your company. When customizing messages, you need to distinguish between those for your own development and those for external developers. Clear division of labor, not easy to misinformation.
Step 2: Send a custom message
Where you want to trigger a custom message, you need to send the message.
In the MFC framework, there are two message sending mechanisms: SendMessage and PostMessage.
::SendMessage(GetParent()->GetSafeHwnd(), WM_USER_CLICKED, 2, 1);Copy the code
Just take examples to illustrate, specific according to the actual function to determine ~
Step 3: Customize the message mapping
ON_MESSAGE(WM_USER_CLICKED1, OnCustomClicked1)
Copy the code
Parameter 1: Custom message defined
Parameter two: The mapping message of the response in the actual window
Step 4: Customize the message implementation
afx_msg LRESULT OnCustomClicked1(WPARAM wParam , LPARAM lParam);
Copy the code
Specific operation application can be written in OnCustomClicked1, this should be based on the actual needs of the application, here no longer do too much description, here, should know how to apply it ~
Analog system message
The simple custom message approach is already covered in custom messages, so let’s take it a step further! How to simulate system messages, for easy to understand explanation, here we simulate ComboBox control CBN_SELCHANGE messages.
People who have used MFC framework control development know that the message is sent by the system, usually we just apply it, if you write such a trigger message, how to achieve it?
Preconditions: Inherit the CWnd class to simulate the ComboBox control. In this case, all control messages need to be simulated internally, so that external developers can call the same message in the system ComboBox.
Suppose we use SendMessage to send a message, we also need to send a message, but we need to send a command message: WM_COMMAND
When is WM_COMMAND triggered?
1: when the user selects a command item from the menu
2: when the control sends a message to its parent window
3: When acceleration keystrokes are translated
In fact, Windows 9X above all send WM_NOTIFY, but to make it compatible with base classes, so the WM_COMMAND message is still used.
Once WM_COMMAND is specified to send messages, what data should wParam and lParam send?
WParam parameter
In sending custom messages, the wParam parameters are divided into high and low bytes and need to be sent using the MAKEWPARAM macro.
This macro creates a 32-bit unsigned value that is used as the wParam parameter in the message, and this macro concatenates two specified 16-bit values.
When passing parameters, the high position is the ID number sent by the current simulation. Each window or even each control has its own number, which is not difficult to obtain.
CBN_SELCHANGE is the system message that needs to be triggered, so the wParam parameter is written as follows:
MAKEWPARAM( GetDlgCtrlID(),CBN_SELCHANGE)
Copy the code
LPARAM parameters
For this parameter, it is as simple as passing the HWND of the current window into the LPARAM parameter.
Overall analog system sending format:
::SendMessage(pwnd->GetSafeHwnd(), WM_COMMAND, MAKEWPARAM( GetDlgCtrlID(),CBN_SELCHANGE), (LPARAM)GetSafeHwnd());
Copy the code
The second and third parameters of SendMessage are the most important for the simulated system to send messages. For the same reason, you can send it as a PostMessage.
Once the message is sent, how is it used in the outside world?
Since we are emulating system messages, the external window calls are consistent with the MFC’s own control message methods
Message mapping:
ON_CBN_SELCHANGE(ID_CUSTOMCOMBOBOXID, &CTestComboboxDlg::OnCbnSelchangeComboSd)
Copy the code
Does this look familiar to you? Is it the same as ComboBox? The subsequent use of the way are consistent!
I am a Chinese good citizen st, a C++ program ape ~