MFC's most detailed introductory tutorial [reproduced]

In the process of learning MFC, I found the following relatively good tutorial, and reproduced here to record
the original address: MFC The most detailed introductory tutorial

 

From:https://blog.csdn.net/wang18323834864/article/details/78621633/

Visual Studio 2019:https://visualstudio.microsoft.com/zh-hans/

 

Chicken pecking rice ----- Catalog and summary of VS2010/MFC programming introductory tutorial: http://www.jizhuomi.com/software/257.html

      1. Catalog of VS2010/MFC programming tutorial

       Part 1: VS2010/MFC Development Environment

       Introduction to VS2010/MFC programming Preface
       One of the introduction to VS2010/MFC programming (VS2010 and MSDN installation process diagram)

       Part II: VS2010/MFC Application Framework

       Getting Started with VS2010/MFC Programming Part 2 (Using the MFC Wizard to Generate a Single-Document Application Framework) Getting
       Started with VS2010/MFC Programming Part 3 (The Composition and Structure of Files in VS2010 Application Engineering) Getting
       Started with VS2010/MFC Programming Part 4 (MFC Application Framework Analysis)
       Introduction to VS2010/MFC Programming Five (Overview of MFC Message Mapping Mechanism)

       Part III: Dialog

       Getting Started with VS2010/MFC Programming Six (Dialog Box: Create Dialog Template and Modify Dialog Properties) Getting
       Started with VS2010/MFC Programming Seven (Dialog Box: Adding Controls to Dialog Boxes)
       Getting Started with VS2010/MFC Programming Eight (Dialog Box: Create Dialog box class and adding control variables)
       VS2010/MFC programming entry nine (dialog box: add message processing function for the control)
       VS2010/MFC programming entry ten (dialog box: set the tab order of the dialog box control)
       VS2010/MFC programming entry The eleventh (dialog box: modal dialog box and its pop-up process)
       The twelfth introduction to VS2010/MFC programming (dialog box: the creation and display of non-modal dialog boxes) The
       thirteenth introduction to VS2010/MFC programming (dialog box: Introduction to property page dialog boxes and related classes) Introduction
       to VS2010/MFC programming fourteen (dialog box: creation and display of wizard dialog boxes) Introduction to
       VS2010/MFC programming fifteenth (dialog box: creation and display of general property page dialog box Display)
       VS2010/MFC Programming Introduction 16 (Dialog Box: Message Dialog Box)
       VS2010/MFC Programming Introduction 17 (Dialog Box: File Dialog Box)
       VS2010/MFC Programming Introduction 18 (Dialog Box: Font Dialog Box)
       VS2010/MFC Programming Introduction Nineteen (Dialog Box: Color Dialog Box)

       Part Four: Common Controls

       VS2010/MFC Programming Introduction 20 (Common Controls: Static Text Box)
       VS2010/MFC Programming Introduction 21 (Common Controls: Edit Box Edit Control)
       VS2010/MFC Programming Introduction 22 (Common Controls: Button Control Button , Radio Button and Check Box)
       VS2010/MFC Programming Introduction 23 (commonly used controls: programming examples of button controls)
       VS2010/MFC Programming Introduction 24 (commonly used controls: list box control ListBox)
       VS2010/MFC Programming Introduction 1 Twenty-five (commonly used controls: combo box control Combo Box)
       VS2010/MFC programming introduction 26 (commonly used controls: scroll bar control Scroll Bar)
       VS2010/MFC programming introduction 27 (commonly used controls: picture control Picture Control)
       VS2010/MFC Programming Introduction 28 (Common Controls: List View Control List Control)
       VS2010/MFC Programming Introduction 29 (Common Controls: List View Control List Control)
       VS2010/MFC Programming Introduction 30 (Common Uses Control: tree control Tree Control)
       VS2010/MFC Programming Introduction 31 (commonly used controls: tree control Tree Control)
       VS2010/MFC Programming Introduction 32 (commonly used controls: label control Tab Control)
       VS2010/ Introduction to MFC Programming Thirty-Three (Common Controls: Under Tab Control)

       Part Five: Menus, Toolbars and Status Bars

       VS2010/MFC Programming Introduction Thirty-Four (Menu: Detailed Explanation of VS2010 Menu Resources)
       VS2010/MFC Programming Introduction Thirty-five (Menu: Menu and CMenu Class Use)
       VS2010/MFC Programming Introduction Thirty-six (Toolbar: Tools Bar resources and CToolBar class)
       VS2010/MFC programming introduction thirty-seven (toolbar: toolbar creation, docking and use)
       VS2010/MFC programming introduction thirty-eight (detailed use of the status bar)

       Part VI: Documentation, Views, and Frames

       Introduction to VS2010/MFC Programming 39 (Documents, Views and Frameworks: Overview)
       Introduction to VS2010/MFC Programming 40 (Documents, Views and Frames: Relationships between Objects)
       Introduction to VS2010/MFC Programming 41 ( Documents, Views, and Frames: Split Windows)

       Part VII: MFC common classes

       Introduction to VS2010/MFC Programming 42 (Common MFC Classes: CString Class)
       Introduction to VS2010/MFC Programming 43 (Common MFC Classes: CTime and CTimeSpan Classes)
       Introduction to VS2010/MFC Programming 44 (Common MFC Classes : Timer Timer)
       VS2010/MFC Programming Introduction 45 (MFC common class: CFile file operation class)
       VS2010/MFC Programming Introduction 46 (MFC common class: MFC exception handling)

       Part 8: Fonts and Text Output

       VS2010/MFC Programming Introduction 47 (Font and Text Output: CFont Font Class)
       VS2010/MFC Programming Introduction 48 (Font and Text Output: Text Output)

       Part IX: Graphical Images

       VS2010/MFC programming introduction forty-nine (graphic image: CDC class and its screen drawing function)
       VS2010/MFC programming introduction fifty (graphic image: GDI object brush CPen)
       VS2010/MFC programming introduction fifty-one (graphics Image: GDI object brush CBrush)

       Part 10: Ribbon interface development

       Introduction to VS2010/MFC programming fifty-two (Ribbon interface development: creating a Ribbon-style application framework) Introduction to
       VS2010/MFC programming fifty-three (Ribbon interface development: adding controls for the Ribbon Bar)
       Introduction to VS2010/MFC programming fifty Four (Ribbon interface development: use more controls and add message processing functions for controls)

 

 

The screenshots in this article are based on VS2019 

 

 

1. Create  a new MFC  project

 

  • 1. Select the menu item  File->New->Project , and the " New Project " dialog box will pop up.
  • 2. Select MFC , click Next, and then enter the project name , in this example, name it "Addition", and set the save path of the project . Click " Create ".
  •  3. Select dialog-based in the drop-down list of application type , and use the default settings for others, and click " Finish ".

See in solution view , the file of this project is much less than single-document application, there are three main classes in Class View : CAboutDlg , CAdditionApp and CAdditionDlg  .

  1. CAboutDlg is the application's "About" dialog class,
  2. CAdditionApp is a class derived from CWinApp,
  3. CAdditionDlg  is the main dialog class, and the main dialog is the main interface displayed after the application runs.

 

open resource view

In the Resource View view, you can see the resource tree of the project Addition, expand Addition.rc, there are four sub-items below: Dialog (dialog box), Icon (icon), String Table (string table) and Version (version). Then expand the Dialog item, there are two dialog templates below, and their IDs are: IDD_ABOUTBOX and IDD_ADDITION_DIALOG, the former is the template of the "About" dialog box, and the latter is the template of the main dialog box. ID is the unique identifier of a resource, and is essentially an unsigned integer. Generally, the integer value represented by an ID is defined by the system, and we don't need to intervene.

It can be seen that for the main dialog box, the creation of a new dialog template in the first step of creating a dialog box has been automatically completed by the system. If you need to add and create a new dialog template, you need to right-click on the "Dialog" node of Resource View, select "Insert Dialog" in the right-click menu, a new dialog template will be generated, and the ID will be automatically assigned. As shown in the picture:

Right-click on the Addition dialog template, and then select Properties in the right-click menu, and the property list of the dialog box will be displayed in the right panel. As shown below:

illustrate:

  • 1. ID: Dialog ID, which uniquely identifies the dialog resource and can be modified. Here is IDD_ADDITION_DIALOG, we don't modify it.
  • 2. Caption: dialog box title . Here the default is empty, we will modify it to "Addition Calculator".
  • 3. Border: border type. There are four types: None, Thin, Resizing, and Dialog Frame. We use the default Dialog Frame.
  • 4. Maximize: Whether to use the maximize button. We use the default of False.
  • 5. Minimize: Whether to use the minimize button. Also we use the default False.
  • 6. Style: dialog box type. There are three types: Overlapped (overlapped window), Popup (popup window), and Child (child window). Pop-up windows are relatively common. We use the default Popup type.
  • 7. System Menu: Whether there is a system menu in the upper left corner of the title bar, including menu items such as move and close. We use the default of True.
  • 8.Title Bar: Whether to have a title bar. We use the default of True.
  • 9.Font(Size): Font type and font size. If it is modified to a non-system font, Use System is automatically changed to False. And if Use System is originally False, change it to True, then Font(Size) is automatically set to the system font. Here we use the default system font.

Modified title property. At this time, the interface after we run this program is as follows:

 

1. Add a static text box (Static Text) to the dialog box to display the string -- "summand".

For a static text box titled "TODO:Place dialog controls here." that is automatically added, delete it here and continue to add new static text boxes.
When deleting a control, you can use the left mouse button to click to select it, and a dotted frame will appear around the control after selection, and then press the Delete key to delete it. Open the dialog template IDD_ADDITION_DIALOG created in the previous lecture in the Resource View of the "Addition" project, and the automatically added static text box can be deleted in this way.
Before adding a new static text box, check whether the Toolbox view is displayed. If not, click View->Toolbox on the menu bar. The Toolbox view is as shown below:

        Some commonly used controls are listed in the Toolbox , one of which is Static Text , which is the control we want to add. Click and hold the left mouse button on the Static Text in the Toolbox, and drag it to the IDD_ADDITION_DIALOG dialog template, a dotted frame will appear on the template, we find a suitable position and release the left mouse button to drop it.

       After selecting the control with the left mouse button, a dotted frame will appear around it, and then move the mouse to a few black dots on the dotted frame and it will become a two-way arrow shape. At this time, you can press the left mouse button and drag to change the size of the control . We can change the size of the newly added static text box control in this way to better display the title. Of course, the entire dialog template can also be resized in this way.

       Next, it's time to modify the text of the static text box. Right-click the static text box, select "Properties" in the right-click menu, and the Properties panel will be displayed. On the panel, modify the Caption property to "summand", and modify the ID to IDC_SUMMAND_STATIC. At this time, the template is as follows:

 

2. Add an edit box (Edit Control) to the dialog box to enter the summand.

The process of adding an edit box is similar to that of a static text box. Select the Edit Control control in the Toolbox and drag it to the dialog template, align it horizontally with the previous static text box (for aesthetics), and then adjust its size to fit the added text box. Number input.
Right-click on the edit box, still select "Properties" in the right-click menu to display the Properties (Properties) panel, and modify its ID to IDC_SUMMAND_EDIT. At this time, the template is as follows:

3. Add a static text box titled "Addend" according to the method in 1, which is used to display the string -- "Addend". And change its ID to IDC_ADDEND_STATIC.
4. Follow the method in 2 to add an edit box with ID IDC_ADDEND_EDIT to input the addend.
5. Follow the method in 1 to add a static text box titled "and" to display the text -- "and". And modify its ID to IDC_SUM_STATIC.
6. Add an edit box with the ID IDC_SUM_EDIT according to the method in 2 to display the final sum.
7. A similar button (Button) control is added to the dialog template, which is used to trigger the addition calculation after being clicked. Change its title to "Calculation" and its ID to IDC_ADD_BUTTON.

So far, the dialog box template is as shown in the figure:

8. Delete the  OK  button. Open  the Properties panel for the Cancel  button, change the Caption to "Exit" and align it horizontally with the Calculate button.
9. According to the layout of the control, properly adjust the size of the entire dialog template to make it a suitable size relative to the layout of the control and have a beautiful interface.
In this way, the controls we need to use in this example are added in the dialog template. The final effect is as follows:

Run the screenshot:

 

 

Create dialog class

Because the program Addition is a dialog-based program, the program automatically creates a dialog template IDD_ADDITION_DIALOG, and automatically generates a dialog class CAdditionDlg, which is derived from the CDialogEx class. Everyone who has used VC++ 6.0 may remember that the dialog classes we defined are all derived from the CDialog class, but in VS2010, the general dialog classes are inherited from the CDialogEx class.

If it is a newly added dialog template, how to create a dialog class for it?

  • 1. Right-click on the "Dialog" node of Resource View, and then select "Insert Dialog" in the right-click menu to create a new dialog template, and the ID uses the default IDD_DIALOG1.
  • 2. The newly created dialog template will be displayed in the middle area, then select this dialog template, right-click, and select Add Class from the right-click menu.

3. After selecting "Add Class", a dialog box will pop up. Just write a custom class name in the edit box under "Class name" in the dialog box, such as CMyDialog.
4. Finally, click "Finish" to complete.

Finally, you can see the newly generated dialog class CMyDialog in Class View, and the corresponding MyDialog.h header file and MyDialog.cpp source file are generated in Solution Explorer. The CMyDialog class is also derived from the CDialogEx class.
Note that general class names start with C, for example, CTestDlg.

 

 

Add variables to the controls in the dialog

        In the above steps  , several controls are added to the dialog box , including three static text boxes, three edit boxes, and one button control. The program-generated Cancel button remains as an exit button, while the OK button is removed.

       The static text box is just to explain the meaning of the data in the following edit box, whether it is the summand, addend or sum, so they will not change, and we will not add variables for them. Button controls are used for operations, and variables are not added to them here. The data in the edit box may change frequently, it is necessary to associate a variable for each of them.

 

First add a variable for the IDC_SUMMAND_EDIT edit box for the summand.

  • 1. Right click on the edit box and select "Add Variable" from the context menu. A wizard dialog box for adding member variables will pop up.
  • 2. We want to add a value variable to it instead of a control variable, so select Value in the combo box under "Category" in the dialog box.
  • 3. The combo box under "Variable type" selects "CString" by default at this time. CString is a string class, and obviously cannot perform addition operations. We can choose double, float, int, etc. Here we choose double, that is, the edit box is associated with a variable of double type.
  • 4. Write the custom variable name in "Variable name". Chicken pecking rice named it m_editSummand.

5. Click "Finish" to complete.

Note that the member variable name of a class generally begins with m_ to identify it as a member variable.

Referring to this method, add a double variable m_editAddend to the addend edit box IDD_ADDEND_EDIT, and add a double variable m_editSum to the edit box IDD_SUM_EDIT.

 

Data Exchange and Validation of Dialog Classes

       In the program running interface, the user often changes the properties of the control, for example, input a character string in the edit box, or change the selected item of the combo box, or change the selected state of the check box. After the property of the control is changed, MFC will modify the value of the associated variable of the control accordingly. This synchronous change is realized through the member function DoDataExchange() automatically generated by MFC for the dialog class, which is also called the data exchange and inspection mechanism of the dialog box.

       After we added variables for the three edit boxes, there are three more DDX_Text call statements in the function body of the DoDataExchange() function of CAdditionDlg in AdditionDlg.cpp. The following is the code of the function body and the comments added by chicken pecking rice.

       Take the Addition program as an example to briefly talk about the data exchange mechanism. If we enter the summand in the program running interface, the input value can be saved to the m_editSummand variable through the DoDataExchange() function of CAddition, otherwise if the value of the variable m_editSummand is modified during the running of the program, it can be saved through the DoDataExchange() of CAddition The function can also display the new variable value in the addend's edit box.

       But in this data exchange mechanism, DoDataExchange() is not automatically called, but we need to call the CDialogEx::UpdateData() function in the program, and then the UpdateData() function will automatically call DoDataExchange().

       The prototype of the CDialogEx::UpdateData() function is: BOOL UpdateData(BOOL bSaveAndValidate = TRUE);

       Parameters: bSaveAndValidate is used to indicate the direction of data transmission, TRUE means from the control to the variable , FALSE means from the variable to the control . The default value is TRUE, which is passed from the control to the variable.

       Return value: The return value of the CDialogEx::UpdateData() function indicates whether the operation is successful. If successful, it returns TRUE, otherwise it returns FALSE.

       In the next lecture, we will demonstrate how to use the CDialogEx::UpdateData() function.

       Chicken Pecking Rice This section mainly talks about creating new dialog classes and adding control variables. The message processing functions of controls will be introduced in detail in the next lecture.

 

 

Add a message processing function for the control.

 Creating dialog classes and adding control variables have already been mentioned above. The main content of this lecture is how to add message processing functions for controls.

 

       MFC defines many messages for dialog boxes and controls , etc. When we operate on them, messages are triggered, and these messages are finally processed by message processing functions. For example, when we click a button, a BN_CLICKED message will be generated, and when the content of the edit box is modified, an EN_CHANGE message will be generated. Generally, in order to achieve the effect of a certain operation, we only need to implement the message processing function of a certain message.

 

1. Add message processing function

       Chicken pecking rice Still take the previous program of the addition calculator as an example to illustrate how to add a message processing function for the "Calculation" button control. There are 4 ways to add:

       

  • 1. Use Class Wizard to add message processing function

       Friends who have used VC++  6.0 should be familiar with Class Wizard. It is often used to add classes , message processing functions, etc. It can be said to be a very core function. But since VS2002, you can't see the Class Wizard anymore. Most of the functions are integrated into the properties of dialog boxes and controls, etc., which is very convenient to use. In VS2010 , the long-lost Class Wizard is back. However, Chicken Pecking Rice is used to using the functions in properties. For those who directly transfer from VC++ 6.0 to VS2010, they may feel that they are more accustomed to using Class Wizard.

       You should remember that the ID of the "Calculate" button is IDC_ADD_BUTTON. In the above figure  , under the command label , there is this ID in the object ID list. Because we want to implement the message processing function after clicking the button,  select the BN_CLICKED message in the message list. Then click  Add Handler on the upper right to add the BN_CLICKED message processing function OnClickedAddButton. Of course, you can also change the name, but generally you can use the default one.

 

  • 2. Add a message processing function through "Add Event Handler..."

       Right-click on the "Calculation" button, and then select the menu item "Add Event Handler..." in the right-click menu, and the "Event Handler Wizard" dialog box will pop up, as shown in the figure below:

It can be seen that the BN_CLICKED message is selected by default in the "Message Type", and the function name and class are automatically given, just click "OK".

 

  •   3. Add a message processing function in the property view of the button

       As mentioned above, since VS2002 , the message processing function has been added mainly from the property view. We right-click on the "calculate" button, select "Properties" in the right-click menu, and the property view of the button will be displayed in the right panel.

We can click the " Control Event " button ( similar to a lightning bolt )        in the attribute view as shown in the figure above , and all the messages of the "Calculation" button are listed below. What we want to process is the BN_CLICKED message. Click the blank list item on the right, and a button with a down arrow will appear. Click this button again and the "<Add> OnBnClickedAddButton" option will appear. Finally, select this option and the BN_CLICKED processing function will be added automatically. up.

 

  •  4. Double-click the button to add a message processing function

       The most direct and easiest method is to double-click the "Calculate" button, and MFC will automatically add the processing function OnBnClickedAddButton() for the BN_CLICKED message in the CAdditionDlg class.

 

 

Add custom functionality in the message handler function

       After we use any method to add the message processing function, we can only get an empty function body of OnBnClickedAddButton() function. To realize the function we want, we need to add custom function code in the function body.

       In the addition calculator program, the function we want the "Calculation" button to achieve is to obtain the values ​​of the summand and the addend, and then calculate their sum and display it in the edit box of the sum. Then, the function body of OnBnClickedAddButton() should be modified as:


  
  
   
   
  1. void CAdditionDlg::OnClickedAddButton()
  2. {
  3. // TODO: add control notification handler code here
  4. // Save the data in each control to the corresponding variable
  5. UpdateData(TRUE);
  6. // Assign the sum of the summand and the addend to m_editSum
  7. m_editSum = m_editSummand + m_editAddend;
  8. // Update the corresponding control according to the value of each variable. and the edit box will display the value of m_editSum
  9. UpdateData(FALSE);
  10. }

        Comments have been added to the above code, which should be easy for everyone to understand. The description of the UpdateData() function has been introduced in the previous lecture. If you forget it, you can go back to the previous lecture to learn more. Next we run the application. In the running result interface, input the summand 1.1 and the addend 2.2, then click "Calculate":

Simple analysis of the running process: input the summand and addend, click the "Calculate" button to generate a click message, and then call the OnBnClickedAddButton() function. After entering this function, the value of the summand 5.1 and the value of the addend 2.3 are saved to the variables m_editSummand and m_editAddend respectively by the UpdateData(TRUE) function, and then the summand and the addend are calculated by the statement m_editSum = m_editSummand + m_editAddend; The sum is 7.4, and assign 7.4 to m_editSum. Finally, call UpdateData(FALSE) to update the display values ​​of the three edit boxes according to the values ​​of the summand, addend, and sum, and the result in the above figure is obtained.

       At this point, an addition calculator application with simple addition functions is basically completed.

 

 

How to adjust the tab order of the controls on the dialog box.

After adding a message processing function for the "Calculate" button in the previous lecture , the addition calculator can already perform floating-point addition operations. But there is still a small remaining problem, that is, the tab order of the dialog box control.

       Run the addition calculator program, do not perform any operation after the dialog box is displayed, just press Enter, and you can see that the dialog box has exited. This is because the "Exit" button is a control with a tab order of 1, which is the first control to accept user input. But according to our input habits, it should be the addend edit box that accepts user input first, then the addend edit box, then the "Calculate" button, and finally the "Exit" button.

       First look at the tab order of each control intuitively : open the " resource view ", and then find the dialog box IDD_ADDITION_DIALOG in the resource, double-click the ID and its template view will appear in the middle client area. Select "Format" -> "Tab Order" in the main menu, or press the shortcut key Ctrl+D, and the tab order number of each control will be displayed on the dialog box template. As shown below:

       In the figure above, there is a number in the upper left corner of each control, which is its Tab response order. When the dialog box is just opened, the input focus is on the "Exit" button with the Tab order of 1. If you press the Tab key without any operation, the input focus will be transferred to the "summand" static text box with the Tab order of 2. But because the static text box does not accept any input, the input focus continues to automatically shift to the summand edit box with the tab order of 3, and then press the Tab key, and the input focus will shift to the "addend" static text with the tab order of 4 On the box, also because it is a static text box, the input focus will continue to be transferred to the addend edit box, and the following controls are the same.

       We think this order is unreasonable, so how to modify it? It's very simple, start from the control that you think the Tab order should be 1, and click in turn. With the completion of the click, the Tab response order of each control is also set according to our ideas.

       For example, in this example, we can click the summand edit box, "summand" static text box, addend edit box, "addend" static text box, and edit box, "and" static text box, " Calculate" button and "Exit" button. After setting, as shown below:

Finally, press the ESC key to confirm the setting and exit the tab order setting state of the dialog template.

       Now we run the program again, we can see that after the dialog box is opened, the initial input focus is on the summand edit box, and then we press the Tab key, and the input focus moves to the addend edit box. The focus will be transferred circularly in the order of "and edit box--'calculate' button--'exit' button--summand edit box-addend edit box--and edit box...". This achieves our purpose.

 

 

Modal dialogs and non-modal dialogs, and how modal dialogs pop up.

 

1.   Modal dialog box and non- modal dialog box

       Windows dialogs are divided into two categories: modal dialogs and modeless dialogs .

  1.  A modal dialog box is such a dialog box: when it pops up, other windows of the application will no longer accept user input, and only the dialog box responds to user input, and other windows can continue to communicate with the user after the corresponding operation is performed on it and exits. interact.
  2.  Non-modal dialog box: After the non-modal dialog box pops up, other windows of the program can still respond to user input. Non-modal dialog boxes are generally used to display prompt information and so on.

       Everyone knows the Windows system very well, and I believe that these two dialog boxes should have been encountered. The previous adding calculator dialog is actually a modal dialog.

 

2. How the modal dialog box pops up

       After all, most of the addition calculator programs are automatically generated by MFC, and you may not be very clear about how the dialog box pops up. Chicken pecking rice Let me briefly talk about where it pops up, and then rebuild a new dialog box and pop it up, so that everyone can use the modal dialog box more flexibly after practice.

       If you open the Addition.cpp file, you can see that the CAdditionApp class has an InitInstance() function.   This function was mentioned in the MFC application framework analysis , but it is in the single-document application App class, and the function body is not the same. But they all initialize the App class instance.

       In the second half of the InitInstance() function,  there is a piece of code that defines the dialog object and pops up the dialog box . The following code is given and commented:


  
  
   
   
  1. CAdditionDlg dlg; // Define the object dlg of the dialog class CAdditionDlg
  2. m_pMainWnd = &dlg; // Set dlg as the main window
  3. INT_PTR nResponse = dlg.DoModal ( ); // Pop up the dialog box dlg, and assign the return value of the DoModal function (the ID of the button clicked when exiting) to nResponse
  4. if (nResponse == IDOK) // Determine whether the return value is the OK button (its ID is IDOK, which has been deleted by chicken pecking rice)
  5. {
  6. // TODO: When to place the processing here
  7. // "OK" to close the dialog code
  8. }
  9. else if (nResponse == IDCANCEL) // Determine whether the return value is a Cancel button (its ID is IDCANCEL, and the chicken pecking rice changed its Caption to "exit")
  10. {
  11. // TODO: When to place the processing here
  12. // code to "cancel" to close the dialog
  13. }
  14. else if (nResponse == -1)
  15. {
  16. TRACE (traceAppMsg, 0 , "Warning: Dialog creation failed, the application will terminate unexpectedly.\n" );
  17. TRACE (traceAppMsg, 0 , "Warning: You cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS if you are using MFC controls on dialogs.\n" );
  18. }

One of the key functions of the pop-up dialog box is the DoModal() function of the dialog box class. The prototype of the CDialog::DoModal() function is:

       virtual INT_PTR DoModal();   

       Return value: an integer value specifying the value of the nResult parameter passed to CDialog::EndDialog (this function is used to close the dialog box). Returns -1 if the function cannot create the dialog, or IDABORT if another error occurs.

       After calling it, a dialog box will pop up, and the return value is the ID of the button clicked when exiting the dialog box. For example, if we click the "Exit" button, then the return value of DoModal is IDCANCEL.

 

 3. Add a new dialog and pop it up

Adds a dialog to the adding calculator program that asks the user if they want to perform a calculation before calculating it. You can take a complete look at the process of adding and popping up the dialog box.

       1. Right click on "Dialog" in Resource View and select "Insert Dialog", create a new dialog template, modify its ID to IDD_TIP_DIALOG, change Caption to "Prompt", and then refer to "Adding Controls to Dialog Box " As mentioned above, add a static text box (static text) to the dialog template, and change the Caption to "Are you sure you want to perform the addition calculation?", and then modify the Caption of the OK button to "OK", and the Caption of the Cancel button to " Cancel", and finally adjust the position of each control and the size of the dialog box. The final dialog template is as follows:

VS2010/MFC Programming Introduction Eleven (dialog box: modal dialog box and its pop-up process)

2. According to the method of creating a dialog class in "Creating a dialog class and adding a control variable", right-click on the dialog template and select "Add Class..." to pop up a dialog box for adding a class, and set "Class name        " to CTipDlg, click "OK". In Solution Explorer, you can see that the header file TipDlg.h and the source file TipDlg.cpp of the CTipDlg class are generated.

       3. We want to pop up this prompt dialog box after clicking the "Calculate" button, then we need to access the prompt dialog class in the message processing function OnBnClickedAddButton() of the "Calculate" button, so in order to access the CTipDlg class, in AdditionDlg.cpp Include the header file of CTipDlg: #include "CTipDlg.h".

       4. Modify the function body of OnBnClickedAddButton(). Before all the codes, construct the object tipDlg of the CTipDlg class, and use the statement tipDlg.DoModal(); to pop up a dialog box, and finally determine whether the return value of the DoModal() function is IDOK or IDCANCEL Whether to continue the calculation. The OnBnClickedAddButton() function is modified as follows:


  
  
   
   
  1. void CAdditionDlg::OnClickedAddButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. INT_PTR nRes; // Used to save the return value of the DoModal function
  5. CTipDlg tipDlg; // Construct an instance of dialog class CTipDlg
  6. nRes = tipDlg.DoModal (); // popup dialog box
  7. if (IDCANCEL == nRes) // Determine whether the return value is IDCANCEL after the dialog box exits, if it is, return, otherwise continue to execute
  8. return;
  9. // Save the data in each control to the corresponding variable
  10. UpdateData(TRUE);
  11. // Assign the sum of the summand and the addend to m_editSum
  12. m_editSum = m_editSummand + m_editAddend;
  13. // Update the corresponding control according to the value of each variable. and the edit box will display the value of m_editSum
  14. UpdateData(FALSE);
  15. }

       5. Test. After compiling and running the program, enter the summand and the addend in the dialog box, click "Calculate", a prompt dialog box pops up asking whether to perform the calculation, if you choose "OK", the prompt dialog box exits, and displays on the main dialog box The sum of the summand and the addend, and if "Cancel" is selected, the prompt dialog box will also exit, but the sum displayed in the main dialog box remains unchanged, that is, no addition calculation is performed.

 

 

Create and display modeless dialog boxes.

 

Summary: The main steps are, after creating a new dialog box, associate a class, and then use a pointer to point to the class; then use the pointer to create and display the dialog box, and finally destroy the pointer in the virtual function to release resources.

       After the non-modal dialog box is displayed, other windows of the program can still run normally, respond to user input, and switch between each other . Change the Tip modal dialog box created in the previous lecture to a non-modal dialog box, let everyone see the effect.

       In fact, there is no difference between modal dialog and non- modal dialog in creating dialog resources and generating dialog classes, so neither the IDD_TIP_DIALOG dialog resource nor the CTipDlg class created in the previous lecture needs to be modified.

       What needs to be modified is the creation and display of the dialog class instance, that is, the dialog display code added in the CAdditionDlg::OnBnClickedAddButton() function body. Here are the specific steps:

  • 1. Include the CTipDlg header file in AdditionDlg.h and define the pointer member variable of CTipDlg type. The detailed operation method is to delete the previously added #include "CTipDlg.h" in AdditionDlg.cpp, and add #include "CTipDlg.h" in AdditionDlg.h, because we need to define the CTipDlg type in AdditionDlg.h pointer variable, so its header file should be included first; then add private member variable CTipDlg *m_pTipDlg; to CAdditionDlg class in AdditionDlg.h.
  • 2. Initialize the member variable m_pTipDlg in the constructor of the CAdditionDlg class . If there are too many functions in the cpp file, we can find the CAdditionDlg class in the upper half of the Class View, and then find its constructor in the lower half of the view. Double-click, and the middle client area can immediately switch to the implementation of the constructor. It is a good habit to add m_pTipDlg = NULL; in the constructor body. Chicken pecking rice mentioned in the pointer assignment and pointer arithmetic of the C++ programming introduction series that it is initialized before any pointer variable is used, which can avoid accidental access. important memory address and destroy the data at this address.
  • 3. Comment or delete the modal dialog display code added in the previous lecture, and add the non-modal dialog creation and display code. In VC++, "//" is used to comment a single line of code, and "/*" can be added at the beginning of the code to be commented, and "*/" at the end of the commented code. The modified CAdditionDlg::OnBnClickedAddButton() function is as follows:

  
  
   
   
  1. void CAdditionDlg::OnClickedAddButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. /*INT_PTR nRes; // Used to save the return value of the DoModal function
  5. CTipDlg tipDlg; // Construct an instance of dialog class CTipDlg
  6. nRes = tipDlg.DoModal(); // popup dialog box
  7. if (IDCANCEL == nRes) // Determine whether the return value is IDCANCEL after the dialog box exits, if it is, return, otherwise continue to execute
  8. return;*/
  9. // If the value of the pointer variable m_pTipDlg is NULL, the dialog box has not been created yet and needs to be created dynamically
  10. if ( NULL == m_pTipDlg)
  11. {
  12. // Create a non-modal dialog instance
  13. m_pTipDlg = new CTipDlg();
  14. m_pTipDlg-> Create(IDD_TIP_DIALOG, this);
  15. }
  16. // show a modeless dialog
  17. m_pTipDlg-> ShowWindow(SW_SHOW);
  18. // Save the data in each control to the corresponding variable
  19. UpdateData(TRUE);
  20. // Assign the sum of the summand and the addend to m_editSum
  21. m_editSum = m_editSummand + m_editAddend;
  22. // Update the corresponding control according to the value of each variable. and the edit box will display the value of m_editSum
  23. UpdateData(FALSE);
  24. }

  In this way, the code for creating and displaying the non-modal dialog box is added and modified. Let's run it to see the effect.

      Enter the summand and addend in the addition calculator dialog box, and then click the "Calculate" button, the prompt dialog box will still pop up as in the previous section, but don't close it yet, you can drag the addition calculator dialog box behind it Try the box, we found that the addition calculator dialog box can be dragged, and the calculation result has been displayed in the "and" edit box, which indicates that the prompt dialog box has not been closed after it is displayed, and OnBnClickedAddButton() will continue to execute downward , not only that, each edit box of the addition calculator can also respond to input.

This is just a simple example. Modeless dialog boxes have many uses, and you will use them in software development in the future.

 

 

Property Pages dialog

 

Classification of property page dialog boxes

The property page dialog box must be familiar to everyone. In the XP system, right-click on the desktop and click Properties, and the pop-up is the property page dialog box, which switches each page through tabs. In addition, the wizard dialog box we use when creating an MFC project is also a property page dialog box, which switches pages by clicking buttons such as "Next".
The property page dialog box includes general property page dialog box and wizard dialog box. It integrates multiple dialogs in one, and switches pages through tabs or buttons.
Property page dialog related classes

When we use the property page dialog box, there are two main classes used: CPropertyPage class and CPropertySheet class.

 

 1. CPropertyPage class

       The CPropertyPage class inherits from the CDialog class, and it is used to process a single property page, so create a subclass that inherits from CPropertyPage for each property page. You can find detailed descriptions of the CPropertyPage class and its members in MSDN of VS2010 . The following chicken pecking rice will explain some of the main member functions of the CPropertyPage class listed in MSDN.


  
  
   
   
  1. ( 1 ) Constructor
  2.         Here are three constructors of the CProperty class. The function prototype is:
  3.         CPropertyPage( );
  4.         explicit CPropertyPage(
  5.                 UINT nIDTemplate,
  6.                 UINT nIDCaption = 0,
  7.                 DWORD dwSize = sizeof(PROPSHEETPAGE)
  8.         );
  9.          explicit CPropertyPage(
  10.                 LPCTSTR lpszTemplateName,
  11.                 UINT nIDCaption = 0,
  12.                 DWORD dwSize = sizeof(PROPSHEETPAGE)
  13.         );
  14.        The first is a constructor without any parameters.
  15.        In the second constructor, the parameter nIDTemplate is the dialog resource ID of the property page,
  16. The parameter nIDCaption is the ID of the string resource used for the title of the property page dialog box tab,
  17. If set to 0 , the tab title uses the title of the property page's dialog resource.
  18.        In the third constructor, the parameter lpszTemplateName is the name string of the dialog resource of the property page,
  19. Cannot be NULL . The parameter nIDCaption is the same as above.
  20. ( 2 ) CancelToClose() function
  21.        After an unrecoverable operation has been performed on the property page of the modal property page dialog box, use the CancelToClose() function
  22. Change the "OK" button to a "Close" button and disable the "Cancel" button. The function prototype is:
  23.         void CancelToClose( );
  24. ( 3 ) SetModified() function
  25.        Call this function to activate or deactivate the "Apply" button, the function prototype is:
  26.         void SetModified( BOOL bChanged = TRUE);
  27. ( 4 ) Overloadable functions
  28.        The CPropertyPage class provides some message processing functions to respond to various messages of the property page dialog box.
  29. We can customize the processing of property page dialog box operations by overloading these message processing functions.
  30. Overloadable message handlers include:
  31.        OnApply: Handle the message that the "Apply" button of the property page is clicked
  32.        OnCancel: Handle the message that the "Cancel" button of the property page is clicked
  33.        OnKillActive: Handle the message that the current active state of the property page is switched, often used for data validation
  34.        OnOK: Handle the message that the "OK" button, "Apply" button or "Close" button of the property page is clicked
  35.        OnQueryCancel: Handle the message sent before the "Cancel" button of the property page is clicked
  36.        OnReset: Handle the message that the "Reset" button of the property page is clicked
  37.        OnSetActive: Handle the message that the property page is switched to the current active page
  38.        OnWizardBack: Handle the message that the "Back" button of the property page is clicked, only valid in the wizard dialog box
  39.        OnWizardFinish: Handle the message that the "Finish" button of the property page is clicked, only valid in the wizard dialog box
  40.        OnWizardNext: Handle the message that the "Next" button of the property page is clicked, only valid in the wizard dialog box

 

2. CPropertySheet class

       The CPropertySheet class inherits from the CWnd class, which is a property sheet class responsible for loading, opening or deleting property pages, and switching property pages in the property page dialog box. It is similar to a dialog box, and it also has two types: modal and non-modal. The following chicken pecking rice will explain some member functions of the CPropertySheet class.


  
  
   
   
  1. ( 1 ) Constructor
  2.        The three constructors of the CPropertySheet class are still listed here:
  3.        CPropertySheet( );
  4.         explicit CPropertySheet(
  5.                UINT nIDCaption,
  6.                CWnd* pParentWnd = NULL,
  7.                UINT iSelectPage = 0 
  8.        );
  9.        explicit CPropertySheet(
  10.                LPCTSTR pszCaption,
  11.                CWnd* pParentWnd = NULL,
  12.                UINT iSelectPage = 0 
  13.        ) ;
  14.        Parameter nIDCaption: ID of the resource string for the title.
  15.        Parameter pParentWnd: the parent window of the property page dialog box, if set to NULL , the parent window is the main window of the application.
  16.        Parameter iSelectPage: In the initial state, the index of the active property page, which defaults to the first property page added to the property sheet.
  17.        Parameter pszCaption: title string.
  18. ( 2 ) GetActiveIndex () function
  19.        Get the index of the currently active property page. The function prototype is:
  20.        int GetActiveIndex( ) const;
  21.        Return value: The index of the currently active property page.
  22. ( 3 ) GetActivePage () function
  23.        Gets the currently active property page object. The function prototype is:
  24.        CPropertyPage* GetActivePage( ) const;
  25.        Return value: pointer to the currently active property page object.
  26. ( 4 ) GetPage () function
  27.        Get a property page object. The function prototype is:
  28.        CPropertyPage* GetPage(int nPage) const;
  29.        Parameters nPage: The index of the target property page.
  30.        Return value: A pointer to the target property page object.
  31. ( 5 ) GetPageCount () function
  32.        Get the number of property pages. The function prototype is:
  33.         int GetPageCount( ) const;
  34.        Return value: the number of property pages.
  35. ( 6 ) GetPageIndex () function
  36.        Gets the index of a property page in the property page dialog box. The function prototype is:
  37.        int GetPageIndex(CPropertyPage* pPage);
  38.        Parameter pPage: The pointer of the property page object to get the index.
  39.        Return value: The index of the property page object in the property page dialog box.
  40. ( 7 ) SetActivePage () function
  41.        Sets a property page as the active property page. The function prototype is:   
  42.         BOOL SetActivePage(
  43.                  int nPage 
  44.        );
  45.         BOOL SetActivePage(
  46.                  CPropertyPage* pPage 
  47.        ) ;
  48.        Parameters nPage: The index to be set as the active property page.
  49.        Parameters pPage: the object pointer to be set as the active property page.
  50. ( 8 ) SetWizardButtons () function
  51.        To enable or disable the Back, Next or Finish buttons on a wizard dialog, this function should be called before calling DoModal.
  52. The function prototype is:
  53.         void SetWizardButtons(
  54.                 DWORD dwFlags 
  55.        );
  56.        Parameter dwFlags: Set the appearance and function attributes of the wizard button. Can be a combination of the following values:
  57.        PSWIZB_BACK Enables the "Back" button, or disables the "Back" button if this value is not included.
  58.        PSWIZB_NEXT Enables the "Next" button, or disables the "Next" button if this value is not included.
  59.        PSWIZB_FINISH Enables the "Finish" button.
  60.        PSWIZB_DISABLEDFINISH Displays a disabled "Finish" button.
  61. ( 9 ) SetWizardMode () function
  62.        Sets the property page dialog as a wizard dialog, and this function should be called before calling DoModal. The function prototype is:
  63.         void SetWizardMode( );
  64. ( 10 ) SetTitle () function
  65.        Sets the title of the properties dialog. The function prototype is:
  66.         void SetTitle(
  67.                LPCTSTR lpszText,
  68.                UINT nStyle = 0 
  69.        );
  70.        Parameter lpszText: title string.
  71.        Parameter nStyle: Specifies the style of the attribute table title. Should be 0 or PSH_PROPTITLE.
  72. If set to PSH_PROPTITLE, the word "Properties" will appear after the specified title.
  73. For example, a call to SetTitle ( "Simple" ,PSH_PROPTITLE) would cause the property sheet title to be "Simple Properties".
  74. ( 11 ) AddPage () function
  75.        Added a new property page for the properties dialog. The function prototype is:
  76.         void AddPage(
  77.                CPropertyPage *pPage 
  78.        ) ;
  79.        Parameter pPage: the object pointer of the new property page to be added.
  80. ( 12 ) PressButton () function
  81.        Simulates pressing a specified button. The function prototype is:   
  82.         void PressButton(
  83.                int nButton 
  84.        );
  85.        Parameter nButton: The button to simulate being pressed, it can be one of the following values:
  86.        PSBTN_BACK Select the "Back" button. 
  87.        PSBTN_NEXT Select the "Next" button.
  88.        PSBTN_FINISH Select the "Finish" button.
  89.        PSBTN_OK Select the "OK" button.
  90.        PSBTN_APPLYNOW Select the Apply button.
  91.        PSBTN_CANCEL Select the "Cancel" button.
  92.        PSBTN_HELP Select the Help button.
  93. ( 13 ) RemovePage () function
  94.        Delete a property page. The function prototype is:
  95.        void RemovePage(
  96.                CPropertyPage *pPage 
  97.        ) ;
  98.         void RemovePage(
  99.                int nPage 
  100.        );
  101.        Parameter pPage: the object pointer of the property page to be deleted.
  102.        Parameters nPage: The index of the property page to be deleted.

       The property dialog box and related two types of chicken pecking rice are introduced here first, mainly to prepare for the use of the property page dialog box later.

 

 

Create wizard dialog

 

       Still based on the previous "addition calculator" example, adding a wizard dialog box, we can use it to explain how to use the addition calculator and guide the user step by step, which is also a relatively common usage.

       When using the addition calculator, it can be roughly divided into three steps: input the summand, input the addend, and click the "calculate" button.

       Chicken pecking rice will detail the creation steps of the wizard dialog box:

 

1. Create a property page dialog resource

       According to the method described in Creating a Dialog Template and Modifying Dialog Properties, right-click on the Dialog node of "Resource View", and then select "Insert Dialog" in the right-click menu to create the first dialog template, the ID of the dialog The attribute is set to IDD_SUMMAND_PAGE, the Caption attribute is changed to "summand page", the Style attribute is selected as "Child" in the drop-down list, and the Border attribute is selected as "Thin" in the drop-down list.

       Delete the "OK" and "Cancel" buttons, and then add a static text box according to the method described in Adding Controls to the Dialog Box , and modify the Caption property of the static text box to "Please enter the double summand first".

       Proceed to add the second and third dialog resources, following the steps above. The ID of the second dialog template is set to IDD_ADDEND_PAGE, and the Caption property is changed to "Addend Page", and a static text box is also added, and the Caption is set to "Please continue to enter double type addend", and other properties are the same as the first dialog box . The ID of the third dialog template is set to IDD_ADD_PAGE, the Caption property is changed to "Calculation Page", the Caption property of the added static text box is changed to "Finally, please press the "Calculate" button", and other properties are the same as the first dialog box .

 

2. Create a property page class

       According to the method in creating a dialog class and adding control variables , right-click on the first dialog template, select "Add Class" in the right-click menu, and the class wizard dialog box will pop up, enter the class in the "Class name" edit box The name "CSummandPage" is different from before, because the property page class should inherit from the CPropertyPage class, so to modify the "Base class" option below, select "CPropertyPage" in the drop-down list.

       Since it is the first property page, it should have a "Next" button, where to add it? As mentioned in the previous lecture on the overloadable function of the CPropertyPage class , the OnSetActive function is used to process the message that the property page is switched to the current active page, so we can make related settings in the OnSetActive function.

       So how to overload the OnSetActive function? We can find the "CSummandPage" node in "Class View", right-click to pop up the right-click menu, select "Properties", and then the property list of the dialog box will be displayed on the right panel of VS2010. There is a tip information on the toolbar of the property list as "Overrides" button, press it, the overloaded functions are listed in the lower list, find "OnSetActive", click on the blank list item on the right and a down arrow will appear, then click the arrow and "<Add>" will appear below OnSetActive" option, select it will automatically add the function OnSetActive in the CSummandPage class.

   We only need to add relevant codes in the OnSetActive function body to achieve the effect of adding the "Next" button. The new function body is as follows:


  
  
   
   
  1. BOOL CSummandPage::OnSetActive()
  2. {
  3. // TODO: Add your specialized code here and/or call the base class
  4. // Get the parent window, that is, the property sheet CPropertySheet class
  5. CPropertySheet* psheet = (CPropertySheet*) GetParent();
  6. // Set the property sheet to only have the "Next" button
  7. psheet-> SetWizardButtons(PSWIZB_NEXT);
  8. return CPropertyPage:: OnSetActive();
  9. }

       Also add property page classes CAddendPage and CAddPage for the second and third dialog boxes, respectively. But the property page of the second dialog box does not need to override the OnSetActive function. The third dialog box is the last dialog box, so the "Next" button is not needed, but should be replaced with the "Finish" button, so it is also necessary to overload the OnSetActive function to set the "Finish" button. The overloaded OnSetActive is as follows:


  
  
   
   
  1. BOOL CAddPage::OnSetActive()
  2. {
  3. // TODO: Add your specialized code here and/or call the base class
  4. // Get the parent window, that is, the property sheet CPropertySheet class
  5. CPropertySheet* psheet = (CPropertySheet*) GetParent();
  6. // Set the attribute table to only have the "Done" button
  7. psheet-> SetFinishText(_T( "完成"));
  8. return CPropertyPage::OnSetActive();
  9. }

       In the above code segment, a _T is added before the string "Complete", this is because the default Unicode character set was used when the project was created, and if _T is not added before "Complete", it is an ASCII string. _T is actually a macro. When the character set of the project is selected as Unicode, the string is converted to a Unicode string, and when Muli-Byte is selected, it is converted to an ASCII string. We can right-click on the Addition root node of Solution Explorer, select "Properties" on the right-click menu, and the project properties dialog box will pop up. The Character Set in the list on the right side of Configuration Properties->General will display the selected character set.

       Then click the "Finish" button on the third property page. If we want to perform some processing, we will overload the OnWizardFinish function, the method is the same as the OnSetActive function. The overloaded OnWizardFinish function is as follows:


  
  
   
   
  1. BOOL CAddPage::OnWizardFinish()
  2. {
  3. // TODO: Add your specialized code here and/or call the base class
  4. // Prompt that the wizard is complete
  5. MessageBox (_T( "The instruction guide has been read!" ));
  6. return CPropertyPage:: OnWizardFinish();
  7. }

 

3. Create a property sheet class

       After the property page resources and property page classes are created, the wizard dialog box cannot be generated. We also need a property sheet class to accommodate these property pages.

       Right-click the root node "Addition" in the Solution Explorer view, select Add->Class in the right-click menu, and the "Add Class" dialog box will pop up, then select "MFC Class" in the middle area, and click the "Add" button, Another class wizard dialog box pops up, set the Class name to CAddSheet, select "CPropertySheet" as the Base class, and click the "Finish" button, so that the property sheet class is built.

       Next, include the header files for the three property sheet classes in the newly generated AddSheet.h:

       #include "SummandPage.h"
       #include "AddendPage.h"
       #include "AddPage.h"

       Then add private variables in AddSheet.h:

       CSummandPage    m_summandPage;C
       CAddendPage     m_addendPage;
       CAddPage        m_addPage;

       Then modify the two constructors of CAddSheet in the AddSheet.cpp file as:


  
  
   
   
  1. CAddSheet:: CAddSheet( UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
  2. :CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
  3. {
  4. // Add three property pages to the property sheet
  5. AddPage(&m_summandPage);
  6. AddPage(&m_addendPage);
  7. AddPage(&m_addPage);
  8. }
  9. CAddSheet:: CAddSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
  10. :CPropertySheet(pszCaption, pParentWnd, iSelectPage)
  11. {
  12. // Add three property pages to the property sheet
  13. AddPage(&m_summandPage);
  14. AddPage(&m_addendPage);
  15. AddPage(&m_addPage);
  16. }

 

4. Show wizard dialog

        We add a button to the addition calculator dialog, click it to open the wizard dialog. The ID of this button is set to IDC_INSTRUCT_BUTTON, and the Caption property is set to "Instructions".

        According to the method described in Adding a message processing function for a control , add a click message processing function OnBnClickedInstructButton in the CAdditionDlg class for the IDC_INSTRUCT_BUTTON button. Then include the header file of CAddSheet in the AdditionDlg.cpp file: #include "AddSheet.h". Finally modify the OnBnClickedInstructButton function as follows:


  
  
   
   
  1. void CAdditionDlg::OnBnClickedInstructButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. // create attribute table object
  5. CAddSheet sheet(_T(""));
  6. // Set the property dialog as a wizard dialog
  7. sheet. SetWizardMode();
  8. // Open the modal wizard dialog
  9. sheet. DoModal();
  10. }

At this point, the wizard dialog box is completely created, and can be displayed by clicking the "Instructions" button on the addition calculator dialog box. Let's see the effect:

       The picture above is just the effect of the added page, click the "Next" button on it to continue to display the next two pages.

       Are the wizard dialog boxes less complex than previously thought? You can use your imagination to make more complex modifications and achieve more perfect functions. Friends are still welcome to the chicken pecking rice blog to exchange and learn.

 

 

Creation and display of property page dialog boxes

 

Property page dialogs include wizard dialogs and general property page dialogs. The previous section described how to create and display wizard dialogs . This section will continue to introduce the creation and display of general property page dialogs.

       In fact, the process of creating and displaying general property page dialog boxes is very similar to that of wizard dialog boxes. Chicken Peck Rice slightly modifies the wizard dialog in the previous section to make it a general property page dialog.

       The creation steps of the general property page dialog box:

       1. Create a property page dialog resource

       The creation method of the property page dialog resource is the same as that of the wizard dialog, and the dialog resource in the previous lecture does not need any modification.

       2. Create a property page class

       The creation of the property page class is basically the same as the property page class of the wizard dialog box, except that buttons such as "Next" and "Finish" are not needed in the general property page dialog box, so the OnSetActive and OnWizardFinish of the property page class in the previous lecture Overloaded functions can be removed. That is, the OnSetActive function in the CSummandPage class, the OnSetActive function and the OnWizardFinish function in the CAddPage class can be deleted or commented out. Other parts do not need any modification.

       3. Create a property sheet class

       The process of creating the property sheet class is the same as that of the wizard dialog box property sheet class, so the CAddSheet class in the previous lecture does not need to be modified.

       4. Display the General Property Pages dialog

       The display of the wizard dialog box in the previous lecture is implemented in the OnBnClickedInstructButton function. The statement sheet.SetWizardMode(); aims to set the property sheet as the wizard dialog mode, so it is not necessary to call the SetWizardMode member function when displaying the general property page dialog box. In addition, we can set the title of the property page dialog box as "Instructions", and pass this string as a parameter of the constructor when constructing the property sheet object . The OnBnClickedInstructButton function is modified as follows:


  
  
   
   
  1. void CAdditionDlg::OnBnClickedInstructButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. // create attribute table object
  5. CAddSheet sheet (_T( "Instructions" )) ;
  6. // Open the modal general property page dialog
  7. sheet. DoModal();
  8. }

In this way, the creation and display of the general property page dialog box is finished. Let's run the program and click the "Instructions" button on the resulting dialog box to see the effect:

Introduction to VS2010/MFC Programming Fifteen (Dialog Box: Creation and Display of General Property Page Dialog Box)

    To sum up, the difference between the creation and display of the general property page dialog box and the wizard dialog box includes: whether to need overloaded functions such as OnSetActive and OnWizardFinish, and whether to call the SetWizardMode function of the property sheet class to set it as the wizard dialog box mode.

 

 

message dialog

 

In the previous sections, the chicken pecking rice talked about the property page dialog box , and we can easily create our own property page dialog box according to the content. This section explains the most commonly used and simplest type of dialog box in the Windows system—the message dialog box.

       We often see message dialog boxes in the process of using the Windows system, prompting us that there is an exception or asking questions. Because message dialog boxes are often used in software development, MFC provides two functions that can directly generate a message dialog box of a specified style, without the need for us to create dialog resources and generate dialog boxes every time we use it. class etc. These two functions are the member function MessageBox() of the CWnd class and the global function AfxMessageBox().

 

1.   Usage of CWnd::MessageBox() function and AfxMessageBox() function

       The following chicken pecking rice will explain the usage of the two functions respectively.

       1. CWnd::MessageBox() function

       The function prototype of CWnd::MessageBox() is as follows:     


  
  
   
   
  1.   int MessageBox(
  2.            LPCTSTR lpszText,
  3.            LPCTSTR lpszCaption = NULL,
  4.             UINT nType = MB_OK
  5.        );
  6.        Parameter Description:
  7.        lpszText: The message string to be displayed.
  8.        lpszCaption: The title string of the message dialog. The default value is NULL . Use the default title when the value is NULL .
  9.        nType: The style and properties of the message dialog. The default is the MB_OK style, that is, only the "OK" button.
  10.        The value of nType can be either one of the values ​​in the following two tables, or any combination of one value for each.
  11. That is, you can specify a dialog box type, a dialog icon, or both.

The value of nType can be either one of the values ​​in the following two tables, or any combination of one value for each. That is, you can specify a dialog box type, a dialog icon, or both. The following table is  the dialog box type table

nType value Parameter Description
MB_ABORTRETRY Has "Abort", "Retry" and "Ignore" buttons
MB_OK Has an "OK" button
MB_OKCANCEL Has "OK" and "Cancel" buttons
MB_RETRYCANCEL Has "Retry" and "Cancel" buttons
MB_YESNO Has "Yes" and "No" buttons
MB_YESNOCANCEL Has "Yes", "No" and "Cancel" buttons

The following table is   the dialog box icon table

nType value show icon
MB_ICONEXCLAMTION
MB_ICONWARNING
Introduction to VS2010/MFC Programming Sixteen (Dialog Box: Message Dialog Box)
MB_ICONASTERISK
MB_ICONINFORMATION
Introduction to VS2010/MFC Programming Sixteen (Dialog Box: Message Dialog Box)
MB_ICONQUESTION Introduction to VS2010/MFC Programming Sixteen (Dialog Box: Message Dialog Box)
MB_ICONHAND
MB_ICONSTOP
MB_ICONERROR
Introduction to VS2010/MFC Programming Sixteen (Dialog Box: Message Dialog Box)

       If you want to set the value of nType to be a combination of type and icon, you can take the value like this: MB_OKCANCEL | MB_ICONQUESTION. Bitwise OR is fine.

 

       2. AfxMessageBox() function

       The function prototype of AfxMessageBox() is:


  
  
   
   
  1.        int AfxMessageBox(
  2.            LPCTSTR lpszText,
  3.            UINT nType = MB_OK,
  4.            UINT nIDHelp = 0
  5.        );
  6.        Parameter Description:
  7.        lpszText: Same as CWnd:: MessageBox () function
  8.        nType: CWnd:: MessageBox () function
  9.        nIDHelp: The context ID of the help for this message. The default value is 0 , and when it is 0 , it means to use the default help context of the application.

 

2.  The return value of CWnd::MessageBox() and AfxMessageBox()

      After we call the above two functions, we can pop up a modal message dialog box. After the message dialog is closed, we can also get their return values. The return value of both is the ID of the button clicked by the user on the message dialog box, which can be the following values:

      IDABORT: Click the Terminate button.
      IDCANCEL: Click the Cancel button.
      IDIGNORE: Click the Ignore button.
      IDNO: Click the "No" button.
      IDOK: Click the OK button.
      IDRETRY: Click the Retry button.
      IDYES: Click the "Yes" button.

 

3.  Application examples

     Let's still take the previous addition calculator program as an example.

       Do you remember that we modified the CAdditionDlg::OnBnClickedAddButton() function during the modal dialog box and its pop-up process . After clicking the "Calculate" button, a modal dialog box popped up first, asking the user if they are sure to perform the addition calculation , and judge whether the user has selected "OK" or "Cancel" through the return value of the DoModal function of the modal dialog box. These functions are obviously fully realized by the message dialog box, and Chicken Peck Rice uses the message dialog box to replace the original modal dialog box.

       In the creation and display of the non-modal dialog box , Jipemi commented the relevant code of the modal dialog box, and added the creation and display code of the non-modal dialog box. Before adding the message dialog box, we added the non-modal dialog box The code of the box is also commented or deleted to ensure that the original modal dialog box or non-modal dialog box is no longer generated in this function.

       The modified CAdditionDlg::OnBnClickedAddButton() function is as follows:


  
  
   
   
  1. void CAdditionDlg::OnBnClickedAddButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. INT_PTR nRes;
  5. // show message dialog
  6. nRes = MessageBox (_T( "Are you sure you want to perform addition calculation?" ), _T( "Addition calculator" ), MB_OKCANCEL | MB_ICONQUESTION);
  7. // Determine the return value of the message dialog box. If it is IDCANCEL, return, otherwise continue to execute downward
  8. if (IDCANCEL == nRes)
  9. return;
  10. // Save the data in each control to the corresponding variable
  11. UpdateData(TRUE);
  12. // Assign the sum of the summand and the addend to m_editSum
  13. m_editSum = m_editSummand + m_editAddend;
  14. // Update the corresponding control according to the value of each variable. and the edit box will display the value of m_editSum
  15. UpdateData(FALSE);
  16. // Set the property dialog as a wizard dialog
  17. //sheet.SetWizardMode();
  18. }

Compile and run, and click the "Calculate" button on the running result dialog box to pop up the following message dialog box:

You can also replace the MessageBox function with the AfxMessageBox() function, and modify the parameters accordingly, and run it to see the effect.

 

 

file dialog

 

      Classification of file dialogs

      文件对话框分为 打开文件对话框保存文件对话框,相信大家在Windows系统中经常见到这两种文件对话框。例如,很多编辑软件像记事本等都有“打开”选项,选择“打开”后会弹出一个对话框,让我们选择要打开文件的路径,这个对话框就是打开文件对话框;除了“打开”选项一般还会有“另存为”选项,选择“另存为”后往往也会有一个对话框弹出,让我们选择保存路径,这就是保存文件对话框。

       正如上面举例说明的,打开文件对话框用于选择要打开的文件的路径,保存文件对话框用来选择要保存的文件的路径。

 

       文件对话框类CFileDialog

      MFC使用文件对话框类CFileDialog封装了对文件对话框的操作。CFileDialog类的构造函数原型如下:


  
  
   
   
  1. explicit CFileDialog(
  2.    BOOL bOpenFileDialog,
  3.    LPCTSTR lpszDefExt = NULL,
  4.    LPCTSTR lpszFileName = NULL,
  5.    DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
  6.    LPCTSTR lpszFilter = NULL,
  7.    CWnd* pParentWnd = NULL,
  8.    DWORD dwSize = 0,
  9.    BOOL bVistaStyle = TRUE
  10. );

       Parameter Description:

       bOpenFileDialog: Specifies the type of file dialog to create. Set to TRUE to create an open file dialog, otherwise a save file dialog will be created.

       lpszDefExt: The default file extension. If the user does not enter an extension in the file name edit box, the extension specified by lpszDefExt will be automatically added to the file name. The default is NULL.

       lpszFileName: The initial file name displayed in the file name edit box. If NULL, no initial filename is displayed.

       dwFlags: The attribute of the file dialog box, which can be a value or a combination of multiple values. Regarding the definition of attribute values, you can find the structure OPENFILENAME in MSDN, and the description of the element Flags contains all attribute values. The default is the combination of OFN_HIDEREADONLY and OFN_OVERWRITEPROMPT. OFN_HIDEREADONLY means to hide the "Read Only" checkbox on the file dialog box. OFN_OVERWRITEPROMPT means that if the file you selected exists in the save file dialog box, a message dialog box will pop up asking whether to confirm to overwrite this file.

       lpszFilter: file filter, which is a string sequence composed of several string pairs. If a file filter is specified, only files that meet the filter criteria will be displayed in the file list to be selected in the file dialog box. Let me show you an example given in VS2010 MSDN:

       static TCHAR BASED_CODE szFilter[] = _T("Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||");

       After setting the filter in this way, there will be four options in the extension combo box of the file dialog box: Chart Files (*.xlc), Worksheet Files (*.xls), Data Files(*.xlc;*.xls) and All Files (*.*), you can see that the extension of each file is a pair of strings. For example, the filter string of Chart Files is a pair of Chart Files (*.xlc) and *.xlc.

       pParentWnd: The pointer to the parent window of the file dialog.

       dwSize: The size of the OPENFILENAME structure. Different operating systems correspond to different dwSize values. MFC uses this parameter to determine the appropriate type of file dialog (for example, whether to create a Windows 2000 file dialog or an XP file dialog). The default is 0, which means that MFC will decide which file dialog box to use according to the version of the operating system the program is running on.

       bVistaStyle: Specify the style of the file dialog box, set to TRUE to use the Vista-style file dialog box, otherwise use the old version of the file dialog box. This parameter only applies when compiling in Windows Vista.

       The file dialog box is also a modal dialog box, so the DoModal() member function of the CFileDialog class needs to be called when it is opened. After clicking "Open" in the open file dialog box or clicking "Save" in the save file dialog box, we can use the member function GetPathName() of the CFileDialog class to obtain the selected file path.

       Listed below are several member functions of the CFileDialog class, we can use them to obtain various options in the file dialog.

GetFileExt(): Get the extension of the selected file.
GetFileName(): Get the name of the selected file, including the extension.
GetFileTitle(): Get the title of the selected file, that is, the suffix is ​​not included.
GetFolderPath(): Get the directory of the selected file.
GetNextPathName(): Get the full path name of the next selected file.
GetPathName(): Get the full path name of the selected file.
GetReadOnlyPref(): Get whether to "open in read-only mode".
GetStartPosition(): Get the position of the first element in the filename list.

 

       file dialog instance

      According to the content mentioned above, Chicken Peck Rice will give you an example of a file dialog box.

       1. Create a dialog-based MFC application project, and set the name to "Example17".

       2. Modify the template of the main dialog IDD_EXAMPLE17_DIALOG, delete the automatically generated "TODO: Place dialog controls here." static text box, add two edit boxes, IDs are IDC_OPEN_EDIT and IDC_SAVE_EDIT, and add two buttons, IDs are set to For IDC_OPEN_BUTTON and IDC_SAVE_BUTTON, Caption is set to "Open" and "Save" respectively. The button IDC_OPEN_BUTTON is used to display the open file dialog, and the edit box IDC_OPEN_EDIT displays the file path selected in the open file dialog. The button IDC_SAVE_BUTTON is used to display the save file dialog, and the edit box IDC_SAVE_BUTTON displays the file path selected in the save file dialog.

       3. Add click message processing functions CExample17Dlg::OnBnClickedOpenButton() and CExample17Dlg::OnBnClickedSaveButton() for buttons IDC_OPEN_BUTTON and IDC_SAVE_BUTTON respectively.

       4. Modify the two message processing functions as follows:


  
  
   
   
  1. void CExample17Dlg::OnBnClickedOpenButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. // set filter
  5. TCHAR szFilter[] = _T( "Text files (*.txt)|*.txt|all files (*.*)|*.*||" );
  6. // construct open file dialog
  7. CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, szFilter, this);
  8. CString strFilePath;
  9. // show open file dialog
  10. if (IDOK == fileDlg. DoModal ())
  11. {
  12. // If the "Open" button on the file dialog is clicked, the selected file path will be displayed in the edit box
  13. strFilePath = fileDlg. GetPathName();
  14. SetDlgItemText(IDC_OPEN_EDIT, strFilePath);
  15. }
  16. }
  17. void CExample17Dlg::OnBnClickedSaveButton()
  18. {
  19. // TODO: Add your control notification handler code here
  20. // set filter
  21. TCHAR szFilter[] = _T( "Text files (*.txt)|*.txt|Word files (*.doc)|*.doc|all files (*.*)|*.*||" ) ;
  22. // Construct the save file dialog
  23. CFileDialog fileDlg(FALSE, _T("doc"), _T("my"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this);
  24. CString strFilePath;
  25. // show save file dialog
  26. if (IDOK == fileDlg. DoModal ())
  27. {
  28. // If the "Save" button on the file dialog is clicked, the selected file path will be displayed in the edit box
  29. strFilePath = fileDlg. GetPathName();
  30. SetDlgItemText(IDC_SAVE_EDIT, strFilePath);
  31. }
  32. }

When displaying the content of the edit box above, Jipeimi uses the Windows API function SetDlgItemText. Of course, you can also associate variables with the edit box        first, and then use the CDialogEx
::UpdateData( ) function, but the chicken pecking rice is more accustomed to using the SetDlgItemText function, which feels more flexible.

       5. Run the program, click the "Open" button on the result dialog box, and the file open dialog box will be displayed as follows:

After clicking the "Save" button, the save file dialog box is displayed:

After selecting the file path in both the open file dialog and the save file dialog, the main dialog is as follows:

    At this point, the file dialog box is finished, is it still very simple? If you forget the meaning of the parameters of the constructor of the file dialog class, you can go back to the chicken pecking rice or look it up on MSDN.

 

 

font dialog

 

       The function of the font dialog box is to select a font. We also often see. MFC uses the CFontDialog class to encapsulate all operations of the font dialog box. The font dialog is also a modal dialog .

       Constructor of CFontDialog class

       Let's first understand the CFontDialog class. Its common constructor prototype is as follows:


  
  
   
   
  1. CFontDialog(
  2.    LPLOGFONT lplfInitial = NULL,
  3.    DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
  4.    CDC* pdcPrinter = NULL,
  5.    CWnd* pParentWnd = NULL
  6. );
  7.        Parameter Description:
  8.        lplfInitial: A pointer to the LOGFONT structure data, through which some characteristics of the font can be set.
  9.        dwFlags: Specifies one or more attributes of the selected font, details can be found in MSDN.
  10.        pdcPrinter: A pointer to a print device context.
  11.        pParentWnd: A pointer to the parent window of the font dialog.

       The first parameter in the above constructor is the LOGFONT pointer, and the LOGFONT structure contains most of the features of the font, including font height, width, direction, name, and so on. Here is the definition of this structure:


  
  
   
   
  1. type def struct tagLOGFONT {
  2.     LONG lfHeight;
  3.     LONG lfWidth;
  4.     LONG lfEscapement;
  5.     LONG lfOrientation;
  6.     LONG lfWeight;
  7.     BYTE lfItalic;
  8.     BYTE lfUnderline;
  9.     BYTE lfStrikeOut;
  10.     BYTE lfCharSet;
  11.     BYTE lfOutPrecision;
  12.     BYTE lfClipPrecision;
  13.     BYTE lfQuality;
  14.     BYTE lfPitchAndFamily;
  15.     TCHAR lfFaceName[LF_FACESIZE];
  16. } LOGFONT;

 

       Get the font selected in the font dialog

       After we select a font in the font dialog box, how to get the selected font? We can indirectly obtain the CFont object of the selected font through the member variable m_cf of the CFontDialog class. m_cf is a variable of CHOOSEFONT type, and the CHOOSEFONT structure is defined as follows:


  
  
   
   
  1. typedef struct {
  2.     DWORD lStructSize;
  3.     HWND hwndOwner;
  4.     HDC hDC;
  5.     LPLOGFONT lpLogFont;
  6.     INT iPointSize;
  7.     DWORD Flags;
  8.     COLORREF rgbColors;
  9.     LPARAM lCustData;
  10.     LPCFHOOKPROC lpfnHook;
  11.     LPCTSTR lpTemplateName;
  12.     HINSTANCE hInstance;
  13.     LPTSTR lpszStyle;
  14.     WORD nFontType;
  15.     INT nSizeMin;
  16.     INT nSizeMax;
  17. } CHOOSEFONT, *LPCHOOSEFONT;

       There is a member lpLogFont in the CHOOSEFON structure, which is a pointer to the variable of the LOGFONT structure. As mentioned above, LOGFONT contains font characteristics. For example, we can know the font name through LFFaceName of LOGFONT.

       What we finally want to get is the CFont object of the selected font. How to get the corresponding CFont object with the LOGFONT of the font? This can be achieved by using the member function CreateFontIndirect of the CFont class. The function prototype is as follows:

       BOOL CreateFontIndirect(const LOGFONT* lpLogFont );

       The parameter is a LOGFONT pointer type, we can pass in the lpLogFont member of the CFontDialog class member variable m_cf, and then we can get the CFont object of the selected font.

 

       Application example of font dialog box

       Chicken pecking rice will make an example of a font dialog box for everyone. First introduce the functions to be realized in this example, generate a dialog box, and place a "font selection" button and an edit box in the dialog box. Click the "Font Selection" button to pop up the font dialog box. The edit box is used to display the selected font name, and the font name string is displayed in the selected font, for example, if Arial is selected, the string "宋体" is displayed in Arial in the edit box.

       Here are the steps to create this instance:

       1. Create a dialog-based MFC project named "Example18".

       2. In the template of the automatically generated main dialog IDD_EXAMPLE18_DIALOG, delete the "TODO: Place dialog controls here." static text box, add a button, ID is set to IDC_FONT_BUTTON, Caption is set to "font selection", used to display the font dialog box to select the font, and then add an edit box with the ID set to IDC_FONT_EDIT to display the font name string in the selected font.

       3. Add a private member variable to the CExample18Dlg class in Example18Dlg.h: CFont m_font;, which is used to save the font selected in the edit box.

       4. Add the click message processing function CExample18Dlg::OnBnClickedFontButton() for the button IDC_FONT_BUTTON.

       5. Modify the message processing function CExample18Dlg::OnBnClickedFontButton() as follows:


  
  
   
   
  1. void CExample18Dlg::OnBnClickedFontButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. CString strFontName; // font name
  5. LOGFONT lf; // LOGFONT variable
  6. // Clear all bytes of lf to zero
  7. memset(&lf, 0, sizeof(LOGFONT));
  8. // Set the element font name in lf to "Arial"
  9. _tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T( "Arial" ));
  10. // Construct the font dialog box, the initial selection font name is "Song Ti"
  11. CFontDialog fontDlg(&lf);
  12. if (IDOK == fontDlg.DoModal ( )) // show font dialog
  13. {
  14. // If m_font has been associated with a font resource object, release it
  15. if (m_font.m_hObject)
  16. {
  17. m_font. DeleteObject();
  18. }
  19. // Create a new font using the LOGFONT of the selected font
  20. m_font. CreateFontIndirect(fontDlg.m_cf.lpLogFont);
  21. // Get the CWnd pointer of the edit box IDC_FONT_EDIT and set its font
  22. GetDlgItem(IDC_FONT_EDIT)-> SetFont(&m_font);
  23. // If the user selects the OK button of the font dialog box, get the name of the selected font and display it in the edit box
  24. strFontName = fontDlg.m_cf.lpLogFont->lfFaceName;
  25. SetDlgItemText(IDC_FONT_EDIT, strFontName);
  26. }
  27. }

       6. Finally, compile and run the program. Display the result dialog box, click the "Font Selection" button, a font dialog box will pop up, the default selection is "Song Ti", let's choose the font "Huawen Caiyun" and click "OK", the edit box will be displayed as follows:

       So far, we have learned how to use the font dialog box, which is very helpful for controlling the displayed font in interface development in the future. If you have any questions, please leave a message on Chicken Peck Rice.

 

 

color dialog

 

       Everyone is familiar with the color dialog box, we can open it to select the desired color, in short, its function is to select the color. The CColorDialog class provided in MFC encapsulates all the operations of the color dialog box, through which we can display the color dialog box and obtain the color selected in the color dialog box. Like the font dialog, the color dialog is also a modal dialog .

       Constructor of CColorDialog class

CColorDialog(
   COLORREF clrInit = 0,
   DWORD dwFlags = 0,
   CWnd* pParentWnd = NULL
);

       Parameter Description:

       clrInit: The color value of the selected color by default, the type is COLORREF, which is actually an unsigned long type. If its value is not set, it defaults to RGB(0,0,0), which is black.

       Note: RGB(r,g,b) is a macro that can calculate color values. The three values ​​in parentheses are the values ​​of red, green and blue components respectively.

       dwFlags: Attribute values ​​for customizing the functionality and appearance of the color dialog box. Details can be found in MSDN.

       pParentWnd: The pointer to the parent window of the color dialog.

       Get the color value selected in the color dialog

       Our ultimate goal of using the color dialog box is to obtain the color value selected in the color dialog box. For this reason, the member function GetColor() of the CColorDialog class can fulfill our requirements very well. The prototype of the GetColor() function is:

       COLORREF GetColor( ) const;

       It returns the COLORREF value of the selected color.

       What if we want to get the value of each component of R, G, and B? According to the COLORREF color value obtained by GetColor, it can be obtained by using the three macros GetRValue, GetGValue and GetBValue. The syntax of GetRValue is:

       BYTE GetRValue(DWORD rgb);

       The parameter rgb is the COLORREF color value, and the return value is the R component value. The other two macros have a similar form. For example, if the COLORREF returned by the GetColor() function is 10000, then the R component value is GetRValue(10000).

       Application example of color dialog box

       Here is a small example of a color dialog box for you. The functions to be realized in this example are briefly introduced: a dialog box is generated, and a "color selection" button, four static text boxes and four edit boxes are placed in the dialog box. The four static text boxes display Color:, R:, G:, and B: respectively, and each static text box is followed by an edit box, which is used to display the color value selected in the color dialog box and the red component of the selected color value , green component, and blue component.

       Here are the steps to create an instance:

       1. Create a dialog-based MFC project named "Example19".

       2. In the template of the automatically generated main dialog IDD_EXAMPLE19_DIALOG, delete the "TODO: Place dialog controls here." static text box, add a button, ID is set to IDC_COLOR_BUTTON, Caption is set to "color selection", used to display the color dialog box to select a color. Add four more static text boxes, IDs are IDC_COLOR_STATIC, IDC_R_STATIC, IDC_G_STATIC, IDC_B_STATIC, and Caption is set to "Color:", "R:", "G:", "B:", and then after each static text box Add an edit box. The IDs of the four edit boxes are IDC_COLOR_EDIT, IDC_R_EDIT, IDC_G_EDIT, and IDC_B_EDIT, which are used to display the color value selected in the color dialog box and the red component, green component, and blue component of the selected color value.

       3. Add a click message processing function CExample19Dlg::OnBnClickedColorButton() for the button IDC_COLOR_BUTTON.

       4. Modify the message processing function CExample19Dlg::OnBnClickedColorButton() as follows:


  
  
   
   
  1. void CExample19Dlg::OnBnClickedColorButton()
  2. {
  3. // TODO: Add your control notification handler code here
  4. COLORREF color = RGB ( 255 , 0 , 0 ); // The initial color of the color dialog is red
  5. CColorDialog colorDlg (color) ; // Construct a color dialog box and pass in the initial color value
  6. if (IDOK == colorDlg.DoModal ( )) // Display the color dialog box and determine whether "OK" is clicked
  7. {
  8. color = colorDlg.GetColor ( ); // Get the color value selected in the color dialog box
  9. SetDlgItemInt (IDC_COLOR_EDIT, color); // Display the selected color value in the Color edit box
  10. SetDlgItemInt (IDC_R_EDIT, GetRValue (color)); // Display the R component value of the selected color in the R edit box
  11. SetDlgItemInt (IDC_G_EDIT, GetGValue (color)); // Display the G component value of the selected color in the G edit box
  12. SetDlgItemInt (IDC_B_EDIT, GetBValue (color)); // Display the B component value of the selected color in the B edit box
  13. }
  14. }

       5. Finally, compile and run the program, click the "color selection" button in the result dialog box, and the color dialog box will pop up. In the initial state, the selection box is on red, and we choose another color. At this time, the color dialog box is as follows:

Click "OK", and the four edit boxes on the main dialog box respectively display the selected color value, R component, G component and B component:

 

 

 

Guess you like

Origin blog.csdn.net/XCJandLL/article/details/126109922