Chapter 18: Progress-Based Controls Visual C++ and MFC Fundamentals 586 © FunctionX, Inc. 4. Add another Vertical Scroll Bar to the right of the erxisting one Change its ID to IDC_SCROLL_GREEN Add a Control Variable for the new scroll bar and name it m_ScrollGreen 5. Add a Static Text under the new scroll bar CChange its ID to IDC_VAL_GREEN Add a CString Value Variable for the new label and name it m_ValGreen 6. Add one more scroll bar control to the right of the others Change its ID to IDC_SCROLL_BLUE Add a Control Variable for it and name it m_ScrollBlue 7. Add a Static Text under the new scroll bar CChange its ID to IDC_VAL_BLUE Add a CString Value Variable for the new label and name it m_ValBlue 8. Save All 18.4.4 ScrollBar Properties There are two forms of the scroll bars. The horizontal scroll bar allows the user to scroll in the left and right directions. The vertical scroll bar allows scrolling up and down. Visual C++ allows you to visual select the desired one and add to it a host. If you are programmaticall creating the control, you can add the SBS_HORZ style to get horizontal scroll bar. This is also the default, meaning that it you do not specify the orientation, the scroll bar would be horizontal. If you want a vertical scroll bar instead, add the SBS_VERT style: BOOL CScrollingDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here Scroller->Create(WS_CHILD | WS_VISIBLE | SBS_VERT, CRect(200, 15, 320, 148), this, 0x16); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE Visual C++ and MFC Fundamentals Chapter 18: Progress-Based Controls © FunctionX, Inc. 587 } As mentioned already, you can resize a scroll bar control to have the dimensions of your choice. If you are programmatically creating the control, it would assume the size allocated during design or the nWidth and the nHeight members of the rect argument of the Create() method. Internally, the operating system has a default width for a vertical scroll bar and a default height for a horizontal scroll bar. If you prefer to use those default values, you have various options. If you are visually creating the scroll bar, change the value of the Align property. Imagine you resize the scroll bar as follows: If you set the Align property to Top/Left for a horizontal scroll bar, it would keep its top border and bring its border up to get the default height set by the operating system: If you select this same value for a vertical scroll bar, it would keep its left border and narrow the control to assume the default width of the operating system: Chapter 18: Progress-Based Controls Visual C++ and MFC Fundamentals 588 © FunctionX, Inc. In the same way, you can set the Align property to a Bottom/Right value to keep the bottom border for a horizontal scroll bar or the right border for a vertical scroll bar and resize them to the default height or width respectively. If you are programmaticall creating the control, to resize a horizontal scroll bar to assume the default height known to the operating system combine the SBS_HORZ with the SBS_TOPALIGN and possibly the SBS_BOTTOMALIGN values to its style. On the other hand, to get the default width of a vertical scroll bar, besides the SBS_VERT style, add the SBS_LEFTALIGN and the SBS_RIGHTALIGN values: BOOL CScrollingDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here Scroller->Create(WS_CHILD | WS_VISIBLE | SBS_VERT | SBS_LEFTALIGN | SBS_RIGHTALIGN, CRect(200, 15, 320, 148), this, 0x16); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } We mentioned already that the operating system keeps a default height for a horizontal scroll bar and a default width for a vertical scroll bar. To get these default values and apply them to your scroll bar control, call the GetSystemMetrics() function and pass it either the SM_CXVSCROLL or the SM_CXHSCROLL value. Then add the value to the x member of the rect argument for the Create() method. Here is an example: Visual C++ and MFC Fundamentals Chapter 18: Progress-Based Controls © FunctionX, Inc. 589 BOOL CScrollingDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here int ButtonWidth = GetSystemMetrics(SM_CXHSCROLL); Scroller->Create(WS_CHILD | WS_VISIBLE | SBS_VERT, CRect(200, 15, 200+ButtonWidth, 148), this, 0x16); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 18.4.5 Scroll Bar Methods A scroll bar is based on the CScrollBar class. We already that, to programatically create this control, you can declare a pointer to its class and initialize it using its Create() method. Since a scroll bar is a value-range control, you must specify its minimum and maximum values from which extremes the thumb can be navigated. To set the range of values of a scroll bar, you can call the CScrollBar::SetScrollRange() method. Its syntax is: void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE); The nMinPos argument specifies the minimum value of the control. The nMaxPos argument is the maximum value of the range. The difference between nMaxPos and nMinPos must not be greater than 32,767. When the values have been changed, you may want to refresh the control to reflect the change. This is the default bahavior. If for some reason you do not want the control to be redrawn, pass a third argument as FALSE. Here is an example: BOOL CScrollingDlg::OnInitDialog() { CDialog::OnInitDialog(); m_Scroller.SetScrollRange(8, 120); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } If the range of a values has already been set for a scroll bar and you want to get its minimum and its maximum possible values, call the CScrollBar::GetScrollRange() method. Its syntax is: void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const; This method returns two values, lpMinPos and lpMaxPos. Here is an example: void CScrollingDlg::OnBtnInfo() { Chapter 18: Progress-Based Controls Visual C++ and MFC Fundamentals 590 © FunctionX, Inc. // TODO: Add your control notification handler code here int Min, Max; m_Scroller.GetScrollRange(&Min, &Max); m_MinValue.Format("%d", Min); m_MaxValue.Format("%d", Max); UpdateData(FALSE); } Once the control has been created and it has the minimum and maximum values set, its thumb would appear in the minimum position. If you want it to assume another position within the range, call the CScrollBar::SetScrollPos() method. Its syntax is: int SetScrollPos(int nPos, BOOL bRedraw = TRUE); The nPos argument hold the value of the new position for the thumb. This value must be between the nMinPos and the nMaxPos values of the SetScrollRange() method. You may need the control to be redraw after this value has been set to reflect the new change, which is the default behavior. If you do not want the control the control to be redrawn, pass the FALSE value as a second argument. Here is an example: BOOL CScrollingDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here Scroller->Create(WS_CHILD | WS_VISIBLE | SBS_VERT | SBS_LEFTALIGN | SBS_RIGHTALIGN, CRect(200, 15, 240, 148), this, 0x16); Scroller->SetScrollRange(12, 248); Scroller->SetScrollPos(165); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } Visual C++ and MFC Fundamentals Chapter 18: Progress-Based Controls © FunctionX, Inc. 591 If the position of the thumb on a scroll bar control has changed, which happens while the user is scrolling,, you can get the current position of the thumb by calling the CScrollBar::GetScrollPos() method. Its syntax is: int GetScrollPos() const; This method returns the position of the thumb on the scroll bar. To set the minimum and the maximum values of a scroll bar, as well as the initial position of the thumb, you can call the CScrollBar::SetScrollInfo() method. Its syntax is: BOOL SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE); The new values to be passed to this method are stored in a SCROLLINFO variable. Therefore, you should first build that variable. The SCROLLINFO structure is defined as follows: typedef struct tagSCROLLINFO { UINT cbSize; UINT fMask; int nMin; int nMax; UINT nPage; int nPos; int nTrackPos; } SCROLLINFO, *LPSCROLLINFO; typedef SCROLLINFO CONST *LPCSCROLLINFO; The cbSize member variable is the size of the structure in bytes. The fMask value specifies the type of value that you want to set. The possible values of fMask are: Value Description SIF_RANGE Used to set only the minimum and the maximum values SIF_POS Used to set only the initial position of the scroll thumb SIF_PAGE Used to set the page size to scroll when using the control SIF_DISABLENOSCROLL Used to disable the scroll bar SIF_ALL Used to perform all allowed operations The nMin value is used to set the minimum value of the scroll bar while nMax specifies its maximum value. The nPage value holds the value of the page scrolling. The nPos is used to set the initial position of the thumb. The nTrackPos member variable must be ignored if you are setting values for the scroll bar. Here is an example: BOOL CScrollingDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here SCROLLINFO ScrInfo; ScrInfo.cbSize = sizeof(SCROLLINFO); ScrInfo.fMask = SIF_ALL; ScrInfo.nMin = 25; Chapter 18: Progress-Based Controls Visual C++ and MFC Fundamentals 592 © FunctionX, Inc. ScrInfo.nMax = 368; ScrInfo.nPage = 2; ScrInfo.nPos = 186; m_Scroller.SetScrollInfo(&ScrInfo); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } If a scroll bar has already been initialized, even it was not initialized using the SetScrollInfo() method, to get information about its values, you can call the CScrollBar::GetScrollInfo(). Its syntax is: BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo, UINT nMask); This method returns a SCROLLINFO value that holds the values of the scroll bar. The possible values of the SCROLLINFO::fMask member variable are: Value Description SIF_RANGE Used to retrieve the minimum and the maximum values SIF_POS Used to retrieves the current position of the scroll thumb. The thumb should not be scrolling when the GetScrollInfo() method is called to get the value associated with this mask SIF_PAGE Used to retrieve the page size to scroll when using the control SIF_TRACKPOS Used to retrieve the current position of the thumb while the user is scrolling SIF_ALL Used to retrieve all above values Practical Learning: Using Scroll Bars 1. Using the OnInitDialog() event, set the range of each scroll bar to (0, 255) and set their initial values to 192 BOOL CPreviewerDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_ScrollRed.SetScrollRange(0, 255); m_ScrollRed.SetScrollPos(63); m_ScrollGreen.SetScrollRange(0, 255); m_ScrollGreen.SetScrollPos(63); m_ScrollBlue.SetScrollRange(0, 255); m_ScrollBlue.SetScrollPos(63); return TRUE; // return TRUE unless you set the focus to a control } Visual C++ and MFC Fundamentals Chapter 18: Progress-Based Controls © FunctionX, Inc. 593 2. Save All 18.4.6 Scroll Bar Events As described already, to use a scroll bar, the user clicks either one of its buttons, a thumb or the scrolling region. When the user clicks, the scroll bar sends a message to its parent or host, which can be a view, a dialog box, or a form. If the scroll bar is horizontal, the message sent is WM_HSCROLL, which fires an OnHScroll() event. The CWnd class, as the parent of all MFC Windows controls and views, carries this event and makes it available to the child classes (and controls) that can perform the scrolling. The syntax of the OnHScroll() event is: afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); The nSBCode argument is the type of scrolling that is being performed. Its possible values are: Value Description Role SB_THUMBTRACK The thumb is being dragged to a specific position SB_LEFT The thumb has been positioned to the minimum value of the scroll bar, to the extreme left. Used to position the thumb to the lowest value of the range SB_LINELEFT The thumb is scrolling to the left one, character or column at a time Used to decrease the position of the thumb, usually by subtracting 1 to the current value, unless the thumb is already positioned there SB_PAGELEFT The thumb is scrolling to the left, one page at a time Refers to the page size of the SCROLLINFO value to decrease the current position by one page SB_PAGERIGHT The thumb is scrolling to the right, one page at a time Refers to the page size of the SCROLLINFO value to increase the current position by one page SB_LINERIGHT The thumb is scrolling to the right one, character or column at a time Used to increase the position of the thumb, usually by adding 1, unless the thumb is already positioned there SB_RIGHT The thumb has been positioned to the maximum value of the scroll bar, to the extreme right Used to position the thumb to the highest value of the range, unless the thumb is already positioned there SB_THUMBPOSITION Absolute postion SB_ENDSCROLL End Scroll Used to determine the end of the scrolling The nPos argument is used in connection with the SB_THUMBTRACK and the SB_THUMBPOSITION values of the nSBCode argument. The value of nPos specifies how much scrolling should be done. The pScrollBar argument can be used to identify the particular scroll bar control needs to be dealt with on this OnHScroll() event. If your scroll bar control is vertical, when the user clicks it, it sends a WM_VSCROLL message which fires the OnVScroll() event. Its syntax is: afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); Chapter 18: Progress-Based Controls Visual C++ and MFC Fundamentals 594 © FunctionX, Inc. The nSBCode argument is the type of scrolling that is being performed. Its possible values are: Value Description Role SB_THUMBTRACK The thumb is being dragged to a specific position SB_UP The thumb has been positioned to the maximum value of the scroll bar, to the extreme right Used to position the thumb to the highest value of the range, unless the thumb is already positioned there SB_LINEUP The thumb is scrolling up, one line at a time Used to increase the position of the thumb, usually by adding 1, unless the thumb is already positioned there SB_PAGEUP The thumb is scrolling up, one page at a time Refers to the page size of the SCROLLINFO value to increase the current position by one page SB_PAGEDOWN The thumb is scrolling to the bottom, one page at a time Refers to the page size of the SCROLLINFO value to decrease the current position by one page SB_LINEDOWN The thumb is scrolling to the bottom, one line at a time Used to decrease the position of the thumb, usually by subtracting 1 to the current value, unless the thumb is already positioned there SB_BOTTOM The thumb has been positioned to the minimum value of the scroll bar, to the bottom side of the scroll bar Used to position the thumb to the lowest value of the range SB_THUMBPOSITION Absolute postion SB_ENDSCROLL End Scroll Used to determine the end of the scrolling The nPos argument is used in connection with the SB_THUMBTRACK and the SB_THUMBPOSITION values of the nSBCode argument. The value of nPos specifies how much scrolling should be done. The pScrollBar argument can be used to identify the particular scroll bar control needs to be dealt with on this OnHScroll() event. Practical Learning: Using the Scroll Bar Events 1. Generate the WM_VSCROLL message of the dialog box and implement it as follows: void CPreviewerDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default int CurPos = pScrollBar->GetScrollPos(); switch (nSBCode) { case SB_TOP: CurPos = 0; break; case SB_LINEUP: if (CurPos > 0) Visual C++ and MFC Fundamentals Chapter 18: Progress-Based Controls © FunctionX, Inc. 595 CurPos ; break; case SB_LINEDOWN: if (CurPos < 255) CurPos++; break; case SB_BOTTOM: CurPos = 255; break; case SB_ENDSCROLL: break; case SB_THUMBPOSITION: CurPos = nPos; break; case SB_THUMBTRACK: CurPos = nPos; break; } // Set the new position of the thumb (scroll box). pScrollBar->SetScrollPos(CurPos); // Update each color based on the positions of the scroll bar controls ColorRed = 255 - m_ScrollRed.GetScrollPos(); ColorGreen = 255 - m_ScrollGreen.GetScrollPos(); ColorBlue = 255 - m_ScrollBlue.GetScrollPos(); CDialog::OnVScroll(nSBCode, nPos, pScrollBar); } 2. Create a timer in the OnInitDialog() event as follows: SetTimer(1, 40, NULL); return TRUE; // return TRUE unless you set the focus to a control } 3. Generate a WM_TIMER message for the dialog box and implement it as follows: void CPreviewerDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default PaintPreviewArea(); CDialog::OnTimer(nIDEvent); } 4. Test the application [...]... the Value property causes the Flat Scroll Bar to fire the Change() event 598 © FunctionX, Inc Visual C++ and MFC Fundamentals Chapter 20: List-Based Controls Chapter 19: Selection-Based Controls ? ? © FunctionX, Inc Radio Buttons Check Boxes 599 Chapter 20: List-Based Controls Visual C++ and MFC Fundamentals 19. 1 Radio Buttons 19. 1.1 Introduction A radio button is a control that appears as a (proportionately...Chapter 18: Progress-Based Controls 5 Visual C++ and MFC Fundamentals Close it and return to MSVC 18.5 Flat Scroll Bars 18.5.1 Overview Besides the Controls toolbox’ regular scroll bar controls, the Win32 and the MFC libraries provide a more elaborate and friendlier object called the flat scroll bar This control provides the same functionality and and features as the above scroll bars but tends... Radio Button group box and click on the upper and click inside the Flavor © FunctionX, Inc Visual C++ and MFC Fundamentals Chapter 20: List-Based Controls 4 Change its Caption to &Vanilla and change its ID to IDC_FLAVORS 5 Complete the design of the dialog box as follows (when adding the radio buttons, start with the Vanilla and add those under it Then add the Container group box and add its radio buttons... IDB_CUP 7 In the same way, import the cone.bmp picture and change its ID to IDB_CONE 8 Import the bowl.bmp picture and change its ID to IDB_BOWL 9 Add a Picture control IDC_PICTURE © FunctionX, Inc to the right side of the dialog box and change its ID to 603 Chapter 20: List-Based Controls Visual C++ and MFC Fundamentals 10 Set its Type to Bitmap and, in its Image combo box, select IDB_CUP 11 Set its... for the IDC_FLAVORS radio button and name it m_Flavors 2 In the same way, add a Control variable for the IDC_CONTAINER, IDC_INGREDIENT, and IDC_SCOOPS named m_ Container, m_Ingredient, and m_Scoops respectively 3 Add a CString value variable for the IDC_PRICE edit control and name it m_Price © FunctionX, Inc 6 09 Chapter 20: List-Based Controls 4 Visual C++ and MFC Fundamentals When the clerk is about... Text value to True © FunctionX, Inc Visual C++ and MFC Fundamentals 5 Execute the application to test the radio buttons 6 Chapter 20: List-Based Controls Close the dialog box and return to MSVC 19. 1.4 Radio Buttons Methods As a Windows control, the radio button is based on the CButton class which, like all other constrols, is based on CWnd As far as the Win32 and the MFC libraries are concerned, a radio... Enter 7 600 Start Microsoft Visual Studio or Visual C++ if necessary Open the Clarksville Ice Scream1 application If you did not create, then create a Single Document Interface application named Clarksville Ice Scream1 Display the menu editor and change the caption of the first menu item under File from &New\tCtrl+N to &New Order…\tCtrl+N © FunctionX, Inc Visual C++ and MFC Fundamentals Chapter 20: List-Based... Scroll Bar Control 596 © FunctionX, Inc Visual C++ and MFC Fundamentals Chapter 18: Progress-Based Controls When a Microsoft Flat Scroll Bar control has been added to a parent window, it appears flat, its buttons and its thumb have no borders This display is controlled by the Appearance property whose default value is 1 – fsbFlat With this value, a simple line is drawn around each button and the central... InvalidateRect(&PictArea); 8 Execute the application and test the Container radio buttons 9 To process an order, add a new Member Function to the CIceScreamOrderDlg class Set its type as void and its name as ProcessOrder 10 Implement the method as follows: // This is the central function that the other controls will refer to © FunctionX, Inc 615 Chapter 20: List-Based Controls Visual C++ and MFC Fundamentals void CIceScreamOrderDlg::ProcessOrder(void)... Text = True Left Text = True Left Text = True Change the designs of the IDR_MAINFRAME icon as follows: 6 19 Chapter 20: List-Based Controls 5 Visual C++ and MFC Fundamentals Save All 19. 2.2 Check Box Properties To provide a check box to an application, on the Controls toolbox, click the Check Box button and click the desired area on the dialog box or form If you require more than one check box, you can . to fire the Change() event. Visual C++ and MFC Fundamentals Chapter 20: List-Based Controls © FunctionX, Inc. 599 Chapter 19: Selection-Based Controls ?. Add your command handler code here CIceScreamOrderDlg Dlg; Dlg.DoModal(); } 11. Test the application and return to MSVC Chapter 20: List-Based Controls Visual C++ and MFC Fundamentals . returns two values, lpMinPos and lpMaxPos. Here is an example: void CScrollingDlg::OnBtnInfo() { Chapter 18: Progress-Based Controls Visual C++ and MFC Fundamentals 590 © FunctionX, Inc.