This article illustrates the dynamic creation of control in MFC and the implementation of event response, shared for everyone to reference. The implementation methods are as follows:
A dynamic control is a control that is created by create () when needed, unlike a control placed in a dialog box beforehand.
First, create dynamic controls:
For comparison, let's take a look at the creation of static controls.
When you place a static control, you must first create a container, typically a dialog box, when we are in the dialog editing window, drag the desired control from the tool window and place it in the dialog box, modify the control ID appropriately, set the control properties, and a static control is created, and the controls on it appear when the dialog box is displayed.
Static controls do not need to call the Create () function to be created.
Creating a dynamic control is very different, for example, take a button, and look at the process of creating a dynamic control:
1. Establish the control ID number:
The ID number is the identity of the control, and you must set an ID number for it before you create the control.
Open a String table in a resource, double-click on a blank line, and an ID properties dialog box pops up, and in the ID edit box, enter the ID, such as: Idc_mybutton, enter the control caption or annotation in caption (Note: the caption box cannot be empty, Null will cause the creation to fail), here I enter the text to be displayed on the button-the dynamic button.
2. Set up control objects:
Different kinds of controls should create different class objects:
Button control CButton (includes normal buttons, radio buttons, and check buttons)
Edit Control CEdit
Static Text control CStatic
Label Control CTabCtrl
Rotate Control CSpinButtonCtrl
Slide Mark Control CSliderCtrl
Multi-information editing control CRichEditCtrl
Progress bar Control CProgressCtrl
Scroll bar control Csrcollbar
Combo box control CComboBox
List box control CListBox
Image List Control Cimagectrl
Tree-like control CTreeCtrl
Animation Control CAnimateCtrl
In this case, we create a normal button for the CButton class. Note You cannot directly define CButton objects, such as: CButton m_mybut; This definition can only be used to define control variables for static controls and not for dynamic controls.
The correct approach is to use new to invoke the CButton constructor to generate an instance:
Copy Code code as follows:
CButton *p_mybut = new CButton ();
The Create () function of the CButton class is then created with the following function prototype:
Copy Code code as follows:
BOOL Create (LPCTSTR lpszcaption, DWORD dwstyle, const rect& RECT, cwnd* pParentWnd, UINT NID);
Lpszcaption is the text displayed on the button;
dwstyle Specifies the button style, which can be a combination of a button style and a window style, with values:
① window Style:
Ws_child child window, must have
ws_visible window is visible, there are generally
ws_disabled Disable the window to create a button with an initial state of gray unavailable
Ws_tabstop can be selected with the TAB key
Ws_group Group, the first button in a group of radio buttons
② button Style:
Bs_pushbutton Press button, also known as the normal button
Bs_autoradiobutton radio button with auto checked status
Bs_radiobutton radio button, not commonly used
Bs_autocheckbox Check button with auto checked status
Bs_checkbox Check button, not used
Bs_auto3state Three-state check button with auto checked state
Bs_3state Three-State check button, not used
The above style specifies the type of button created and cannot be used at the same time, but must have one.
Bitmap is displayed on the Bs_bitmap button
Bs_defpushbutton is set as the default button, only for Push button, a dialog box can only specify a default button
RECT specifies the size and position of the button;
pParentWnd indicates that the parent window that owns the button cannot be null;
NID specifies the ID number associated with the button, with the ID number created in the previous step.
The Create () function of the different control classes is slightly different and can be referenced in the relevant data.
Cases:
Copy Code code as follows:
P_mybut->create ("Dynamic button", Ws_child | ws_visible | Bs_pushbutton, CRect (20,10,80,40), this, Idc_mybutton);
In this way, we created the 20,10 button with a width of 60, a height of 30, and a button text of "Dynamic button" in the current dialog box.
To make the creation process more user-friendly, I have defined the following functions:
Copy Code code as follows:
cbutton* Ctexteditorview::newmybutton (int nid,crect rect,int nstyle)
{
CString m_caption;
M_caption.loadstring (NID); Take button title
CButton *p_button = new CButton ();
Assert_valid (P_button);
P_button->create (m_caption, Ws_child | ws_visible | Bs_pushbutton | Nstyle, rect, this, NID); Create a button
return P_button;
}
where M_caption.loadstring (NID) reads the button text from the string table, so that when the button ID is created, the text should be set up, and the argument Nstyle to an extra style except the one that must be styled.
Below, I call the function to create three buttons and specify that the first button is the default button, and the button ID is preset:
Copy Code code as follows:
CButton *p_mybut[3];
P_mybut[0] = Newmybutton (ID_MYBUT1, CRect (10,20,50,35), Bs_defpushbutton);
P_MYBUT[1] = Newmybutton (Id_mybut2, CRect (55,20,95,35), 0);
P_MYBUT[2] = Newmybutton (ID_MYBUT3, CRect (100,20,140,35), 0);
Second, the response of the dynamic control:
The response function of a dynamic control cannot be added with ClassWizard and can only be added manually. Still take the above button as an example, we make the button's click Response function.
1. Add a response function to the MESSAGE_MAP:
The message response function is defined in the Message_map table in the form of a message name (ID, function name), and when we add a function with ClassWizard, it is automatically added to the range enclosed in afx_msg_map, such as:
Copy Code code as follows:
Begin_message_map (Ctexteditorview, CFormView)
{{Afx_msg_map (Ctexteditorview)
On_bn_clicked (idc_iconbut0, OnIconbut0)
}}afx_msg_map
End_message_map ()
Do not add to the Afx_msg_map range when manually added to prevent ClassWizard from working properly, such as:
Copy Code code as follows:
Begin_message_map (Ctexteditorview, CFormView)
{{Afx_msg_map (Ctexteditorview)
On_bn_clicked (idc_iconbut0, OnIconbut0)
}}afx_msg_map
On_bn_clicked (ID_MYBUT1, ONMYBUT1)
On_bn_clicked (Id_mybut2, OnMybut2)
On_bn_clicked (ID_MYBUT3, ONMYBUT3)
End_message_map ()
Where on_bn_clicked is a button click message.
2. Add a function definition to the header file:
When you add a function with ClassWizard, the function definition is added within the afx_msg interval of the header file, such as:
Protected
Copy Code code as follows:
{{afx_msg (Ctexteditorview)
afx_msg void OnIconbut0 ();
}}afx_msg
Declare_message_map ()
We imitate this form and just add the function definition to the AFX_MSG range:
Copy Code code as follows:
Protected
{{afx_msg (Ctexteditorview)
afx_msg void OnIconbut0 ();
}}afx_msg
afx_msg void OnMybut1 ();
afx_msg void OnMybut2 ();
afx_msg void OnMybut3 ();
Declare_message_map ()
3. Write the message response function:
The above is related to the message and function, specifically after the click of the button should do the work in the function to complete:
Copy Code code as follows:
void Ctexteditorview::onmybut1 ()
{
MessageBox ("Ha!") You clicked the dynamic button. " );
}
void Ctexteditorview::onmybut2 ()
{
......
}
void Ctexteditorview::onmybut3 ()
{
......
}
In addition to the button's response function, you can also use the pointer Access button obtained above, such as:
To modify the size and position of a button: P_mybut[0]->movewindow (...);
Modify button text: P_mybut[0]->setwindowtext (...);
Show/Hide buttons: P_mybut[0]->showwindow (...); Wait a minute.
Third, recycling resources:
Because the dynamic control object is generated by new, it is not automatically freed by the program, so it needs to be manually released. You can delete a control when it is no longer in use:
Copy Code code as follows:
if (P_mybut[0])
Delete P_mybut[0];
These are the methods that the button control dynamically generates. Next, take a look at the dynamic generation of the radio button.
Iv. Example: Dynamic generation of radio button groups
Radio buttons also belong to the CButton class, but because radio buttons are always used in groups, it makes and uses a certain difference from the normal buttons.
Suppose you have three radio buttons that make up a group, and the first radio button is selected at the beginning.
Let's take a look at the static fabrication method: Place three radio buttons in the dialog box, setting the properties as follows:
Radio1 properties: Visible, Group, Tab stop, Auto
Radio2 properties: Visible, Tab stop, Auto
Radio3 properties: Visible, Tab stop, Auto
Such a property setting divides three radio buttons into one group, and they can only be selected at a time, and if there are other groups of radio buttons in the dialog box, they will not interfere with each other. However, the first button is not selected at this time.
Then you add a variable to this set of radio buttons with ClassWizard, just add a variable to the first radio button. Set the variable name to M_radio and type int. In the constructor ClassWizard the M_radio value to-1, we change it to 0, so that when you run the program, you can see that the first radio button is selected.
After that, you should also use ClassWizard for three radio buttons to add a click response function, in which to modify the value of M_radio corresponding to three radio buttons on it.
The above is the usual way to make radio button group, now we want to change to dynamic generation, mainly to solve the button group and click Control problems. The following steps are made:
1. Define the ID of the three radio buttons:
Open "String Table" in the resource and add three ID values to it:
First: ID is idc_myradio1,caption for single option 1
The second: ID is idc_myradio2,caption for single option 2
Third: ID idc_myradio3,caption to Radio 3
Where caption is the text to be displayed on the button, set as needed.
2. Generate three radio buttons using the Create () function of the CButton class:
For convenience, define a function to generate radio buttons first:
Copy Code code as follows:
cbutton* ctexteditorview::newmyradio (int nid,crect rect,int nstyle)
{
CString m_caption;
M_caption.loadstring (NID); Take button title
CButton *p_radio = new CButton ();
Assert_valid (P_radio);
P_radio->create (m_caption, Ws_child | ws_visible | Nstyle | Ws_tabstop | Bs_autoradiobutton, rect, this, NID); Create a button
return p_radio;
}
function LoadString () is used to read button text from String Table, and the Create () function sets the required properties for the radio button, including the visible, Tab stop, auto properties.
The parameter NID is a radio button ID number, RECT is a radio button size, and Nstyle is a property other than the required property. The return value is a pointer to the new button.
With this function, when you create a radio button group, you call the function in turn, and the first radio button in the radio button group must specify the Ws_group property.
Copy Code code as follows:
CButton *p_myradio[3];
P_myradio[0] = Newmyradio (Idc_myradio1, CRect (15,90,60,105), ws_group);
P_MYRADIO[1] = Newmyradio (Idc_myradio2, CRect (15,108,60,123), 0);
P_MYRADIO[2] = Newmyradio (Idc_myradio3, CRect (15,126,60,141), 0);
3. Define the control variable for the radio button group and set the first radio button to be selected:
You cannot add a variable here with ClassWizard, and do not add a control variable in DoDataExchange (), because a dynamic control does not exist at first, adding control variables in DoDataExchange () can cause a run error. Here we simply define an int variable as a control variable in the header file, such as:
Copy Code code as follows:
Set its initial value to 0:m_selradio = 0 in the constructor;
In the statement that creates the button above, use the SetCheck () function to set the initially selected button:
Copy Code code as follows:
CButton *p_myradio[3];
P_myradio[0] = Newmyradio (Idc_myradio1, CRect (15,90,60,105), ws_group);
P_MYRADIO[1] = Newmyradio (Idc_myradio2, CRect (15,108,60,123), 0);
P_MYRADIO[2] = Newmyradio (Idc_myradio3, CRect (15,126,60,141), 0);
P_myradio[m_selradio]->setcheck (1); To set the first single selection as a selected state
In the SetCheck () function, a parameter of 1 indicates a selected state, and 0 indicates an unchecked state.
4. Add Mouse click response function:
After the mouse clicks a radio button, its status has been changed automatically, here we also need to modify the control variable M_selradio value to track the selected radio button.
First, in Message_map, you associate the mouse click message with the response function:
Copy Code code as follows:
Begin_message_map (Ctexteditorview, CFormView)
{{Afx_msg_map (Ctexteditorview)
On_bn_clicked (idc_iconbut0, OnIconbut0)//classwizard added here
}}afx_msg_map
On_bn_clicked (Idc_myradio1, ONMYRADIO1)//radio button 1
On_bn_clicked (Idc_myradio2, OnMyRadio2)//radio button 2
On_bn_clicked (Idc_myradio3, OnMyRadio3)//radio button 3
End_message_map ()
Then define the click function in the Message_map of the header file:
Copy Code code as follows:
Protected
{{afx_msg (Ctexteditorview)
afx_msg void OnIconbut0 (); ClassWizard to add here
}}afx_msg
afx_msg void OnMyRadio1 (); radio Button 1
afx_msg void OnMyRadio2 (); Radio Button 2
afx_msg void OnMyRadio3 (); Radio Button 3
Declare_message_map ()
Note here not to add a function to the afx_msg range to prevent the ClassWizard from being used.
Define the specific response function (this is added by hand, not by ClassWizard):
Copy Code code as follows:
Click the radio button 1 void ctexteditorview::onmyradio1 ()
{
m_selradio=0;
}
Click the radio button 2 void Ctexteditorview::onmyradio2 ()
{
M_selradio=1;
}
Click the radio button 3 void Ctexteditorview::onmyradio3 ()
{
m_selradio=2;
}
5. Recycling Resources:
In the destructor, recycle the radio buttons that you create (you can also recycle them when you do not use radio buttons):
Copy Code code as follows:
Ctexteditorview::~ctexteditorview ()
{
int i;
for (i=0; i<3; i++)
{
if (P_myradio[i])
Delete P_myradio[i];
}
}
The above is the dynamic control of the generation and response methods, a variety of different control practices slightly different, but the ideas and steps are similar, I hope this article on the VC program to help.