Second, the programming technology of the toolbar
1, command processing
To make the menu and toolbar execute a command, light is specified for the command ID, and the command processing function must be defined for each command ID. If you do not define a command process function or the command to be updated below, the framework will automatically disable (ashing) the menu item and button corresponding to the command.
Use ClassWizard in CMAINFRAME, join the OnRecordStart and the OnRecordStop message processing function.
Now insert the corresponding source code in these two command processing functions to implement its functions. We just let these two functions make a sound, symbolically represent the execution of the function, and the specific code is shown in Listing 4.2.
Listing 4.2 OnRecordStart and OnRecordStop functions
Void CMAINFRAME :: OnRecordStart ()
{
// Todo: add your command handler code here
MessageBeep ((UINT) (- 1));
}
Void cmainframe :: OnRecordStop ()
{
// Todo: add your command handler code here
MessageBeep ((UINT) (- 1));
}
2, command update
Although the start and stop commands can be implemented, there is still a shortcomings. The stop command should be disabled before the recording is not started, that is, the corresponding menu item and the button should be disabled because there is no need to execute the command at this time. After the recording begins, the stop command should allow, and the start command should be changed to disable. We can use the MFC command update mechanism to implement this logic.
Before the menu is dropped, or during the idle cycle during the toolbar button, the MFC will send an update command, which will cause the command to update the call of the process. Command Update Processing Functions can be allowed or disabled by user interface objects (main finger menu items and toolbar buttons) depending on the situation. The method of defining the command update processing function is as follows:
Press the CTRL W button to enter the classwizard.
Select CMAINFRAME in the Class Name column, select ID_record_start in the Object IDS bar, double-click the update_command_ui item in the Messages column, and ClassWizard will pop up a dialog box to ask the command to update the name of the handler, use the function name provided. After pressing the OK button, the function onupdateRecordStart is added to Member
In the Functions column.
Simulation step 2, define a command update process function for ID_record_stop.
Press the OK button to close the ClassWizard dialog. At this time, the reader will find that the CMAINFRAME class has two member functions, OnUpdateRecordStart, and OnUpdateRecordStop.
Command Update Processing Function There is a parameter that is a pointer to the CCMDUI class, by calling a member function enable (TRUE) or enable (false) of the CCMDUI class, allows the user interface object to be allowed or disabled. Need to add a Boolean member variable to CMAINFRAME to indicate whether it is recording, such a command update process function can determine the status of the user interface object according to this variable. Please read the following line of code within the CMAINFRAME class:
Bool m_bworking;
Next, please make a modification by Listing 4.3.
Listing 4.3 Command Update Processing
CMAINFRAME :: CMAINFRAME ()
{
// Todo: Add Member Initialization Code Here
m_bworking = false;
}
Void CMAINFRAME :: OnRecordStart ()
{
// Todo: add your command handler code here
MessageBeep ((UINT) (- 1));
M_bworking = true;
}
Void cmainframe :: OnRecordStop ()
{
// Todo: add your command handler code here
MessageBeep ((UINT) (- 1));
m_bworking = false;
}
Void CMAINFRAME :: OnUpdateRecordStart (ccmdui * pcmdui)
{
// Todo: Add your command Update Ui Handler Code Here
PCMDUI-> Enable (! m_bworking);
}
Void CMAINFRAME :: OnUpdateRecordStop (ccmdui * pcmdui)
{
// Todo: Add your command Update Ui Handler Code Here
pcmdui-> enable (m_bworking);
}
The initial value of m_bworking should be FALSE, which is done in the constructor of CMAINFRAME. M_bworking's value is updated when processing the start and stop commands to reflect the current state. Both command update processing functions call CCMDUI :: Enable, which updates the command interface object according to the value of m_bworking.
Compile and run the Record, the logical function of the start and stop commands is now implemented.
3, button style
In the Record program, the user can select two sampling frequencies to recording. The user interface object should reflect the current sampling frequency. Ordinary toolbar buttons will be played immediately after pressing, we hope that the frequency selection button of the Record program has the style of the radio button, that is, when the user selects a sampling frequency, the button corresponding to the sampling frequency is in the pressed. The state, and the other frequency selection button should be in a pop-up state.
We can use the ccmdui :: setCheck function to implement this feature, call CCMDUI: SetCheck (true) or ccmdui :: setCheck (false) in the command update function, you can set the user interface object to select or not select the status, When a user interface object is selected, the corresponding tool button will be in the state, and a selected marker will be added in front of the corresponding menu item. Here you need to add a Boolean member variable to the CMAINFRAME class to indicate the current sampling frequency. Please read the following line of code within the CMAINFRAME class: bool
m_bhighquality;
Next, please make a modification by Listing 4.4.
Listing 4.4
CMAINFRAME :: CMAINFRAME ()
{
m_bworking = false;
m_bhighquality = true;
}
Void CMAINFRAME :: onhquality ()
{
m_bhighquality = true;
}
Void CMAINFRAME :: Onlowquality ()
{
m_bhighquality = false;
}
Void CMAINFRAME :: OnUpdateHighquaLity (ccmdui * pcmdui)
{
PCMDUI-> SetCheck (m_bhighquality);
}
Void CMAINFRAME :: OnUpdatelowquality (ccmdui * pcmdui)
{
PCMDUI-> SetCheck (! m_bhighquaality);
}
The initial value of m_bhighquality is True, which is the default, high frequency sampling, which is completed in the constructor of CMAINFRAME. M_BhighQuality's value is handling high
The Quality and Low Quality command are updated to reflect the current state. Both command update processing functions call CCMDUI :: SetCheck, which updates the command interface object according to the value of M_BHighQuality, so that the toolbar button has a radio button. 4, hidden / display of the toolbar
The reader may have tried the functionality of the Record program's View menu. By this menu user can hide / display the toolbar and status bar, this function is automatically implemented by AppWizard. Since the second toolbar is hand-established, it does not automatically have hidden / display functions. But we can program the hidden / display of the second toolbar by programming:
Open IDR_MAINFRAME menu resource
Add a menu item called Toolbar1 in the View menu, specify its ID to ID_View_toolbar1, and enter Show or Hide the Toolbar1 / NToggle Toolbar1 in the Prompt column.
Press the CTRL W button to enter the classwizard. Select CMAINFRAME in the Class Name column, select ID_View_toolbar1 in the Object IDS bar, and define the command handler onViewToolbar1 and command update processing function on /updateviewToolbar1 for the command IDS bar.
Modify the program by Listing 4.5.
Listing 4.5 Display / Hide Toolbar
Void CMAINFRAME :: OnViewToolbar1 ()
{
M_Wndtoolbar1.showWindow (m_wndtoolbar1.iswindowvisible ()? SW_HIDE: SW_SHOW);
RECALCLAYOUT ();
}
Void CMAINFRAME :: OnUpdateViewToolbar1 (ccmdui * pcmdui)
{
PCMDUI-> SetCheck (m_wndtoolbar1.IswindowVisible ());
}
Call CWnd :: ShowWindow (sw_show) or CWnd :: ShowWindow (sw_hide) can display or hide the window. Due to the toolbar is also a window, CToolbar is the inheritance class of the CWND class, so the function is also a member of CToolbar. In the command handler onviewToolbar1, we call CToolbar :: ShowWindow to display the / hide the toolbar, use the CWnd :: IswindowVisible function to make a judgment when calling, if the toolbar is visible, pass the ShowWindow function sw_hide parameter to hide the tool Article, otherwise, pass the SW_SHOW parameter display toolbar. Then you want to call CMAINFRAME:: RecalCLayout to re-adjust the layout of the main frame window.
Command Update Processing Function OnupDateViewToolbar1 will be selected or not selected according to the toolbar.
Third, the design and implementation of the status bar
The status bar is actually a window, which is generally divided into several panes, each pane displaying different information. AppWizard automatically creates a status bar for the application, including several panes, used to display status bar hints and CAPS
The status of LOCK, NUM LOCK, SCROLL LOCK key. In the MFC, the functionality of the status bar is implemented by the CSTATUSBAR class. Creating a status bar requires the following steps:
Build a CSTATUSBAR object.
Call CSTATUSBAR :: CREATE Create a status bar window.
Call the CStatusBar :: Setindicators function assignment pane and connect each pane of the status bar with a string ID.
The corresponding code reader can find in the CMAINFRAME :: oncreate member function of the Record Engine.
Listing 4.6 Creating a status bar
...
IF (! m_wndstatusbar.create (this) ||
! m_wndstatusbar.setindicators (Indicators, SizeOf (Indicators) / SizeOf (UINT)) {
Trace0 ("Failed to Create Status Bar / N);
Return -1; // fail to create
}
...
The first parameter of the SETInDicators function is an ID array that can be found in the beginning of the CPP file in the CMAINFRAME class, as shown in Listing 4.7.
Listing 4.7 ID array
Static uint indeicators [] =
{
ID_separator, // status line indeicator
ID_indicator_caps,
ID_indicator_num,
ID_Indicator_scrl,
}
The Indicator array provides allocation information of the status bar pane. Its first item is generally id_separator. The corresponding pane is used to display the command prompt information. The last three items are string ID, readers can be in String Table strings Find these three strings in resources are CAP, NUM, and SCRL, respectively. The three panes they correspond to the status of the keyboard.
Now let's add a time pane to the status bar, which will be used to display the system time. The displayed format is HH: mm: SS, I'm, minutes: seconds.
First insert a ID called ID_indicator_clock after the ID_separator item of the Indicators array. Then find and double-click the string resource called String Table, open the string resource editing window. Then press the INSERT button in the edit window to insert a new string, specify the id_indicator_clock, the content is 00:00:00. The status bar will determine the default width of the corresponding pane based on the length of the string, so the time to be displayed for time to display the space.
Tip: The above method cannot dynamically change the width of the pane and sometimes inaccurate, which may cause some errors when the system font changes. Considering that this method is simple and intuitive, and in general, the problem is not large, so this article uses it.
The time of the time pane is displayed must be updated every other second. The text of the update time pane can call the cstatusbar :: setPaNetExt function, you should update it, you should use the WM_TIMER message. In Windows, users can install one or more timers, and the timer will automatically issue a WM_TIMER message every time interval, and this time interval can be specified by the user. The MFC's WINDOW class provides the WM_TIMER message processing function Ontimer, and we should perform the work of the update time pane within this function.
Readers Please use ClassWizard to join the CMAINFrame class to add WM_Timer's message processing function onTimer and WM_Close messages onClose. The CMAINFRAME :: OnClose function is to turn off the main frame window is called, and the program can do some clearance in this function. Next, please press Listing 4.8 to modify the program.
Listing 4.8 Partial code for CMAINFRAME class
INT CMAINFRAME :: OnCreate (lpcreatestruct lpcreatestruct)
{
...
SetTimer (1,1000, null);
Return 0;
}
Void CMAINFRAME :: ONTIMER (uint nidevent)
{
Ctime Time;
CframeWnd :: ONTIMER (Nidevent);
Time = CTIME :: getcurrenttime ();
CString s = time.format ("% h:% m:% s");
M_WndStatusBar.SetPanetext (m_wndstatusbar.commandtoIndex (id_indicator_clock), s); cframeWnd :: Ontimer (nidevent);
}
Void cmainframe :: onClose ()
{
Killtimer (1);
CframeWnd :: onClose ();
}
Call CWnd :: SetTimer in the CMAINFRAME :: oncreate function to install a timer, the first parameter of the setTimer specifies the timer ID to 1, the second parameter specifies the time interval of the timer to 1000 milliseconds, 1 second . In this way, the ONTIMER function will be called once every 1 second.
In the ONTIMER function, first build a CTIME object, then call the CTIME's static member function getCurrentTime to get the current system time, then use the CTIME :: Format function to return a time: String in the format, final call CSTATUSBAR :: SetPaNetext To update the text of the time pane displayed. The first parameter of SetPaneText is the index of the pane. For a pane ID, CSTATUSBAR :: CommMandToIndex can be called to get the index.
When the main frame window is revoked, the timer should be turned off, so the KillTimer function is called in the CMAINFRAME:: ONCLOSE function.
Let us now look at the message map of CMAINFRAME, and the message mapping of the class can be found in the start section of the CMAINFRAME class, as shown in Listing 4.9.
Listing 4.9
Begin_MESSAGE_MAP (CMAINFRAME, CFRAMEWND)
// {{AFX_MSG_MAP (CMAINFRAME)
ON_WM_CREATE ()
ON_COMMAND (ID_Record_Stop, OnRecordStop)
ON_COMMAND (ID_Record_Start, OnRecordStart)
ON_UPDATE_COMMAND_UI (id_record_start, onupdaterecordstart)
ON_UPDATE_COMMAND_UI (id_record_stop, onupdaterecordstop)
ON_COMMAND (ID_High_quality, Onhlightity)
ON_COMMAND (ID_LOW_QUALI, ONLOWQUALITY)
ON_UPDATE_COMMAND_UI (ID_High_Quality, OnupdateHigh Quality)
ON_UPDATE_COMMAND_UI (ID_LOW_QUAL, ONUPDATELOWQUALITY)
ON_COMMAND (ID_View_toolbar1, onviewtoolbar1)
ON_UPDATE_COMMAND_UI (id_view_toolbar1, onupdateviewToolbar1)
ON_WM_TIMER ()
ON_WM_CLOSE ()
//}} AFX_MSG_MAP
END_MESSAGE_MAP ()
Readers can see that in the message mapping table, classwizard automatically adds message mapping for message processing functions and command processing functions. The automatically added portion is displayed in gray, located between the notes // {{AFX_MSG_MAP and //}} AFX_MSG_MAP. The command processing function is mapping by an on_command macro, and the command update process is mapped by ON_UPDATE_COMMAND_UI, and the processing function of the WM_ message is mapped by the ON_WM_ message macro.
Tip: As long as you see // {{AFX_..., you will explain that the part there is ClassWizard automatically added, this part is grayed. Don't modify them casually, you can't put the part of the hand-added portion // {AFX _... Note Pair, otherwise it is possible to cause the ClassWizard error. Fourth, small knot
This chapter mainly introduces some practical technologies in the toolbar and status bar to readers. The points are as follows:
In the MFC, create a window is generally two steps:
1. Build a window object. The constructed method is to define an object or dynamically created with the New operator.
2. Call the CREATE member function of the window class. This function works out the actual window and saves its HWND in the public data member m_hwnd of the window.
Creating a toolbar and status bar is done in the cmainframe :: oncreate function, the oncreate function is called when the window is created, when the creation of the window is partially completed, the HWND handle of the window object is also valid, but the window Still don't visible. It is therefore generally in an oncreate function to make initialization work such as a creative sub-window.
The AFX_MSG prefix ensures that the correct version of the message processing function is called.
There are two elements of the toolbar: toolbar resources and tools CToolbar. If a user only needs one toolbar, you can use AppWizard to automatically generate, and then modify it. If multiple toolbars are needed, you must be created manually.
If you do not define a command to process a function or a command update process function, the framework will automatically disable the user interface object (main finger menu item and button) corresponding to the command. Use ClassWizard that can easily add command processing functions and command update processing functions.
Before the menu is dropped, or during the idle cycle during the toolbar button, the MFC will send an update command, which will cause the command to update the call of the process. Command Update Processing Function Using the CCMDUI class to update the user interface object. Calling CCMDUI :: Enable enables user interface objects to allow or disable, calling CCMDUI: SetCheck to make user interface objects or not. Call CWnd :: ShowWindWind You can hide / display a window.
To insert a new pane in the status bar, you need to insert a new string ID in an Indicator array. The status bar will determine the default width of the new pane according to the length of this string.
Call CSTATUSBAR :: SetPaNetExt Update the body of the status bar window.
Dialog
The dialog is a user interface, its main function is to output information and the user's input. The dialog box and control are unsualed. In each of the dialogs, there are some controls, and the dialog interacts with the user on these controls. A typical dialog box example is the file dialog box that is ejected after the file-open command.
I. Basic concept of dialog box and control
1. Basic concept of dialog
The dialog (Dialog) is actually a window. In the MFC, the function of the dialog is encapsulated in the CDIALOG class, and the CDIALOG class is a derived class for the CWND class.
The dialog is divided into two types of modal dialogs and non-modular dialogs. The modal dialog monopolizes the user's input. When a modal dialog is turned on, the user can only interact with the dialog, while other user interfaces do not receive input information. The typical example of the non-modular dialog is the search dialog box provided by Windows95, and the search dialog does not monopolize the user's input. After opening the search dialog, you can still interact with other user interfaces, the user can search while searching While modifying articles, this is great to be used.
From the perspective of the MFC programming, a dialog is composed of two parts:
Dialog Template Resources: Dialog Template For the specified controls and distributions thereof, Windows creates and displays dialogs based on dialog templates.
Dialog Box Class: Dialog Box Class For the function of implementing the dialog, since the function of the dialog is different, therefore generally needs a new class from the CDIALOG class to complete specific features. Accordingly, the design of the dialog includes two main aspects of the design and dialog box class of dialog templates.
The message related to the dialog mainly includes the WM_INITDIALOG message and control notification message. When the dialog is created, the WM_INITDIALOG message is received, and the dialog is the handler of the message is OnInitdialog.
OnInitDialog's main use is the initialization dialog. The control of the dialog box sends a control notification message to the dialog to indicate that the status of the control changes.
2, the basic concept of the control
Figure 5.1 Controls in the dialog
Control (Control) is a separate widget that controls the main role during the dialog and the user's interaction. There are many types of controls, and Figure 5.1 shows some basic controls in the dialog. The MFC control class encapsulates the functionality of the control. The following table describes some commonly used controls and their corresponding control classes.
Control function correspondence
Static Text Displays the body, generally cannot accept the input information. CSTATIC
Picture (Picture) explicit bitmap, icon, box, and element files, generally unacceptable input information. CSTATIC
Edit box (Edit Box) input and edit your text, support a single line and multi-line editing. Cedit
The command button (PushButton) responds to the user's input, triggers the corresponding event. CButton
Check Box is used as a selection tag that can be selected, unchecked, and unsure three states. CButton
The radio button is used to select one of two or more options. CButton
Group box (Group Box) displays the body and box, mainly used to polyglysented some controls. CButton
List box (list box) displays a list, users can select one or more from this list. Clistbox
The Combination Box is a combination of an edit box and a list box. Divided into simple, drop-down and drop-down list. CCOMBOBOX
Scroll Bar is mainly used to select an integer value from a predefined range value. Cscrollbar
The control is actually a window, and all control classes are derived classes for the CWND class. The control is usually created as a sub-window of the dialog, and the control can also appear in the view window, the toolbar, and status bar.
Second, dialog box template design
Using the visual design tool provided by Developer Studio, users can easily design dialog templates.
Readers Please use AppWizard to create an MFC application named Register as described in the following chapter, and follow the steps below after entering the MFC AppWizard dialog:
1. Select Single Document in step 1 to create a single document application.
2. In step 4, the Docking Toolbar item is not selected so that AppWizard will not create a toolbar.
3. Select CREGISTERVIEW in step 6, then select CEDITVIEW in the Base Class bar, so that CregisterView will be the inheritance class of CEDITVIEW, so that the view has editing functions.
Compile and run register, the reader will find that register is actually a editor, it can open, edit, and save text files. Of course, the purpose of Register is not only an editor. Suppose you want to investigate a certain area, we hope that the Register program can log in to employment data and store data.
To log in to the data, it is appropriate to use the dialog box. A typical employment login dialog box is shown in Figure 5.1, the task of this section is to design a Chinese dialog template as shown in Figure 5.1. Switch to the resource view, select the insert-resource command, and double-click the Dialog item in the Insert Resource dialog. A new dialog template resource called IDD_DIALOG1 will appear after completion of the resource view. Double-click IDD_DIALOG1, the editing window of the dialog template will open. The default dialog template has OK and Cancel two buttons, there is a control panel next to the window, select a control with the mouse on the control panel, then click in the dialog, the corresponding control is placed to the dialog Template.
After selecting the control or dialog, press Enter, then a property dialog box is popped, the Properties dialog is used to set various properties of the control or dialog. The Properties dialog is the tab dialog, and the first page is General attributes.
In the regular properties of the Control Properties dialog, there are some controls common attributes:
ID attribute. Used to specify the identifier of the control, Windows relies on the ID to distinguish between different controls.
CAPTION attribute. Static body, group box, button, check box, radio button and other controls can display titles for text descriptions for controls. Characters in the control header & make the characters after the following lines, press the ALT Underline, will start the control. If the control is a radio button, the Alt Underline Character will select the button; if it is check the box, it is equivalent to pressing the space bar for the check box; if the button will activate the button command; if the control is a static body, Activation is followed by the next control in the tab order.
Visible properties. It is visible to specify whether the control is visible.
Disable properties. Enable the control to allow or disable, a prohibited control is grayed, and no input cannot be received.
TabStop properties. The user can move on the control with the TabStop property by pressing the Tab button. The order of Tab moves can be specified by the user. Press CTRL D to the tab order, the user can re-specify the Tab order with the mouse. The default TAB order is the order of the control.
Group properties. Used to specify a set of controls, the user can use the arrow keys to move within the group control. The radio button in the same group has a mutually exclusive characteristic, that is, in these radio buttons, only one is selected. If a control has a Group property, this control and all the controls followed by the Tab belong to a set until another control with another Group property is encountered.
Start the design of the dialog template now. First, use the mouse to select the dialog box, press the Enter key, change the ID to IDD_REGISTER and specify the title "Login Data" in the pop-up of Idd_register and specify the title of the dialog. It should be noted that the correct language and font must be set because the Chinese characters are displayed in the dialog. Readers Click the IDD_REGISTER item in the Dialog type of the workspace resource view, and then press the Alt Enter key and select Chinese in the Language column in the pop-up property dialog box (p.r.c. Next, open the property dialog of the template, click the Font ... button, and select "Song".
Next, please delete all controls on the dialog template, the way to delete is to select the control and press the DEL key. In order to accommodate all required controls, the size of the dialog is required to be expanded to 280 × 180. Then, readers can design dialog templates as shown in Figure 5.1 and Table 5.2.
Tip: The size unit of the dialog is not pixel, but is related to the size of the font. One unit in the X direction is equal to 1/4 of the character average width, and one unit in the Y direction is equal to 1/8 of the character average height. Thus, as the font changes, the dialog unit also changes, and the overall proportion of the dialog is unchanged. Table 5.2
Control Type ID Title (CAPTION) Other Properties
Group box (personal situation) default personal situation
Group box (unit) default unit
Static body (name) default name
Edit box (Name) IDC_NAME default
Check box (marriage no) IDC_Married marriage
Static body (age) default age
Edit box (age) IDC_AGE default
Group box (gender) default gender default
Single selection button (Male) IDC_SEX Male Group, Tabstop
Single selection button (female) default female default
Group box (employment situation) default employment situation
Single selection button (in-service) IDC_Work Attendance Group, TabStop
Single selection button (laid off) IDC_WORK1 laid off
Static text (work unit) default work unit
Edit box (work unit) IDC_Unit default
Static body (unit properties) default unit nature
Combination box (unit properties) IDC_Kind Drop List, no sorting (not selected), initialization list items (see below)
Static text (wage income) default pay income
List box (salary income) IDC_INCOME is not sorted (not Sort)
Button (OK) IDOK Determine (& Y) Default
Button (Cancel) Idcancel Cancel (& C) Default
caution:
The combination frame has three kinds of Simple, drop-down (DROPDOWN) and drop-down list (DROP LIST). The Simple Composite Box contains an edit box and a list box that always displays. The distinction between the drop-down combination box with the simple combination box is that the list box will only appear only if you click the down arrow. The drop-down list combination box also has a drop-down list box, but its edit box is read-only and cannot enter characters.
The list item of the combo box can be initialized during design templates, and the initialization of the list box can only be done in the program. Please enter the following list items in the DATA page of the Properties dialog box of the combo box IDC_Kind as an option of unit properties. Be careful when entering, do not press Enter while pressing, but press CTRL Enter key. State-owned enterprises, collective enterprises, private enterprises, Chinese and foreign joint ventures, foreign companies
One of the combination frame controls is that it has two sizes, one is the size of the lower pull, one is the size of the drop. When you click on the arrow on the combo box with a mouse, the drop-down size can be set.
The control is best placed in the blue virtual box of the dialog template, and the distance between the controls should not be too close, otherwise it may cause incorrect display.
After resetting the control, the next task is to specify the Tab order. After pressing the CTRL D button, the current Tab sequence will be displayed. You can set the new Tab sequence by clicking the control with the mouse. If you want to give up this modification, click on the blank of the dialog box.
Finally, you need to test the dialog box. Press CTRL T, a current template's test dialog box will pop up, the appearance and basic behavior of this dialog box are the same as the dialog boxes you want to pop up. In this way, the reader does not need to compile the running program, and the dialog box can be evaluated as required by the test dialog box. If you find an error or unsatisfactory place, press the ESC button to exit the test dialog and re-modify the dialog template.
At this point, the design of the dialog template is completed.
Third, the design of the dialog box
After completing the design of the dialog template, you need to design a dialog class class to implement the function of the dialog. The design dialog box class mainly includes the following steps:
Create a dialog class class. This class should be derived from the CDIALOG class.
Add a member variable corresponding to the control to the dialog box class.
Initialize the dialog.
Increase the processing of the control notification message 1, the creation of the dialog box class
With ClassWizard, programmers can easily create derived classes for MFC window classes, and the dialog box is no exception. Please read the reader to follow the following steps:
Open the IDD_register dialog template, then press Ctrl W to enter the ClassWizard.
After entering ClassWizard, ClassWizard discovers IDD_register is a new dialog template, so it will ask if you want to create a dialog class for IDD_register. Press the OK key to confirm.
In the CREATE New Class dialog, enter CREGISTERDIALOG in the Name column, select CDIALOG in the Base Class bar, select IDD_REGOSTER in the Dialog ID box. After pressing the CREATE button, the dialog box CREGISTERDIALOG is created.
ClassWizard automatically links class CregsterDialog to IDD_REGISTER templates.
Tip: As long as the class wants to create is a derived class of a certain MFC window class, it is generally possible to use ClassWizard to move from the creation. The general way to create is: Open ClassWizard, select Add class-> New, then enter the CREATE New Class dialog box to enter the class name of the new class, select its MFC base class, if it is the dialog class, choose the dialog box ID.
2, join member variables for dialog box classes
The main function of the dialog is to output and enter data. The dialog requires a group of member variables to store data. In the dialog box, the control is used to represent or enter data, so the member variable of the stored data should correspond to the control.
The member variable corresponding to the control can be a data, or a control object, which will be determined by the specific needs. For example, you can specify a data variable for an edit box control so that you can easily obtain the data represented by the edit box control. If you want to control the edit box control, you should specify a CEDIT object for the edit box, pass Cedit objects, programmers can control the behavior of the control. It should be noted that the type of data variable corresponding to different types of controls is often different, and there may be a variety of data variables corresponding to one control. Table 5.3 illustrates the type of data variable of the control.
Type of control data variables
Edit Box Cstring, Int, Uint, Long, DWORD, FLOAT, DOUBLE, SHORT, BOOL, COLEDATETIME, COLECURRENCY
Ordinary check box bool (true representation, false means unchecked)
Three-state check box int (0 means unchecked, 1 indicating that 2 means uncertain state)
The radio button (the first button in the group) INT (0 indicates the first radio button in the group, 1 means the second ..., - 1 means no one is selected)
The list of non-sorted lists cstring (when it is empty, there is no list item being selected),
INT (0 indicates the first item, 1 means the second term, -1 means no one is selected)
Drop-oriented combination box cstring, int (meaning the same)
Other list boxes and combination box cstring (meaning the same)
Use ClassWizard to add member variables to the dialog class CREGISTERDIALOG. Please read the reader to follow the steps below.
Press CTRL W to enter ClassWizard.
Select the MEMBER VARIABLES tab at the ClassWizard and select CregisterDialog in the Class Name column. At this time, the ID of the dialog control is appear in the list of variables below. Double-click ID_age in the list pop-up the Add Member Variable dialog. Enter m_nage in the MEMBER VARIABLE NAME field, select Value in the Category column, select UINT in the Variable Type column. After pressing the OK button, the data variable m_nage will be added to the list of variables.
Patches with the third step and Table 5.4, add the corresponding member variables for each control.
Limit the value of m_nage between 16 to 65. The method is to select m_nage first, then enter the maximum and minimum value in the lower left corner of the ClassWizard dialog. M_Nage represents age, which specifies the age of people surveyed at 16 years old and 64 years old. After this limit, the dialog will validate the input age value. If the value entered is not within the limit, the dialog prompts the user to enter a valid value.
Table 5.4
Control ID variable type variable name
IDC_AGE uint m_nage
IDC_INCOME CSTRING M_STRINCOME
IDC_INCOME CLISTBOX M_CTRLINCOME
IDC_KIND CSTRING M_STRKIND
IDC_Married Bool M_Bmarried
IDC_NAME CSTRING M_STRNAME
IDC_SEX INT M_NSEX
IDC_Unit cstring m_strunit
IDC_Work Int M_nwork
The reader will notice that the control IDC_income actually has two variables, one is a CString type, one is a CListbox type, which is completely legal and will not cause any conflict. The reason why the clistbox type variable is to be added is because the initialization of the list box is performed via the CListbox object.
Tip: In ClassWizard, you can specify a data variable and a control object, respectively, and the advantage of making it easy to get data, and easily control the control.
3, initialization of the dialog
The initialization of dialogs is generally completed in the constructor and the OnInitDialog function. Initialization in the constructor is mainly a data member for the dialog. The reader can find the constructor of CREGISTERDIALOG, as shown in Listing 5.1.
Listing 5.1 CREGISTERDIALOG constructor
CREGISTERDIALOG :: CREGISTERDIALOG (CWND * PPARENT / * = NULL * /)
: Cdialog (cregisterDialog :: IDd, pparent)
{
// {{AFX_DATA_INIT (CREGISTERDIALOG)
m_nage = 0;
m_strincome = _t ("");
m_strkind = _t ("");
m_bmarried = false;
m_strname = _t ("");
M_Nsex = -1;
m_strunit = _t ("");
m_nwork = -1;
//}} AFX_DATA_INIT
}
It can be seen that the initialization of the data member is automatically complete by ClassWizard.
When the dialog is created, the WM_INITDIALOG message is received, and the dialog is the handler of the message is OnInitdialog. When calling OnInitDialog, the dialog has been initially created, and the window handle of the dialog is also valid, but the dialog has not been displayed. Therefore, you can do some initialization work that affects the appearance of dialog box in OnInitDialog. OnInitdialog's role in dialog is similar to OnCreate. The role of CMAINFRAME. Tip: The initialization of the MFC window is generally made in the oncreate member function, but the initialization of the dialog is best performed in OnInitdialog.
OnInitDialog is WM_INITDIALOG message handler, so use ClassWizard increase WM_INITDIALOG message handler for RegisteritDialog a class, the method is increased after entering ClassWizard, first select MessageMaps tab and select CRegisterDialog in the Class name, select the column in the Object IDs CREGISTERDIALOG, find WM_INITDIALOG in the Messages column and double-click, and finally press the OK button to exit ClassWizard. Use the reader to modify the OnInitDialog function by Listing 5.2.
Listing 5.2 OnInitDialog function
Bool creGisterDialog :: oninitdialog ()
{
CDIALOG :: OnInitdialog ();
m_ctrlincome.addstring ("500 yuan or less");
m_ctrlincome.addstring ("500-1000 yuan");
M_Ctrlincome.Addstring ("1000-2000 yuan");
m_ctrlincome.addstring ("2000 yuan or more");
Return True;
}
CregisterDialog :: OnInitDialog () The main task is to initialize the list item of the salary income list box. Call CListbox :: addString Adds the specified string to the list box. Since the list is not automatically sorted, addString adds the entry at the end of the list box.
4, dialog box data exchange mechanism
The data member variable of the dialog stores data corresponding to the control. Data variables need to be exchanged with the control to complete the input or output function. For example, an editing box can be used to input, or it can be used to output: When the user is input, the corresponding data member should be updated; when used as an output, it should be refreshed in time to refresh the contents of the edit box. Reflect changes in the corresponding data members. The dialog requires a mechanism to implement this data exchange function, which is critical to the dialog.
The MFC provides class CDataExchange to implement data exchange (DDX) between dialog classes and controls, which also provides a data effective mechanism (DDV). Data exchange and data effective mechanisms apply to edit boxes, check boxes, radio buttons, list boxes, and combo boxes.
Data exchange work is done by cdialog :: DODATAExchange. Readers can find the CregisterDialog :: DODATAEXCHANGE function, as shown in Listing 5.3. 0
Listing 5.3 DODATAEXCHANGE functions
Void CregisterDialog :: DODATAEXCHANGE (CDATAEXCHANGE * PDX)
{
CDIALOG :: DODATAEXCHANGE (PDX);
// {{AFX_DATA_MAP (CREGISTERDIALOG)
DDX_Control (PDX, IDC_INCOME, M_CTRLINCOME);
DDX_LBSTRING (PDX, IDC_INCOME, M_STRINCOME);
DDX_CBSTRING (PDX, IDC_KIND, M_STRKIND); DDX_CHECK (PDX, IDC_Married, m_bmarried);
DDX_TEXT (PDX, IDC_NAME, M_STRNAME);
DDX_RADIO (PDX, IDC_SEX, M_NSEX);
DDX_TEXT (PDX, IDC_Unit, M_Strunit);
DDX_RADIO (PDX, IDC_Work, M_nWork);
DDX_TEXT (PDX, IDC_AGE, M_NAGE);
DDV_MINMAXUINT (PDX, M_NAGE, 16, 65);
//}} AFX_DATA_MAP
}
The reader can see that the code in this function is automatically added by ClassWizard. DODATAEXChange has only one parameter, the pointer PDX of a CDataExchange object. DDX functions are called in this function to complete data exchange, call DDV functions to perform data effective check.
When the program needs to exchange data, do not call the DODATAEXCHANGE function directly, and CWnd :: Updatedata should be called. DODATAEXCHANGE is called inside the UpdataData function. This function has only one Boolean parameter that determines the direction of data transfer. Call Updatedata (TRUE) Transferring data from the control of the dialog to the corresponding data member, call Updatedata (false), transfer the data from the data member to the corresponding control.
UpdateData (false) is called in the default cdialog :: OnNIndIalog, so that when the dialog is created, the initial value of the data will be reflected on the corresponding control. If the user is pressed the OK (OK) button exits the dialog, the dialog box is considered to be valid, and UpdataData (TRUE) will pass the data in the control to the data member. Figure 5.9 depicts this data exchange mechanism of the dialog.
Figure 5.9 Data exchange of dialog
5, the operation mechanism of the dialog
There are two steps to run the modal dialog box in the program:
Build a dialog object in the form of a variable on the stack.
Call CDIALOG :: Domodal ().
Domodal is responsible for the creation and revoking of the modal box. When the dialog is created, the Domodal task includes loading the dialog template resource, calls the OnInitDialog Initialization dialog and display the dialog on the screen. After completing the creation of the dialog, Domodal launches a message loop to respond to the user's input. Since the message loop intercepts almost all input messages, the main message loop does not receive input to the dialog, causing the user to interact with the modal dialog, while other user interfaces are not allowed to receive input information.
If the user clicks the IDOK button in the dialog (usually the title "OK" or "OK"), or press the Enter key, CDIALOG :: Onok will be called. Onok first calls Updatedata (TRUE) to pass the data from the control to the dialog member variable, then call CDIALOG :: EndDialog Close dialog. After closing the dialog, Domodal will return a value IDOK.
If the user clicks the ID Cancel button (usually its title "Cancel" or "Cancel"), or press the ESC button, it will cause CDIALOG :: OnCancel calls. This function only calls CDIALOG :: EndDialog Close dialog. After closing the dialog, Domodal will return the value IDCANCEL.
The program can determine whether the user is determined or canceled by the user is determined or canceled by IDOK or IDCANCEL.
After changing the running mechanism of the dialog box, let us implement the functionality of the Register program login data.
First, switch the REGISTER project's work area to the resource view. Open the IDR_MAINFRAME menu resource, add a new menu item named "Login Data" on the bottom end of the EDIT menu, and make it id_edit_register (preferably add a separation line before this item, so that the previous menu item is separated) . Next, create a command processing function creGisterView :: OneIgister for this menu command with ClassWizard. Note that OneDitRegister is a member function of class CREGIsterView because CREGISTERVIEW is responsible for opening and closing the login data dialog and outputs data entered from the dialog box in the view.
Then, please read the beginning of the REGISTERVIEW.CPP file to join a line #include "registerDialog.h"
Finally, modify the program by Listing 5.4.
Listing 5.4 One DITREGISTER function
Void Cregisterview :: OneDitRegister ()
{
CregisterDialog DLG;
IF (DLG.Domodal () == iDOK)
{
CString Str;
GetWindowText (STR); // Get editing body
Str = "/ r / n"; // Renewal
STR = "Name:";
Str = dlg.m_strname;
Str = "/ r / n";
STR = "Gender:";
STR = DLG.M_NSEX? "Female": "Men";
Str = "/ r / n";
STR = "age:";
CString str1;
Str1.format ("% D", DLG.M_NAGE); // output data format to string object
STR = STR1;
Str = "/ r / n";
Str = "Marry:";
Str = dlg.m_bmarried? "Married": "Unmarried";
Str = "/ r / n";
STR = "Employment Status:";
STR = DLG.M_NWORK? "Laid": "in-service";
Str = "/ r / n";
STR = "Work Unit:";
Str = dlg.m_strunit;
Str = "/ r / n";
Str = "Unit Nature:";
Str = dlg.m_strkind;
Str = "/ r / n";
STR = "Salary Revenue:";
Str = dlg.m_strincome;
Str = "/ r / n";
SetWindowText (STR); / / Update the text of the edit view
}
}
In the onEditregister function, first build a CREGISTERDIALOG object, then call CDialog :: Domodal to implement the Modal dialog box. If Domodal returns IDOK, the user confirms the operation of the login data, and the program needs to output the recorded data in the editing view. The program uses a CString object as a buffer of editing the body. CString is a powerful string class. Its maximum feature is that the dynamically changed sized string so that the user does not have to worry about the length of the string exceeds the buffer The size is very convenient to use. When outputting data, the program first calls CWnd :: getWindowText to get editing body, this is a multi-line editing body. CWnd :: getWindowText is used to get the title of the window. If the window is a control, it is obtained that the body inside the control. CREGISTERVIEW is the inheritance class of CeditView, and the CEDITVIEW actually contains an editing control, so the CREGISTERVIEW is called GetWindowText to edit the body.
The program then adds new data at the end of the editing body. A large amount of the overload operator " =" of the CSTRING class is used in the program, which is the end of the operator to the end of the character string on the left side of the operator. Note that there is a pair of carriage return and newline characters at the end of the multi-line editing control. CSTRING:: Format is called in the program to format the data to the string, and the Format is similar to Sprintf. Finally, call CWnd :: SetWindowText to update the body in the edit view.
Compile and run Register, open the login data dialog, and enter some data. Now, Register is already a simple database application that can output data related to the employment situation to an editing view. The user can edit the body in the view and save the results in the text file.
6, handle control notification message
Although Register already logs in to data, the reader will soon discover that there are some imperfect places:
After logging in to a person's data, the dialog is turned off. If the user has a lot of people's data to enter, the dialog must be opened frequently, it is very inconvenient. When logging in to data, the dialog should always be in an open state.
The login data dialog box is divided into two groups of individual situations and units. If the respondent is a laid-off worker, it will not be necessary to enter the unit. The program should be able to respond in time to the user's input, that is, when the user selects the "Launch" radio button, the control in the unit should be prohibited. A prohibited control is grayed and cannot receive the user's input.
To solve the above problems, the control notification message must be processed. When the status of the control changes, the control will issue a control notification message to its parent window due to the change of the input or the like. For example, if the user clicks the mouse on a certain button (including the normal button, check box, and radio button) in the login data dialog, the button sends a BN_Clicked message to the dialog. The dialog is activated according to the ID ID of the button to react with the event of the click button. With the processing of the BN_Clicked message for the button, we can make the function of the login data dialog to the above requirements.
First, let us solve the first question. Our idea is to modify the original "Determined (Y) button so that when the user clicks the button, output the data into the view, and the dialog is not closed so that the user enters the next data. Please make changes to the following steps below.
Modify the "OK (Y) button of the login data dialog so that the title of the button becomes" Add (& A) ", the ID changes to IDC_ADD. Thus, the dialog will receive a BN_Clicked message when the user clicks the button. Since the button ID corresponding to this BN_Clicked message is not IDOK, the ONOK message processing function is not triggered, so the dialog is not closed. Create a message processing function for the Bn_Clicked message of Button IDC_ADD. After the creating method is to enter the ClassWizard, select the Message Maps page and select CregisterDialog in the Class Name column, then select IDC_ADD in the Object IDS bar, double-click BN_Clicked in the Messages column. After confirming that the default message processing function name OnAdd, press Enter to exit the ClassWizard.
Onadd wants to output a body to edit views, you must get a pointer to the CREGIsterView object to access the object. To do this, add the following line in the description of the CregisterDialog class.
CWND * m_pparent; // Notice Do not add in the AFX annotation pair.
For the function of implementing the IDC_ADD button, press Listing 5.5 and Listing 5.6 Modifying the program. The main change is to hand over the task of output data in the view from Cregiserview :: OneIitRegister to CregisterDialog :: OnAdd.
Listing 5.5 CREGISTERVIEW :: OneEDitRegister function
Void Cregisterview :: OneDitRegister ()
{
// Todo: add your command handler code here
CregisterDialog DLG (this);
Dlg.domodal ();
}
Listing 5.6 Some source code for the CREGISTERDIALOG class
CREGISTERDIALOG :: CREGISTERDIALOG (CWND * PPARENT / * = NULL * /)
: Cdialog (cregisterDialog :: IDd, pparent)
{
// {{AFX_DATA_INIT (CREGISTERDIALOG)
..........
//}} AFX_DATA_INIT
m_pparent = pParent;
}
Void cregisterdialog :: onadd ()
{
// Todo: Add Your Control Notification Handler Code Here
//update data
Updatedata (TRUE);
/ / Check if the data is valid
IF (m_strname == "|| m_nsex <0 || m_nwork <0 || m_strunit ==" "
|| m_strkind == "" || m_strincome == "" "
{
AFXMessageBox ("Please enter a valid data");
Return;
}
CString Str;
// Get editing text
m_pparent-> getWindowText (STR);
// Renewal
Str = "/ r / n";
STR = "Name:";
Str = m_strname;
Str = "/ r / n";
STR = "Gender:";
STR = m_nsex? "female": "male";
Str = "/ r / n";
STR = "age:";
CString str1;
// Output data format to str1.format ("% D", m_nage) in the string object;
STR = STR1;
Str = "/ r / n";
Str = "Marry:";
STR = m_bmarried? "Married": "Unmarried";
Str = "/ r / n";
STR = "Employment Status:";
STR = m_nwork? "Lowering": "in-service";
Str = "/ r / n";
STR = "Work Unit:";
Str = m_strunit;
Str = "/ r / n";
Str = "Unit Nature:";
Str = m_strkind;
Str = "/ r / n";
STR = "Salary Revenue:";
Str = m_strincome;
Str = "/ r / n";
/ / Update the body in the edit view
m_pparent-> setWindowText (STR);
}
The constructor of CregisterDialog has a parameter PParent, which is a pointer to the CWND object that specifies the parent window or owner window of the dialog. In the CregisterView :: OneDitRegister function, the THISTERDIALOG object is built, and the this pointer points to the CregisterView object itself. This is called a member m_pparent of CregisterDialog when calling the constructor of CREGISTERDIALOG. Onadd functions can use M_PParent to access the owner of the dialog, the CregisterView object.
Tip: The term parent window (PARENT) is relative to the child window. If a window has a child window (Child), the window is called the parent window of the sub-window. The sub-window is a window with a WS_CHILD style, and the child window depends on the parent window and is fully limited to the inside of the parent window. The owner window (OWNER) is relative to the owner window. If a window has a non-sub-window, the window is called the owner window. It is owned by the window (OWNED) without WS_CHILD style, can be moved on the screen.
When the user clicks the IDC_ADD button with a mouse, the button's BN_Clicked message processing function cregisterDialog :: OnAdd will be called. In ONADD, Updatedata (TRUE) is first called to transfer the data from the control to the data member variable of the dialog. The program then checks the validity of the data. If the input data is not fully valid, a message dialog is displayed, prompting the user to enter a valid data. The next job is to output data in the view, this part of the code is similar to Listing 5.4, and the reader should be more familiar.
After completing the above work, the login data dialog becomes more practical. After opening the dialog, the user can easily enter multiplayer data. After pressing the cancel button, the dialog will close.
Let us first solve the second problem. The key to solving this problem is that when the user clicks the "Office" or "Logging" radio button, the program is to respond to the received BN_Clicked message. Some readers may think of creating a BN_Clicked message processing function for two radio buttons, which can be made in the case of only two radio buttons, but if there is a plurality of radio buttons in a group, create a message processing separately The function is more troublesome. Message mapping with MFC Macro on_control_range can avoid this trouble, the mapping macro maps messages emitted by multiple id consecutive controls to the same processing function. In this way, we can respond to the BN_Clicked message of "post" and "laid" and "laid" and "laid". ClassWizard does not support an on_control_range macro, so we must manually create a message mapping and message processing function of the radio button. First, add a declaration of the message processing function in the header file of the CREGISTERDIALOG class, which is named onworkClicked, as shown in Listing 5.7.
Listing 5.7 Bn_Clicked Message Processing Function ONWORKCLICKED Declaration
..........
protected:
Void OnWorkclicked (uint ncmdid);
// generated message map functions
// {{AFX_MSG (CREGISTERDIALOG)
Virtual Bool OnInitdialog ();
AFX_MSG void onadd ();
//}} AFX_MSG
..........
Then, add an ON_CONTROL_RANGE mapping in the message map of the CregisterDialog class, as shown in Listing 5.8. ON_CONTROL_RANGE mapping form is on_control_range
Listing 5.8 Join on_control_range mapping in the message map of the CregisterDialog class
Begin_MESSAGE_MAP (CregisterDialog, CDIALOG)
// {{AFX_MSG_MAP (CREGISTERDIALOG)
ON_BN_CLICKED (IDC_ADD, ONADD)
//}} AFX_MSG_MAP
ON_CONTROL_RANGE (BN_Clicked, Idc_Work, IDC_Work1, ONWorkclicked)
END_MESSAGE_MAP ()
The first parameter of the ON_Control_Range message mapping macro is that the control message code, the second and third parameters indicate the first and last ID of a set of continuous control IDs, and the last parameter is the message processing function name. If the reader places the control in the order of Table 5.2, Idc_Work and IDC_WORK1 should be continuous. In this way, the ONWORKClicked message processing function is called whether the user is clicked on Idc_Work or on the IDC_WORK1 radio button.
Tip: If you cannot determine if the two IDs are continuous, open the resource.h file with the file-> Open command, and have the definition of the control ID value in this file. If two IDs are disconnected, the reader can change the definition value for the ID, but pay attention to the value after the change is not conflicted with the other ID value.
Finally, the final plug message processing function creGisterDialog :: ONWORKClicked in the CREGOSTERDIALOG class is located in the CregisterDialog class.
Listing 5.9 CREGISTERDIALOG :: ONWORKCLICKED message handler
Void CregisterDialog :: OnWorkclicked (uint ncmdid)
{
// Deconstimate whether the "in-service" radio button is selected
IF (ISDLGBUTTONCHECKED (IDC_WORK))
{
/ / Make the control allow
Getdlgitem (IDC_Unit) -> EnableWindow (TRUE); getdlgitem (IDC_KIND) -> EnableWindow (TRUE);
Getdlgitem (IDC_INCOME) -> EnableWindow (TRUE);
}
Else
{
/ / Clear the contents of the edit box and disable it
Getdlgitem (IDC_Unit) -> setWindowText ("");
Getdlgitem (IDC_Unit) -> EnableWindow (false);
/ / Make the combo frame in the unselected state and disable it
CCOMBOBOX * PCOMBOBOX = (ccomboBox *) getdlgitem (IDC_KIND);
PCOMBOBOX-> setCursel (-1);
PCOMBOBOX-> EnableWindow (FALSE);
/ / Make the list box in the unselected state and disable it
m_ctrlincome.setcurseel (-1);
m_ctrlincome.enableWindow (FALSE);
}
}
ONWORKCLICKED function Judgment "The Office" radio button is selected. If the button is selected, the control in the unit case is allowed. If the button is not selected, the "Lower" button is selected, then the control should be disabled, clear the body in the edit box, and make the combo box And the list box is in an unchecked state.
The following functions are mainly called in the onworkclicked function:
CWnd :: isdlgbuttonChecked function, used to determine whether the radio button or check box is selected, the declaration of the function is uint isdlgButtonChecked (int Nidbutton) const; parameter nidbutton is the ID of the button. If the button is selected, the function returns 1, otherwise it returns 0. If the button is in an uncertain state, the return value is 2.
CWnd :: getdlgitem function, used to get a pointer to a control, the declaration of the function is CWnd * getdlgitem (int NID) const; parameter NID is the ID of the control. This function returns a CWND object pointer to a specified control, and the program can control the control through this pointer.
CWnd :: EnableWindow function, the function enables the window to allow or disable, the prohibited window is grayed, and the keyboard and the input of the mouse cannot be received. The declaration of this function is BOOL EnableWindow; if the value of the parameter Benable is true, the window is allowed. If the Benable value is false, the window is disabled.
Clistbox :: setCurseel and CCOMBOBOX :: SetCuRsel function functions, used to make an item in the list selected, the selected item is high brightness display. The statement of the function is int setCurseel (INT NSELECT); the parameter nSelection specifies the index of the new option. The index value of the first item is 0. If the value of NSELEC is -1, the function will clear the previous selection, so that the list is not selected status.
Sometimes, you need to convert the CWND pointer returned by Getdlgitem to the pointer to the control object to call the control object's proprietary member function to control the control. For example, the pointer returned in the program Getdlgitem (IDC_KIND) is forced to convert into a CCOMBOBOX type. Only this can call the CCOMBOBOX :: SetCursel member function.
In order to query and control the control, two ways of access controls are used in the program. One method is to directly utilize the control objects provided by ClassWizard, such as the M_CtrLinCome list box object. Another way is to use a member function of a group of management dialog controls provided by the CWND class, such as getDLGITEM and ISDLGBUTTONCHECKED used in the program. Both methods are common methods for accessing controls within the dialog, and readers should be mastered. Table 5.5 lists the CWND member functions of the management dialog control. Table 5.5 CWND member functions used to manage dialog controls
Function name function
Checkdlgbutton is selected or not selected button controls.
CheckRadiobutton selects a specified radio button and makes other radio buttons within the same group not selected.
DLGDIRLIST adds a list of files, directories, or drives to a list box.
DLGDIRLISTCOMBOBOX adds a list of files, directories, or drives in a list box in a combo box.
DLGDIRSELECT Gets the currently selected file, directory, or drive from a list box.
DLGDIRSELECTBOMBOBOX Gets currently selected files, directories, or drives from a combo box.
GetCheckedRadiobutton returns the ID of the selected select button in the specified radio button group.
GetDLGITEM returns a pointer to the temporary object of a given control.
Getdlgitemint returns a numeric value represented by the body in a specified control.
GetdlgiteMtext is a body displayed in one control.
GetNextdlGroupItem returns a pointer to the temporary object of the next control within a set of controls.
GetNextdlgTabItem returns a pointer to the temporary object of the next Tab sequence.
IsdlgButtonChecked returns a status of a button control.
SenddlgiteMMessage transmits a message to a control.
Setdlgitemint converts an integer into a body and assumes this anecdote to the control.
SetdlgitemText Sets a control displayed by a control.
Compile and run Register to see, the current login data dialog is more satisfactory.
Fourth, non-modular dialog
1, characteristics of non-modular dialog
Unlike the modal dialog, the non-modular dialog does not monopolize the user's input, and the user can still interact with other interfaces after the user opens the non-modular dialog.
The design and modal dialog of non-modular dialogs is basically similar, including the design dialog template and a derived class of the CDialog class. However, during the creation and deletion of the dialog, the non-modular dialog box is different from the modal dialog box:
· The template for non-modular dialogs must have a Visible style, otherwise the dialog will not be visible, and the modal dialog box does not need to set this style. What is more insurance is to call CWnd :: ShowWindow (SW_SHOW) to display the dialog, regardless of whether the dialog has a Visible style.
• Non-modular dialog objects are dynamically created in the heap in the stack, rather than embedding other objects in the form of a member variable or on the stack in the form of a local variable. You should usually declare a pointer member variable to the dialog class within the owner window class of the dialog, which can access the dialog object through this pointer.
· Start the dialog by calling the cdialog :: create function, not CDIALOG :: Domodal, which is the key to the modal dialog. Since the CREATE function does not start a new message loop, the dialog box is cycled with the application, so that the dialog box does not monopolize the user's input. CREATE returns immediately after the dialog is displayed, and Domodal is returned after the dialog is turned off. As is well known, in the MFC program, the survival period of the window object should be longer than the corresponding window, that is, cannot delete the corresponding window object in the case where the window is not closed. Since it is not possible to determine if the dialog has been turned off after Create returns, it is not possible to determine the living period of the dialog object, so you have to build a dialog object in the heap, and cannot be built in the form of a local variable. · Cause CWnd :: DestroyWindow instead of cdialog :: enddialog to turn off the Non-Modular dialog. Call CWnd :: DestroyWindow is a general method of deleting a window. Due to the default cDialog :: Onok and CDIALOG :: OnCancel functions, both endDialog, the programmer must write its own Onok and the oncancel function and call DESTROYWINDOW to close the dialog in the function.
· Because it is built with a New operator to build a non-modular dialog object, you must remove the dialog object with the Delete operator after the dialog is turned off. After the window is deleted, the frame will call CWnd :: Postncdestroy, this is a virtual function, the program can complete the work of the delete window object, the specific code is as follows
Void CmodelessDialog :: Postncdestroy
{
Delete this; // Delete the object itself
}
Thus, after deleting the dialog on the screen, the dialog object will be automatically deleted. The owner object does not have to explicitly call Delete to delete the dialog object.
· There must be a logo that the non-modal dialog is open. The reason for this is that the user may select an open command again in the case of opening a modal dialog. The program determines based on the flag to open a new dialog or only the original open dialog is activated. You can usually use the pointer to the pointing dialog object in the owner window as this flag. When the dialog is turned off, the null value is assigned to indicate that the dialog object does not exist.
Tip: In C programming, it is judged whether or not there is a common way to exist in the heap to determine whether the pointer to the object is empty. This mechanism requires a programmer to initialize the pointer to the object to a null value, assigns the address returned to the pointer when the object is created, and the pointer is set to a null value when the object is deleted.
According to the above analysis, we can easily change the login data dialog in the Register program into a non-modular dialog. The benefit of doing this is that if the user finds an error in the editing view when entering the data, the dialog box can be modified in the edit view without having to close the dialog.
Please read the following steps below:
Select the Visible item in the more STYLES page of the Properties dialog box for the login data dialog template.
Add to the definition of the CREGIsterView class of the registerview.h header
PUBLIC:
CREGISTERDIALOG * M_PREGISTERDLG;
Add a statement on the CregisterDialog class on the head of the registerview.h header file
Class CregisterDialog;
The reason for adding the line is a pointer to a CREGISTERDIALOG type in the CREGIsterView class, so it is necessary to ensure that the CregisterDialog class has appeared before CregisterView, otherwise compiles. There are two ways to solve this problem. One way is to ensure that there is a #include "registerDialog.h" statement before the #include "registerview.h" statement, this method has caused a dependence, increasing the compilation burden, not very Ok, another way is to temporarily "blind" compiler for CregisterDialog before the statement of the CregisterView class, so in the module of the #include "registerview.h" statement, unless you want to use the CREGISTERDIALOG class. Otherwise, don't join the #include "registerdialog.h" statement. Add the following two lines at the end of the #include statement area of the head of the registerdialog.cpp file.
#include "registerdoc.h"
#include "registerview.h"
Use ClassWizard to join the oncancel and postncdestroy member functions for the CregisterDialog class. The joined method is to select Message after entering ClassWizard.
MAPS page and select CregisterDialog in the Class Name column. Then, after selecting IDCANCEL in the Object IDS bar, double-click BN_Clicked in the Messages column, which creates an oncancel. To create postncdestroy, first select CregisterDialog in the Object IDS bar, and then double-click PostNCDESTROY in the Messages column.
Press Listing 5.10 and 5.11, modify the CregisterView class and the CregisterDialog class.
Some code for the list 5.10 CREGISTERVIEW class
Cregisterview :: CREGISTERVIEW ()
{
// Todo: Add Construction Code Here
m_pregisterdlg = null; / / Pointer initialized to null
}
Void Cregisterview :: OneDitRegister ()
{
// Todo: add your command handler code here
IF (m_pregisterdlg)
m_pregisterdlg-> setActiveWindow (); // Activate dialog
Else
{
// Create a non-modal dialog
m_pregisterdlg = new cregisterdialog (this);
m_pregisterdlg-> create (IDD_register, this);
}
}
Some code of list 5.11 CREGISTERDIALOG
Void cregisterdialog :: postncdestroy ()
{
// Todo: Add Your Specialized Code Here and / or Call The Base Class
Delete this; // Delete dialog object
}
Void cregisterdialog :: oncancel ()
{
// Todo: Add extra cleanup here
(CREGISTERVIEW *) m_pparent) -> m_pregisterdlg = NULL;
DESTROYWINDOW (); // Delete dialog
}
The CregisterView :: OneDitRegister function determines if the login data dialog is open. If you activate the dialog, you will create the dialog box. The following function is mainly called: Call the CWnd :: SetActiveWindow activation dialog, the declaration of the function is CWND * setActiveWindow ();
This function makes this window a moving window and returns the original event window.
Call CDialog :: Create to display the dialog box, the function is bool create (uint nidTemplate, CWnd * pParentWnd = null);
The parameter nidtemplate is the ID of the dialog template. PParentWnd specifies the parent window or owner of the dialog.
When the user clicks on the "Cancel" button in the login data dialog, CregisterDialog :: OnCancel will be called, call CWnd :: DestroyWindow in this function to close the dialog, and set the cregisterview member m_pregisterdlg to NULL to indicate dialog box Closed. Calling DestroyWindow results in call to CregisterDialog :: PostNCDESTROY, in which DELETE operator is used to delete the CREGISTERDIALOG object itself.
Compile and run the Register, the login data dialog now has become a non-modular dialog.
5.4.2 Automatic Clear of Window Objects
An MFC window object includes two aspects: First, the window of the window object package is stored in the hwnd in the M_HWnd member, and the other is that the window object itself is a C object. To delete an MFC window object, you should first remove the window of the window object package, and then delete the window object itself.
The most direct way to delete the window is to call CWnd :: DestroyWindow or :: DestroyWindow, the former encapsulates the function of the latter. The former will not only call the latter, but also the HWnd invalid (NULL) saved by member M_hWnd. If DESTROYWINDOW deletes a parent window or owner window, the function will automatically delete all sub-windows or owners, and then delete the parent window or owner. In general, do not have to call DESTROYWINDOW directly in the program to delete the window because the MFC will automatically call DESTROYWINDOW to delete the window. For example, when the user exits the application, a WM_CLOSE message generates a WM_Close message that causes the MFC to automatically call CWnd :: DestroyWindow to delete the main frame window, when the user presses the OK or Cancel button in the dialog, the MFC will automatically call CWnd :: DestroyWindow to delete dialogs and their controls.
The deletion of the window object itself is divided into two situations depending on the object creation. In the MFC programming, a large number of window objects are used, and some window objects are embedded in other objects or in the form of a local variable in the form of a local variable, and some use the New operator in the heap. For a window object created in a variable, the programmer does not have to care about its deletion problem, because the life of the object is always limited, if the object is a member variable of an object, it will disappear with the parent Disappearing, if the object is a local variable, it will be cleared when the function returns.
For a window object that is dynamically created in the heap, its life is arbitrary. When you learn C programming, the use of the New operator is often not very practical because you create an object in the stack, you can't forget to delete the object with Delete. When the reader learns the MFC routine, you may have such a question, why some programs create a window object with NEW, but did not explicitly use DELETE to delete it? The answer to the question is that some MFC window objects have the function of automatic clearance. As mentioned in the previous Non-Modular dialog, the PostncDestroy member function of the deleted window is called when the CWnd :: DESTROYWINDOW or:: DestroyWindow deletes the window. The default PostNCDESTROY does not dry, but some MFC window classes override the function and call DELETE THIS to delete the object in the new version of PostNCDESTROY, which has the function of automatic clearance. Such window objects are typically created in a heap with a New operator, but the programmer does not have to use the Delete operator to delete them, because once the DestroyWindow delete window is called, the corresponding window object will be removed immediately.
Window classes that do not have automatic clearance functions are as follows. These window objects are usually created in the form of variables without automatic cleaning.
All standard Windows control classes.
Sub-window objects (such as user-customized controls) from the CWND class.
Split window csplitterwnd.
Default control bar class (including toolbar, status bars, and dialogue).
Modal dialog class.
Window classes with automatic cleaning functions are as follows, which are usually created in the heap.
The main frame window (directly or indirectly derived from the CFrameWnd class).
View class (derived from the CView class directly).
When the reader is designed with your derived window class, the reader can decide whether the window class can be automatically cleared according to the creation method of the window object. For example, for a non-modular dialog, its object is created in a heap and therefore should have an automatic cleaning function.
In summary, for the MFC window class and its derived class, the window object is generally not necessary in the program. That is, there is no need to call DESTROYWINDOW to delete the window of the window object package, nor does it have to explicitly use the Delete operator to remove the window object itself. As long as the non-automatic cleared window object is created in the form of a variable, the auto-cleared window object is created in the heap, the MFC's running mechanism ensures complete deletion of the window object.
If you need to manually delete window objects, you should call the corresponding function (such as CWnd :: DestroyWindow) to delete the window, then delete the window object. For window objects created in variables, the deletion of window objects is automatically completed by the framework. For non-automatic cleared window objects that are dynamically created in the heap, you must delete the object (generally in the destructuring function of the owner or parent window) after the window is deleted. For window objects with automatic cleaning, you can remove windows and window objects with CWnd :: DESTROYWINDOW. Note that for window objects created in the heap, do not use the delete operator with the Delete operator with the DELETE operator without being closed.
Tip: You may not call CWnd :: destroyWindow in the oncance function of the Non-Modular dialog, and replaced it is to invoke CWnd :: ShowWindow (sw_hide) to hide the dialog. When you open the dialog next time, you don't have to call CREATE, just call CWnd :: ShowWindow (SW_SHOW) to display the dialog. The benefit of this is that the data in the dialog can be saved for later use. Since the owner window calls DESTROYWINDOW to delete every window when it is closed, as long as the non-modular dialog is automatically cleared, the programmer does not have to worry about the problem of the dialog object. 5.5 Label dialog
5.6 Common dialog
5.7 small knot
Finish