This is a continuation from the previous module... Program examples compiled using Visual C++ 6.0 (MFC 6.0) compiler on Windows XP Pro machine with Service Pack 2. Topic and sub topic if any for this Tutorial is listed below:
The MYMFC8 Project Example
The steps using common controls are shown below.
Run AppWizard to generate the MYMFC8 project. Choose New from Visual C++'s File menu, and then select Microsoft AppWizard (exe) from the Projects page. Accept all the defaults but two: select Single Document and deselect Printing And Print Preview. The options and the default class names are shown here.
Figure 58: MYMFC8 project summary.
Create a new dialog resource with ID IDD_DIALOG1 (default ID used). Place the controls as shown in Figure 57.
You can select, drag and drop the controls from the control palette. The following table lists the control types and their IDs. Don't worry about the other properties now; you'll set those in the following steps. Some controls might look different than they do in Figure 59 until you set their properties. Set the tab order as shown next.
|
Figure 59: MYMFC8 dialog resource with its common controls.
|
Use ClassWizard to create a new class, CMymfc8Dialog, derived from CDialog. ClassWizard will automatically prompt you to create this class because it knows that the IDD_DIALOG1 resource exists without an associated C++ class.
Figure 60: Creating a new class, CMymfc8Dialog, derived from CDialog.
Figure 61: The CMymfc8Dialog class information.
Map the WM_INITDIALOG message, the WM_HSCROLL message, and the WM_VSCROLL message.
Figure 62: Mapping the WM_INITDIALOG, WM_HSCROLL and WM_VSCROLL messages.
Program the progress control. Because ClassWizard won't generate a data member for this control, you must do it yourself. Add a public integer data member named m_nProgress in the CMymfc8Dialog class header, and set it to 0 in the constructor.
Figure 63: Adding a public integer data member named m_nProgress.
Figure 64: Adding the variable type and name.
Listing 13.
Also, add the following code in the OnInitDialog() member function:
CProgressCtrl* pProg = (CProgressCtrl*) GetDlgItem(IDC_PROGRESS1);
pProg->SetRange(0, 100);
pProg->SetPos(m_nProgress);
Listing 14.
Program the "continuous" trackbar control. Add a public integer data member named m_nTrackbar1 to the CMymfc8Dialog header, and set it to 0 in the constructor.
Figure 65: Adding a public integer data member named m_nTrackbar1 to the CMymfc8Dialog header.
Figure 66: Entering the variable type and name.
Listing 15.
Listing 16.
Next add the following code in the OnInitDialog() member function to set the trackbar's range, to initialize its position from the data member, and to set the neighboring static control to the tracker's current value.
CString strText1;
CSliderCtrl* pSlide1 = (CSliderCtrl*) GetDlgItem(IDC_TRACKBAR1);
pSlide1->SetRange(0, 100);
pSlide1->SetPos(m_nTrackbar1);
strText1.Format("%d", pSlide1->GetPos());
SetDlgItemText(IDC_STATIC_TRACK1, strText1);
Listing 17.
To keep the static control updated, you need to map the WM_HSCROLL message that the trackbar sends to the dialog. Here is the code for the handler:
void CMymfc8Dialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CSliderCtrl* pSlide = (CSliderCtrl*) pScrollBar;
CString strText;
strText.Format("%d", pSlide->GetPos());
SetDlgItemText(IDC_STATIC_TRACK1, strText);
}
Listing 18.
Finally, you need to update the trackbar's m_nTrackbar1 data member when the user clicks OK. Your natural instinct would be to put this code in the OnOK() button handler. You would have a problem, however, if a data exchange validation error occurred involving any other control in the dialog. Your handler would set m_nTrackbar1 even though the user might choose to cancel the dialog. To avoid this problem, add your code in the DoDataExchange() function as shown below. If you do your own validation and detect a problem, call the CDataExchange::Fail function, which alerts the user with a message box.
if (pDX->m_bSaveAndValidate)
{
TRACE("updating trackbar data members\n");
CSliderCtrl* pSlide1 = (CSliderCtrl*) GetDlgItem(IDC_TRACKBAR1);
m_nTrackbar1 = pSlide1->GetPos();
}
Listing 19.
Program the "discrete" trackbar control. Add a public integer data member named m_nTrackbar2 to the CMymfc8Dialog header, and set it to 0 in the constructor. This data member is a zero-based index into the dValue, the array of numbers (4.0, 5.6, 8.0, 11.0, and 16.0) that the trackbar can represent.
Figure 67: Adding a public integer data member named m_nTrackbar2 to the CMymfc8Dialog header.
Listing 20.
Listing 21.
Define dValue as a private static double array member variable in mymfc8Dialog.h:
Figure 68: Adding dValue array member variable in mymfc8Dialog.h.
Listing 22. |
And add to mymfc8Dialog.cpp the following line:
double CMymfc8Dialog::dValue[5] = {4.0, 5.6, 8.0, 11.0, 16.0};
Listing 23.
Next add code in the OnInitDialog() member function to set the trackbar's range and initial position.
CString strText2;
CSliderCtrl* pSlide2 = (CSliderCtrl*) GetDlgItem(IDC_TRACKBAR2);
pSlide2->SetRange(0, 4);
pSlide2->SetPos(m_nTrackbar2);
strText2.Format("%3.1f", dValue[pSlide2->GetPos()]);
SetDlgItemText(IDC_STATIC_TRACK2, strText2);
Listing 24.
If you had only one trackbar, the WM_HSCROLL handler in the previous step would work. But because you have two trackbars that send WM_HSCROLL messages, the handler must differentiate. Here is the new code:
void CMymfc8Dialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CSliderCtrl* pSlide = (CSliderCtrl*) pScrollBar;
CString strText;
// Two trackbars are sending
// HSCROLL messages (different processing)
switch(pScrollBar->GetDlgCtrlID())
{
case IDC_TRACKBAR1:
strText.Format("%d", pSlide->GetPos());
SetDlgItemText(IDC_STATIC_TRACK1, strText);
break;
case IDC_TRACKBAR2:
strText.Format("%3.1f", dValue[pSlide->GetPos()]);
SetDlgItemText(IDC_STATIC_TRACK2, strText);
break;
}
}
Listing 25.
This trackbar needs tick marks, so you must check the control's Tick Marks and Auto Ticks properties back in the dialog editor. With Auto Ticks set, the trackbar will place a tick at every increment. The same data exchange considerations applied to the previous trackbar applies to this trackbar. Add the following code in the dialog class DoDataExchange() member function inside the block for the if statement you added in the previous step:
CSliderCtrl* pSlide2 = (CSliderCtrl*) GetDlgItem(IDC_TRACKBAR2);
m_nTrackbar2 = pSlide2->GetPos();
Listing 26.
Use the dialog editor to set the Point property of both trackbars to Bottom/Right. Select Right for the Align Text property of both the IDC_STATIC_TRACK1 and IDC_STATIC_TRACK2 static controls.
Figure 69: Modifying the Slider properties.
Figure 70: Modifying static text properties.
Continue on next module...part 5.
Further reading and digging:
MSDN MFC 9.0 class library online documentation - latest version.
DCOM at MSDN.
COM+ at MSDN.
COM at MSDN.
Unicode and Multi-byte character set: Story and program examples.