MFC dynamically creates controls (buttons) and adds message responses

Source: Internet
Author: User

A dynamic control is a control created by create () when needed, unlike a control placed in a dialog box beforehand.

First, create a dynamic control:

For the sake of comparison, let's take a look at the creation of static controls.
When you place a static control, you must first create a container, usually a dialog box, when we drag the desired control from the tool window into the dialog box in the Dialog editor window, modify the control ID appropriately, set the control property, and a static control is created, and the controls on it are displayed when the dialog box is displayed.
Static controls do not need to call the Create () function for creation.
While creating dynamic controls is a big difference, here's an example of a button to look at the creation of a dynamic control:

1. Build the control ID number:

The ID number is the identity of the control, and you must set an ID number for it before creating the control.
Open the String table in the resource, double-click on a blank line, and an ID property dialog pops up, enter the ID in the ID edit box, such as: Idc_mybutton, enter the control title or annotation in caption (Note: the caption box cannot be empty, Null causes the creation to fail), here I enter the text to be displayed on the button – the dynamic button.

2. Create the Control object:

Different kinds of controls should create different class objects.
Button controls CButton (including normal buttons, radio buttons, and check buttons)
Edit Control CEdit
Static Text control CStatic
Label Control CTabCtrl
Rotate Control CSpinButtonCtrl
Slide Label Control CSliderCtrl
Multi-information Edit 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 example we create a normal button for the CButton class. Note You cannot define CButton objects directly, 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 call the CButton constructor with new to generate an instance:

CButton *p_MyBut = new CButton();

This can also be created without new, instead of placing an object of the CButton class as a member of the dialog class.

private:    CButton m_btn_1;    CButton m_btn_2;

It is then created with the Create () function of the CButton class, the function prototype is 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 button style and window style, with the following values:
Window style:
Ws_child child window, must have
ws_visible window is visible, generally have
ws_disabled Disable the window, create a button when the initial state is dimmed is used
Ws_tabstop available Tab key selection
Ws_group, the first button in a group of radio buttons
Button style:
Bs_pushbutton Push-button, also known as the normal button
Bs_autoradiobutton radio buttons with auto-check status
Bs_radiobutton radio button, not commonly used
Bs_autocheckbox Check button with auto-check status
Bs_checkbox Check button, not used
Bs_auto3state Tri-state check button with auto-check status
Bs_3state Three-State check button, not commonly used
The above style specifies the type of button created and cannot be used at the same time, but must be one.
The bitmap is displayed on the Bs_bitmap button
Bs_defpushbutton is set as the default button, only for the push button, only one default button can be specified in a dialog box
RECT specifies the size and position of the button;
pParentWnd indicates the parent window that owns the button and cannot be null;
NID specifies the ID number associated with the button, using the ID number created in the previous step.
The Create () function for different control classes is slightly different, so you can refer to the relevant data.

For example:
P_mybut->create ("Dynamic button", Ws_child | ws_visible | Bs_pushbutton, CRect (20,10,80,40), this, Idc_mybutton);

This creates a push button with a width of 60, a height of 30, and a button text of "Dynamic button" at (20,10) in the current dialog box.

To make the creation process more user-friendly, I defined the following functions:

CButton* CTextEditorView::NewMyButton(int nID,CRect rect,int//取按钮标题newthis//创建按钮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, and the parameter nstyle as an extra style beyond the style that must be styled.
Below, I call this function to create three buttons and specify the first button as the default button, the ID of the button is pre-set:

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, but can only be added manually. Still with the above button as an example, we make a click response function for the button.

1. Add a response function for the control in Message_map:

The message response function is defined in the Message_map table in the form of a message name (ID, function name), which is automatically added to the interval enclosed in afx_msg_map when we add a function with ClassWizard, such as:

BEGIN_MESSAGE_MAP(CTextEditorView, CFormView)//{{AFX_MSG_MAP(CTextEditorView)ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0)//}}AFX_MSG_MAPEND_MESSAGE_MAP()

Do not add to the Afx_msg_map interval when manually added, in case ClassWizard does not work properly, such as:

 begin_message_map(ctexteditorview, CFormView)//{{afx  _MSG  _ map  (ctexteditorview ) on  _bn  _ CLICKED  (IDC  _iconbut  0, oniconbut  0)//}}  afx_msg_mapon_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 the declaration of the response function in the header file:

When you add a function with ClassWizard, a function definition is added within the afx_msg interval of the header file, such as:

protected://{{AFX_MSG(CTextEditorView)afx_msg void OnIconbut0();//}}AFX_MSGDECLARE_MESSAGE_MAP()

We imitate this form, just add the function definition to the afx_msg interval:

 Protected://{{AFX_msg(ctexteditorview)AFX_msg void oniconbut 0 ();/}} afx_msgafx_msg void OnMybut1(); afx_msg void OnMybut2 (); afx_msg void ONMYBUT3 (); Declare_message_map ()

3. Implement the message response function in the source file:
The above is to associate the message and function, the specific work to do after clicking the button is done in the function:

void CTextEditorView::OnMybut1"哈!你单击了动态按钮。" );}void CTextEditorView::OnMybut2(){……}void CTextEditorView::OnMybut3(){……}

In addition to the button's response function, you can also use the pointer access buttons above, such as:
Modify the size and position of the button: P_mybut[0]->movewindow (...);
Modify button text: P_mybut[0]->setwindowtext (...);
Show/Hide button: P_mybut[0]->showwindow (...); Wait a minute.
Third, recycling resources:

if the control is a member object of dialog, then the steps for this recycle resource are not required.
Because the dynamic control object is generated by new, it is not automatically freed by the program, so it needs to be freed manually. You can delete a control when it is no longer in use:

if( p_MyBut[0] )delete p_MyBut[0];

These are the methods that the button control dynamically generates. Next, look at the radio button's dynamic generation problem.
Iv. Example: Dynamic generation of radio button groups

Radio buttons are also part of the CButton class, but because radio buttons are always used in groups, it differs from normal buttons in production and use.

Suppose you have three radio buttons that make up a group, and initially, the first radio button is selected.

Let's take a look at the static authoring method: Place three radio buttons in the dialog box and set 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 the three radio buttons into a group, they can only have one 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 use ClassWizard to add variables to this set of radio buttons, where you simply add a variable for the first radio button. Set variable named M_radio, type int. In the constructor ClassWizard set the value of M_radio 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 add a click response function with ClassWizard for three radio buttons, and modify the value of M_radio to correspond to three radio buttons.
The above is the usual way to make radio button group, now we want to change the dynamic generation, mainly to solve the button grouping and click Control problems. Here are the steps to make:

1. Define the ID of three radio buttons:

Open "String Table" in the resource and add three ID values to it:
First: The ID is idc_myradio1,caption as a single choice 1
Second: The ID is idc_myradio2,caption as a single choice 2
Third: ID idc_myradio3,caption for Radio 3
Where caption is the text you want to display on the button, you can set it as needed.

2. Generate three radio buttons with the Create () function of the CButton class:

For the sake of convenience, define a function to generate a radio button:

CButton* CTextEditorView::NewMyRadio(int nID,CRect rect,int//取按钮标题newthis//创建按钮return p_Radio;}

The function loadstring () is used to read the button text from the String Table, and the Create () function sets the required properties for the radio button, including the visible, Tab stop, Auto property.
The parameter NID is a radio button ID number, and RECT is a radio button size, Nstyle is a property other than the required attribute. The return value is a pointer to the new button.
With this function, when you create a radio button group, you simply call the function in turn, where the first radio button of the radio button group must specify the Ws_group property.

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 as checked:
You cannot add variables with ClassWizard, nor do you add control variables in DoDataExchange (), because dynamic controls do not exist at first, and adding control variables in DoDataExchange () can cause run errors. Here we simply define an int variable as a control variable in the header file, such as:
int M_selradio;
Set its initial value in the constructor to 0:m_selradio = 0;
In the above statement of the Create button, use the SetCheck () function to set the initial selected button:

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); //设置第一个单选为选中状态

In the SetCheck () function, a parameter of 1 indicates that the setting is selected, and 0 indicates unchecked.
4. Add a mouse click response function:

When the mouse clicks on a radio button, its status can be changed automatically, here we also need to modify the value of the control variable M_selradio, in order to track the selected radio button.

First, the mouse click message is associated with the response function in Message_map:

BEGIN_MESSAGE_MAP(CTextEditorView, CFormView)//{{AFX_MSG_MAP(CTextEditorView)ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0) //ClassWizard在此处添加//}}AFX_MSG_MAPON_BN_CLICKED(IDC_MYRADIO1, OnMyRadio1) //单选按钮1ON_BN_CLICKED(IDC_MYRADIO2, OnMyRadio2) //单选按钮2ON_BN_CLICKED(IDC_MYRADIO3, OnMyRadio3) //单选按钮3END_MESSAGE_MAP()

Then define the click function in the Message_map of the header file:

protectedvoid//ClassWizard在此处添加//}}AFX_MSGvoid//单选按钮1void//单选按钮2void//单选按钮3DECLARE_MESSAGE_MAP()

Note here that the function is not added to the afx_msg interval in order to prevent the use of ClassWizard.
Define a specific response function (this is done by hand, not by ClassWizard):
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, the created radio button is recycled (and can be reclaimed immediately without using a radio button):

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 that the above examples to you can be helpful.
Transferred from: http://blog.163.com/up_tlx/blog/static/206022202201241992431218/

MFC dynamically creates controls (buttons) and adds message responses

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.