Estimated  time to complete this lab: 45 minutes
To  complete the exercises in this lab, you must have the required software. For  detailed information about the labs and setup for the labs, see Labs in this  course.
Objectives
After  completing this lab, you will be able to:
®  Add  a pane to a status bar.
®  Provide  a handler to update the displayed text.
Prerequisites
There  are no prerequisites for this lab.
Exercise
The  following exercise provides practice with the concepts and techniques covered  in this chapter:
®  Exercise  1: Implementing a Time Pane
In  this exercise, you will add a new pane to the status bar and set its text to  the current time. You will also add a command handler to provide updates to the  status bar. 
Create  a simple SDI application saved as TimeStamp.
In  this exercise, you will add a new pane to the status bar and set its text to  the current time. Use an UPDATE_COMMAND_UI handler to provide updates to the  status bar.
CStatusBar includes support for adding panes to the status bar. The framework stores pane  identifier information in an array with the leftmost pane at position 0 in the  array. When you create a status bar, you use an array of pane IDs that the  framework associates with the corresponding panes. You can then either use the  pane ID or the array index to access a pane.
By  default, the first pane is "elastic": It takes up the status bar  length not used by the other panes, so that the other panes are right-aligned.
If  you examine CMainFrame::On Create, you can find the creation code for  the status bar:
if  (!m_wndStatusBar.Create(this) ||
       !m_wndStatusBar.SetIndicators(indicators,
                   sizeof(indicators)/sizeof(UINT)))
In  the code above, CStatusBar::SetIndicators uses the strings associated  with the pane IDs in the indicators array to size and initialize the text that  appears in the panes. To add a pane, you must create a new identifier for the  pane and then add the identifier for it to the indicator array.
 Add a pane to the  status bar
Every  status-bar pane is associated with an ID. To create an ID for the new pane, you  will add a new ID using a dummy menu. A dummy menu is a menu resource that is  used to store IDs that are used in your application, but that are not directly  used by a menu. Another reason for using a dummy menu for creating an ID is  that ClassWizard can be used to add handlers for the ID.
      1.   In ResourceView,  right-click the menu resource and insert a new menu.
     2.   Right-click the new  top-level menu item and select Properties. Select the Keep Visible button (pushpin) in the Properties dialog box to keep the dialog box on  top. Enter "DummyMenu" for the caption string.
     3.   Click on the new  drop-down menu item to select it. Set the ID of the menu to ID_INDICATOR_TIME.  Set the caption to some value that will remind you what the ID is for, such as  ID INDICATOR PANE.
     4.   Set the prompt value  to HH:MM AM. This value will determine the size of the pane as well as its  initial value.
     5.   Open MainFrm.cpp.
     6.   Add ID_INDICATOR_TIME  to the indicators array. Save MainFrm.cpp. The array follows:
static  UINT indicators[] =
{
   ID_SEPARATOR,           // status line indicator
   ID_INDICATOR_CAPS,
   ID_INDICATOR_NUM,
   ID_INDICATOR_SCRL,
   ID_INDICATOR_TIME,
};
Update the time pane
Whenever  the framework finishes processing all the pending messages for the MainFrame window, it sends itself a WM_IDLEUPDATECMDUI message. This message is one of  the generators of the UPDATE_COMMAND_UI message that is sent by the system to CCmdTarget-derived  objects such as CStatusBar. Use this message to force the update of the  time pane.
      1.   Click ClassWizard on the View menu, or press CTRL+W. If  a dialog box appears asking if you want to add a new class, click Cancel.
     2.   Click the Message  Maps tab and select CMainFrame as the class name. In the Object IDs list box, select the new message identifier, ID_INDICATOR_TIME. Select  UPDATE_COMMAND_UI as the message and add a function for this message.  ClassWizard will prompt you for the function name. Rename the function to  OnUpdateTime.
     3.   Click Edit Code.  ClassWizard will place you in the body of the new handler. Code the OnUpdateTime function by creating a CTime object and initializing it to the current  system time as follows:
CTime        time =  CTime::GetCurrentTime();
     4.   Use CTime::Format to format the time in HH:MM AM format and assign that string to a new CString.
CString  sTime = time.Format ("%I:%M %p");
    5.   Set the text of the  pane to the time:
pCmdUI->SetText(sTime);
     6.   Save MainFrm.cpp. The  complete function follows:
void  CMainFrame::OnUpdateTime(CCmdUI *pCmdUI)
{
   CTime   time =  CTime::GetCurrentTime();
   CString sTime = time.Format  ("%I:%M %p");
   // Now set the text of the  pane.
  pCmdUI->SetText(sTime);
}
     7.   Build and run the  TimeStamp application. You will see the current time displayed in the fifth  pane of the status bar as shown in the following illustration:
 Use a timer to cause  background updating
The  TimeStamp application will show the time and update itself as long as there are  messages for its frame window to process. However, TimeStamp is little more  than a clock in a status bar. Without messages, a WM_IDLEUPDATECMDUI message is  not sent to update the time pane. In this section, you can set up a timer for  TimeStamp to process and update time.
      1.   Open MainFrm.cpp. At  the end of the OnCreate function and before the return statement,  set a timer that will send a message once a second. The ID of this timer is  irrelevant and can therefore be any value; there is no callback function.
SetTimer(1234,1000,  NULL);
      2.   Click ClassWizard on the View menu, or press CTRL+W.
      3.   In the CMainFrame class, add a function for WM_TIMER. Even though you cannot add functionality to  the default behavior, you must map the message through a function for the message  pump to empty the queue and send the UPDATE_COMMAND_UI message. You can  leave the OnTimer handler as provided or you can comment out the call to  the default function.
      4.   Save MainFrm.cpp.  Build and run TimeStamp.exe. You will notice that the timer pane updates  properly whether or not TimeStamp.exe is in the foreground or background and  whether or not there has been activity in the window.
The  completed code for this exercise is in \Labs\Ch08\Lab04\Ex01
No comments:
Post a Comment