Microsoft KB Archive/99198

= How To Display the Current Time in a CStatusBar Pane =

Article ID: 99198

Article Last Modified on 11/21/2006

-

APPLIES TO

 Microsoft Foundation Class Library 4.2, when used with:  Microsoft Visual C++ 1.0 Professional Edition

 Microsoft Visual C++ 1.5 Professional Edition

 Microsoft Visual C++ 1.51

 Microsoft Visual C++ 1.52 Professional Edition</li></ul>

 Microsoft Visual C++ 2.0 Professional Edition</li></ul>

 Microsoft Visual C++ 2.1</li></ul>

 Microsoft Visual C++ 4.0 Standard Edition</li></ul>

 Microsoft Visual C++ 5.0 Standard Edition</li></ul>

 Microsoft Visual C++ 6.0 Service Pack 5</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q99198

<div class="summary_section">

SUMMARY
The text below describes a process by which a MFC AppWizard application can be designed to display the current time on its status bar.

Perform the following five steps:

<ol> Use App Studio, or the Resource View in Visual C++ versions later than 4.0, to edit the application's string tables. Add a new string in the segment that defines ID_INDICATOR_NUM and so on; for example, create a new string with the ID ID_INDICATOR_TIME. Specify a caption like 00:00. The Status Bar uses the specified initial value to calculate the size of the pane. An application can dynamically change the size of the pane using the CStatusBar::SetPaneInfo function. With Visual C++ versions prior to 4.0, close App Studio to save the .RC file. With Visual C++ version 4.0 or later, use the File menu to Save and Close the string table resource.</li> Edit the MAINFRM.CPP file. The CStatusBar object builds the status bar using the data in the indicators[] array in sequential order. Insert the ID_INDICATOR_TIME indicator into the array at the desired position.

If you compiled the program at this stage, you would see a new pane in the status bar but it would not contain any text.</li>  Edit the message map for the CMainFrame object to add the following line (add the line outside the AFX_MSG_MAP comments): ON_UPDATE_COMMAND_UI(ID_INDICATOR_TIME, OnUpdateTime) Because ID_INDICATOR_TIME is an ID, and not an object, you cannot use Class Wizard to make this addition. </li>  Edit the MAINFRM.CPP file and create a function similar to the following: void CMainFrame::OnUpdateTime(CCmdUI *pCmdUI) {        CTime t = CTime::GetCurrentTime; char szTime[6]; int nHour = t.GetHour; int nMinute = t.GetMinute;

// Base Hours on 12 instead of 24 if (nHour > 12) nHour = nHour - 12;

wsprintf(szTime, &quot;%i:%02i&quot;, nHour, nMinute);

// Now set the text of the pane. m_wndStatusBar.SetPaneText(              m_wndStatusBar.CommandToIndex(ID_INDICATOR_TIME),               LPCSTR(szTime)); pCmdUI->Enable; } The application calls this function once when it has idle time. Each time the application empties its message queue, it sends a WM_IDLEUPDATECMDUI message (new idle time). For more information on idle time, please refer to Technical Note #24 in the MFC Tech Notes help file or to the documentation of the CWinApp::OnIdle function in the &quot;Class Library Reference, Volume 1.&quot; The application must call the pCmdUI->Enable function to enable the user-interface item for this command. If the application doesn't enable the user-interface item, the pane appears in the status bar, but it does not display any text.

If you compiled the program at this point, the status bar would display the current time in one of its panes. However, one implementation problem would remain. Because the application calls the UI Command Handler only once each time the system becomes idle, what happens if the application runs and the user does not interact with it? The application does not reset the time until it receives one or more messages and empties its queue (new idle time). The code in Step 5 addresses this situation. </li>  Even though there are several methods to accomplish this, the simplest method takes advantage of the fact that the application calls the UI Command Handler only once when the application's message queue is emptied. Add the following statement to the CMainFrame::OnCreate member function: m_wndStatusBar.SetTimer(1, 1000, NULL); The CWnd::SetTimer event generates a message in the application's queue every second. Even if the user does not interact with the application, the queue empties after processing the timer event, new idle time is available, and the application updates the time pane in its status bar. Be sure to call KillTimer when the window is destroyed. </li></ol>

<div class="moreinformation_section">

MORE INFORMATION
When a modal dialog box is up, the dialog manager manages the application's message queue. Since the dialog manager's message loop does not include calls to do Idle time processing, the above mentioned OnUpdateTime function never gets called. If you would like to use a modal dialog, yet still have the time on the status bar updated, you will have to avoid using the message queue.

<ol> Start with the code above.</li> <li> In mainfrm.h, add the following to the CMainFrame class definition. UINT m_nIDTimer; static VOID __export CALLBACK TimerProc(HWND hwnd, UINT uMsg,       UINT uIDEvent, DWORD dwTime); NOTE: In Win32, the &quot;__export&quot; keyword is obsolete and will cause the compiler to generate a C4236 warnings in Visual C++ version 4.0 or later. To correct, simply remove the keyword. </li> <li> In mainfrm.cpp, change the SetTimer call in CMainFrame::OnCreate to: m_nIDTimer = ::SetTimer(NULL, 0, 1000, TimerProc); </li> <li> Add a timer procedure: VOID __export CALLBACK CMainFrame::TimerProc(HWND hwnd, UINT uMsg,        UINT uIDEvent, DWORD dwTime) {        CMainFrame *pMainWnd = (CMainFrame *)AfxGetApp->m_pMainWnd; ASSERT(uIDEvent == pMainWnd->m_nIDTimer);

CCmdUI cui; cui.m_nID = ID_INDICATOR_TIME; cui.m_nIndex = 4; cui.m_pMenu = NULL; cui.m_pOther = &pMainWnd->m_wndStatusBar;

pMainWnd->OnUpdateTime(&cui); }                       </li> <li> In the destructor, use: ::KillTimer(NULL, m_nIDTimer); </li></ol>

Keywords: kbdatetime kbhowto kbmfcctrlbar kbstatbar kbuidesign KB99198

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.