Enhancing the Ex07a Application
The Ex07a application requires little coding for a lot of functionality. Now we'll make a new version of the program that uses some hand-coding to add extra features. We'll eliminate Ex07a's rude habit of dumping the user in response to a press of the Enter key, and we'll hook up the scroll bar controls.
Taking Control of the OnOK Exit
In the original Ex07a application, the CDialog::OnOK virtual function handles the OK button, which triggers data exchange and the exit from the dialog box. Pressing the Enter key happens to have the same effect, and that might or might not be what you want. If the user presses Enter while in the Name edit control, for example, the dialog box closes immediately.What's going on here? When the user presses Enter, Windows looks to see which button has the input focus, as indicated on the screen by a dotted rectangle. If no button has the focus, Windows looks for the default button that the program or the resource specifies. (The default button has a thicker border.) If the dialog box has no default button, the virtual OnOK function is called, even if the dialog box does not contain an OK button.You can disable the Enter key by writing a do-nothing CEx07aDialog:: OnOK function and adding the exit code to a new function that responds to clicking the OK button. Here are the steps:
"Map" the IDOK button to the virtual OnOK function. In Class View, select the CEx07aDialog class. At the top of the Properties window, click the Overrides button to get the list of overridden functions. Click OnOK from the function list, click the down arrow, and click <Add> OnOK. This action generates the prototype and skeleton for OnOK. Leave the OnOK function as is for now.
Use the dialog editor to change the OK button ID. Display the IDD_DIALOG1 resource and select the OK button. In the Properties window, change its ID from IDOK to IDC_OK, and then set the Default Button property to False.
Create a member function named OnClickedOk. In Class View, select the CEx07aDialog class. Click the Events button at the top of the Properties window. Expand the IDC_OK item, select the BN_CLICKED message, and then click <Add> OnBnClickedOk to add the OnBnClicked message handler for the newly renamed control IDC_OK.
Edit the body of the OnClickedOk function in

void CEx07aDialog::OnClickedOk()
{
TRACE("CEx07aDialog::OnClickedOk\n");
CDialog::OnOK();
}
Edit the original OnOK function in

void CEx07aDialog::OnOK()
{
// dummy OnOK function -- do NOT call CDialog::OnOK()
TRACE("CEx07aDialog::OnOK\n");
}
Build and test the application.Try pressing the Enter key now. Nothing should happen, but TRACE output should appear in the Output window. Clicking the OK button should exit the dialog box as before, however.
OnCancel Processing
Just as pressing the Enter key triggers a call to OnOK, pressing the Esc key triggers a call to OnCancel, which results in an exit from the dialog box with a DoModal return code of IDCANCEL. Ex07a does no special processing for IDCANCEL; therefore, pressing the Esc key (or clicking the Close button) closes the dialog box. You can circumvent this process by substituting a dummy OnCancel function, following approximately the same procedure you used for the OK button.
Hooking Up the Scroll Bar Controls
The dialog editor allows you to include scroll bar controls in your dialog box, and the Add Member Variable Wizard lets you add integer data members. You must add code to make the Loyalty and Reliability scroll bars work.Scroll bar controls have position and range values that can be read and written. If you set the range to (0, 100), for example, a corresponding data member with a value of 50 will position the scroll box at the center of the bar. (The function CScrollBar::SetScrollPos also sets the scroll box position.) The scroll bars send the WM_HSCROLL and WM_VSCROLL messages to the dialog box when the user drags the scroll box or clicks the arrows. The dialog box's message handlers must decode these messages and position the scroll box accordingly.Each control you've seen so far has had its own individual message handler function. Scroll bar controls are different because all horizontal scroll bars in a dialog are tied to a single WM_HSCROLL message handler and all vertical scroll bars are tied to a single WM_VSCROLL handler. Because this monster dialog contains two horizontal scroll bars, the single WM_HSCROLL message handler must figure out which scroll bar sent the scroll message.Here are the steps for adding the scroll bar logic to Ex07a:
Add the class enum statements for the minimum and maximum scroll range. In

enum { nMin = 0 };
enum { nMax = 100 };
Edit the OnInitDialog function to initialize the scroll ranges. In the OnInitDialog function, we'll set the minimum and the maximum scroll values such that the CEx07aDialog data members represent percentage values. A value of 100 means "Set the scroll box to the extreme right"; a value of 0 means "Set the scroll box to the extreme left."Add the following code to the CEx07aDialog member function OnInitDialog in the file

CScrollBar* pSB = (CScrollBar*) GetDlgItem(IDC_LOYAL);
pSB->SetScrollRange(nMin, nMax);
pSB = (CScrollBar*) GetDlgItem(IDC_RELY);
pSB->SetScrollRange(nMin, nMax);
Add a scroll bar message handler to CEx07aDialog. Select CEx07aDialog in Class View and click the Messages button at the top of the Properties window. Select the WM_HSCROLL message, and then add the member function OnHScroll. Enter the following code shown in boldface:
void CEx07aDialog::OnHScroll(UINT nSBCode, UINT nPos,
CScrollBar* pScrollBar)
{
int nTemp1, nTemp2;
nTemp1 = pScrollBar->GetScrollPos();
switch(nSBCode) {
case SB_THUMBPOSITION:
pScrollBar->SetScrollPos(nPos);
break;
case SB_LINELEFT: // left arrow button
nTemp2 = (nMax - nMin) / 10;
if ((nTemp1 - nTemp2) > nMin) {
nTemp1 -= nTemp2;
}
else {
nTemp1 = nMin;
}
pScrollBar->SetScrollPos(nTemp1);
break;
case SB_LINERIGHT: // right arrow button
nTemp2 = (nMax - nMin) / 10;
if ((nTemp1 + nTemp2) < nMax) {
nTemp1 += nTemp2;
}
else {
nTemp1 = nMax;
}
pScrollBar->SetScrollPos(nTemp1);
break;
}
}
Build and test the application.Build and run Ex07a again. Do the scroll bars work this time? The scroll boxes should "stick" after you drag them with the mouse, and they should move when you click the scroll bars' arrows. (Notice that we haven't added logic to cover the user's click on the scroll bar itself.)