MFC dynamic control creation

Source: Internet
Author: User

 

A dynamic control is a control created by create () as needed, which is different from a control pre-placed in a dialog box.
1. Create a dynamic control:
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, usually a dialog box. In this case, drag the required control from the tool window in the dialog box editing window, and then modify the Control ID as appropriate, set the control properties. A static control is created. When the dialog box is displayed, the control on it is also displayed.

Static controls do not need to be created by calling the CREATE () function.
The creation of dynamic controls is quite different. The following uses buttons as an example to describe how to create dynamic controls:
1. Create a Control ID:
The ID number is the identifier of the control. You must set an ID number for the control before creating it.
Open "string table" in the resource and double-click the mouse on the blank line. An ID attribute dialog box is displayed. Enter the ID in the ID edit box, for example, idc_mybutton, enter the title or annotation of the control in caption (note: the caption box cannot be blank. If it is empty, creation fails.) Here, I enter the text to be displayed on the button-Dynamic Button.

2. Create a control object:
Different types of controls should create different class objects:
Button Control cbutton (including common buttons, single-choice buttons, and check buttons)
Edit Control cedit
Static text control cstatic
Ctabctrl
Rotating control cspinbuttonctrl
Slide control csliderctrl
Multi-Info Edit Control cricheditctrl
Progress bar control cprogressctrl
Scroll bar control csrcollbar
Combo control ccombobox
List box control clistbox
Image list control cimagectrl
Tree control ctreectrl
Canimatectrl
In this example, we create a common button for the cbutton class. Note that you cannot directly define a cbutton object, for example, cbutton m_mybut. This definition can only be used to define control variables for static controls, not dynamic controls.

The correct method is to use new to call the cbutton constructor to generate an instance:
Cbutton * p_mybut = new cbutton ();
Use the CREATE () function of the cbutton class to create the function. 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. It can be a combination of the button style and window style. The values include:
Window style:
Ws_child subwindow, which must have
The ws_visible window is visible and generally has
Ws_disabled disabled window, used when creating a button in the initial gray unavailable state
Ws_tabstop available Tab key selection
Ws_group: group. Used to group the first button in a single-choice button.
Button style:
Bs_pushbutton push button, which is also a common button
Bs_autoradiobutton contains a single-choice button in the Automatically Selected status
Bs_radiobutton radio button, not commonly used
Bs_autocheckbox contains the check button in the Automatically Selected status
Bs_checkbox check button, not commonly used
Bs_auto3state: three-state check button with auto-selected status
Bs_3state three-state check button, not commonly used
The above style specifies the button type to be created and cannot be used at the same time, but must have one.
The bs_bitmap button displays the bitmap.
Bs_defpushbutton is set as the default button and only used for the push button. Only one default button can be specified in a dialog box.
Rect specifies the button size and position;
Pparentwnd indicates the parent window with buttons. The value cannot be null;
NID specifies the ID number associated with the button and uses the ID number created in the previous step.
The create () functions of different control classes are slightly different. For more information, see.
Example: p_mybut-> Create ("Dynamic Button", ws_child | ws_visible | bs_pushbutton, crect (20, 10, 80, 40), this, idc_mybutton );

In this way, a 60-width, 30-height button is created at (20, 10) in the current dialog box, and the button text is a dynamic button.
To make the creation process easier and easier, I have defined the following functions:

Show Code print 1 cbutton * ctexteditorview: newmybutton (int nid, crect rect, int nstyle)

2 {

3 cstring m_caption;

4 m_caption.loadstring (NID); // obtain the button title

5 cbutton * p_button = new cbutton ();

6 assert_valid (p_button );

7 p_button-> Create (m_caption, ws_child | ws_visible | bs_pushbutton | nstyle, rect, this, NID); // create button

8 return p_button;

9}

 

 

M_caption.loadstring (NID) reads the button text from the string table. In this way, you should set the text when creating the button ID. The nstyle parameter is an extra style except the required style.

Below, I call this function to create three buttons and specify the first button as the default button. The button ID has been set in advance:

Show Code print 1 cbutton * p_mybut [3];

2 p_mybut [0] = newmybutton (id_mybut1, crect (10, 20, 50, 35), bs_defpushbutton );

3 p_mybut [1] = newmybutton (id_mybut2, crect (55,20, 95,35), 0 );

4 p_mybut [2] = newmybutton (id_mybut3, crect (,), 0 );

 

 

2. Dynamic Control response:
The response function of the dynamic control cannot be added with classwizard, but can only be added manually. Take the preceding button as an example. We create a button and click the response function.
1. Add a response function to message_map:
The message_map table defines the message Response Function in the format of message name (ID, function name). When we use classwizard to add a function, the function is automatically added to the range starting with afx_msg_map, for example:

Show Code print 1 begin_message_map (ctexteditorview, cformview)

2 // {afx_msg_map (ctexteditorview)

3 on_bn_clicked (idc_iconbut0, oniconbut0)

4 //} afx_msg_map

5 end_message_map ()

Do not add them to the afx_msg_map range when manually adding them to prevent classwizard from working properly, for example:

Show Code print 1 begin_message_map (ctexteditorview, cformview)

2 // {afx_msg_map (ctexteditorview)

3 on_bn_clicked (idc_iconbut0, oniconbut0)

4 //} afx_msg_map

5 on_bn_clicked (id_mybut1, onmybut1)

6 on_bn_clicked (id_mybut2, onmybut2)

7 on_bn_clicked (id_mybut3, onmybut3)

8 end_message_map ()

On_bn_clicked is the button to click the message.
2. Add the function definition to the header file:
When you use classwizard to add a function, the function definition is added to the afx_msg range of the header file, for example:

Show the code print 1 protected:

2 // {afx_msg (ctexteditorview)

3 afx_msg void oniconbut0 ();

4 //} afx_msg

5 declare_message_map ()

We mimic this form, just add the function definition outside the afx_msg range:

Show the code print 1 protected:

2 // {afx_msg (ctexteditorview)

3 afx_msg void oniconbut0 ();

4 //} afx_msg

5 afx_msg void onmybut1 ();

6 afx_msg void onmybut2 ();

7 afx_msg void onmybut3 ();

8 declare_message_map ()

3. Compile the message response function:
The above is to associate the message with the function. The specific work that should be done after clicking the button is completed in the function:

Display code print 01 void ctexteditorview: onmybut1 ()

02 {

03 MessageBox ("Ha! You click the Dynamic Button. ");

04}

05 void ctexteditorview: onmybut2 ()

06 {

07 ......

08}

09 void ctexteditorview: onmybut3 ()

10 {

11 ......

12}

In addition to the response function of the button, you can also use the pointer obtained above to access the button, such:
Modify the button size and position: p_mybut [0]-> movewindow (......);
Modify the button text: p_mybut [0]-> setwindowtext (......);
Show/hide button: p_mybut [0]-> showwindow (......); And so on.
Iii. Recycling Resources:
Because the dynamic control object is generated by new, it will not be automatically released by the program, so it needs to be released manually. You can delete a widget when it is no longer in use:
If (p_mybut [0])
Delete p_mybut [0];
The above is the dynamic generation of button controls. Next, let's take a look at the dynamic generation of Single-choice buttons.
4. instances: dynamic generation of radio button groups
The single-choice button also belongs to the cbutton class. However, because the single-choice button is always used in groups, it is different from the common button in terms of creation and use.
Assume that three radio buttons are in a group. Initially, the first radio button is selected.
Let's take a look at the static production method: place three radio buttons in the dialog box and set the attributes as follows:
Radio1 attributes: visible, group, tab stop, and auto
Radio2 attributes: visible, tab stop, and auto
Radio3 attributes: visible, tab stop, and auto
In this way, three single-choice buttons are divided into one group, and only one of them can be selected at a time. If there are other single-choice buttons in the dialog box, they will not interfere with each other during use. However, the first button is not selected yet.

Then, use classwizard to add variables for this set of radio buttons. Here, you only need to add variables for the first radio button. Set the variable name to m_radio and the type to int. In the constructor, classwizard sets the m_radio value to-1 and changes it to 0. In this way, the first radio button is selected when running the program.

Then, you should use classwizard to add and click the response function for the three single-choice buttons, and modify the m_radio value pairs in the response to the three single-choice buttons.
The preceding figure shows how to create a single-choice button group. to dynamically generate a button group, we mainly need to solve the button group and click control problems. Follow these steps:
1. Define the IDs of the three radio buttons:
Open "string table" in the resource and add three ID values:
First: ID is idc_myradio1, caption is single choice 1
Second: ID is idc_myradio2, caption is single choice 2
Third: ID is idc_myradio3, caption is single choice 3
Caption is the text to be displayed on the button, which can be set as needed.
2. Use the CREATE () function of the cbutton class to generate three radio buttons:
For convenience, first define a function generation radio button:

Show Code print 1 cbutton * ctexteditorview: newmyradio (int nid, crect rect, int nstyle)

2 {

3 cstring m_caption;

4 m_caption.loadstring (NID); // obtain the button title

5 cbutton * p_radio = new cbutton ();

6 assert_valid (p_radio );

7 p_radio-> Create (m_caption, ws_child | ws_visible | nstyle | ws_tabstop | bs_autoradiobutton, rect, this, NID); // create button

8 return p_radio;

9}

 

The loadstring () function is used to read the button text from "string table". The create () function sets the attributes required for the single-choice button, including the visible, tab stop, and auto attributes.

The NID parameter is the ID of a Single-choice button, the rect parameter is the size of a single-choice button, and the nstyle parameter is a property other than the required property. The return value is the pointer to the new button.
With this function, you only need to call this function when creating a single-choice button group. The first single-choice button in the single-choice button group must specify the ws_group attribute.

Display code print 1 cbutton * p_myradio [3];

2 p_myradio [0] = newmyradio (idc_myradio1, crect (15,90, 60,105), ws_group );

3 p_myradio [1] = newmyradio (idc_myradio2, crect (15,108, 60,123), 0 );

4 p_myradio [2] = newmyradio (idc_myradio3, crect (15,126, 60,141), 0 );

 

 

3. Define the control variables of the radio button group and set the first radio button to the selected status:
You cannot use classwizard to add variables or add control variables to dodataexchange (). Because dynamic controls do not exist at the beginning, adding control variables to dodataexchange () may cause a running error. Here, we only need to define an int type variable as the control variable in the header file, for example:

Int m_selradio;
In the constructor, set its initial value to 0: m_selradio = 0;
In the above create button statement, use the setcheck () function to set the initial selected button:

Display code print 1 cbutton * p_myradio [3];

2 p_myradio [0] = newmyradio (idc_myradio1, crect (15,90, 60,105), ws_group );

3 p_myradio [1] = newmyradio (idc_myradio2, crect (15,108, 60,123), 0 );

4 p_myradio [2] = newmyradio (idc_myradio3, crect (15,126, 60,141), 0 );

5 p_myradio [m_selradio]-> setcheck (1); // set the first single choice to the selected status

 

 

In the setcheck () function, if the parameter is set to 1, the parameter is set to the selected status. If the parameter is set to 0, the parameter is not selected.
4. Add and click the response function:
After you click a single-choice button, its status can be changed automatically. Here, we also need to modify the value of the control variable m_selradio to track the selected single-choice button.
First, associate the message with the response function by clicking the message in message_map:

Show Code print 1 begin_message_map (ctexteditorview, cformview)

2 // {afx_msg_map (ctexteditorview)

3 on_bn_clicked (idc_iconbut0, oniconbut0) // classwizard

4 //} afx_msg_map

5 on_bn_clicked (idc_myradio1, onmyradio1) // radio button 1

6 on_bn_clicked (idc_myradio2, onmyradio2) // radio button 2

7 on_bn_clicked (idc_myradio3, onmyradio3) // single-choice button 3

8 end_message_map ()

 

 

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

Display code print 01 protected:

02 // {afx_msg (ctexteditorview)

03 afx_msg void oniconbut0 (); // classwizard add

04 //} afx_msg

05 afx_msg void onmyradio1 (); // single choice button 1

06 afx_msg void onmyradio2 (); // radio button 2

07 afx_msg void onmyradio3 (); // single choice button 3

08 declare_message_map ()

09 do not add the function to the afx_msg range to avoid affecting the use of classwizard.

10 define a specific response function (manually added here, not classwizard ):

11 // click the single-choice button 1 void ctexteditorview: onmyradio1 ()

12 {

13 m_selradio = 0;

14}

15 // click the single-choice button 2 void ctexteditorview: onmyradio2 ()

16 {

17 m_selradio = 1;

18}

19 // click the single-choice button 3 void ctexteditorview: onmyradio3 ()

20 {

21 m_selradio = 2;

22}

 

 

5. Recycle resources:
In the destructor, clear the created radio button (you can also recycle it immediately when no radio button is used ):

Show Code print 1 ctexteditorview ::~ Ctexteditorview ()

2 {

3 int I;

4 For (I = 0; I <3; I ++)

5 {

6 if (p_myradio [I])

7 delete p_myradio [I];

8}

9}

 

 

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.