"Ready" prompt replacement

This sample was contributed by Mark Findlay.

Replacing the "Ready" message at run time with custom text.

The following will allow you to specify a replacement string to appear in the status bar any time the customary "Ready" string would normally appear.

The difference between this and simply using the AFX_IDS_IDLEMESSAGE is that this technique allows you to set the text to appear in place of the "Ready" prompt AT RUN TIME.

With this, you could for example, read a database, then display the number of records read of a total record count, or display the time it took to read the table, or the table name, etc.

With this technique you can change the text as much as you like, any time you like during the course of program execution.

Thanks to Steve McAdams for his help in pointing me to the right place to get things working.

We will create 2 functions in the CmainFrame cpp file. StatusBarMessage() and OnSetMessageString(). OnSetMessageString() is an overridden function of CframeWnd and is copied almost verbatim from the WINFRM.CPP CFrameWnd::OnSetMessageString. The only change is to display our own message string.

Our changes will take place in the CMainFrame class.

 

Step1: Create a variable for the status bar text

In MainFrm.h create a CString variable that will contain the text to display

	CString m_sStatusBarString;

Step2: Add the function prototypes

Add the prototype in the MainFrm.h file for the OnSetMessageString() function:

	//{{AFX_MSG(CMainFrame)
	.
	afx_msg LRESULT OnSetMessageString(WPARAM wParam, LPARAM lParam);
	.
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

Then add the prototype in the MainFrm.h file for the StatusBarMessage () function. Note that this prototype
is NOT defined within the AFX_MSG macros.

void StatusBarMessage(TCHAR * fmt,...);

Step3: Add an include to MainFrm.cpp

Add an include for afxpriv.h to the MainFrm.cpp file. This is needed for the WM_SETMESSAGESTRING definition
we will use in Step4.

#include <afxpriv.h>

Step4: Add a message handler to MainFrm.cpp

Add the OnSetMessageString() handler to the MainFrm.cpp file

	BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
		//{{AFX_MSG_MAP(CMainFrame)
		.
		ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
		.
		//}}AFX_MSG_MAP
	END_MESSAGE_MAP()

Step5: Add the functions to MainFrm.cpp

Create the OnSetMessageString() and StatusBarMessage() functions:

//*************************************************************************
// OnSetMessageString
//*************************************************************************
LRESULT CMainFrame::OnSetMessageString(WPARAM wParam, LPARAM lParam)
{
	UINT nIDLast = m_nIDLastMessage;
	m_nFlags &= ~WF_NOPOPMSG;

	CWnd* pMessageBar = GetMessageBar();
	if (pMessageBar != NULL)
	{
		CString sMsg;
		CString strMessage;

		// set the message bar text
		if (lParam != 0)
		{
			ASSERT(wParam == 0);    // can't have both an ID and a string
            			m_sStatusBarString = (LPCTSTR)lParam;
            			sMsg = m_sStatusBarString;
		}
		else if (wParam != 0)
		{
			// map SC_CLOSE to PREVIEW_CLOSE when in print preview mode
			if (wParam == AFX_IDS_SCCLOSE && m_lpfnCloseProc != NULL)
				wParam = AFX_IDS_PREVIEW_CLOSE;

			// get message associated with the ID indicated by wParam
            			if (wParam == AFX_IDS_IDLEMESSAGE)
                				sMsg = m_sStatusBarString;
else
{
	GetMessageString(wParam, strMessage);
	sMsg = strMessage;
}
		}

		pMessageBar->SetWindowText(sMsg);

		// update owner of the bar in terms of last message selected
		CFrameWnd* pFrameWnd = pMessageBar->GetParentFrame();
		if (pFrameWnd != NULL)
		{
			m_nIDLastMessage = (UINT)wParam;
			m_nIDTracking = (UINT)wParam;
		}
	}

	m_nIDLastMessage = (UINT)wParam;    	// new ID (or 0)
	m_nIDTracking = (UINT)wParam;       	// so F1 on toolbar buttons work

	return nIDLast;
}



//*************************************************************************
// StatusBarMessage
//*************************************************************************
void CMainFrame::StatusBarMessage(TCHAR * fmt,...)
{
	TCHAR buffer[256]= _T("");

	CStatusBar* pStatus = (CStatusBar*) 
		GetDescendantWindow(AFX_IDW_STATUS_BAR);

	va_list argptr;
	va_start(argptr, fmt);
	_vstprintf(buffer, fmt, argptr);
	va_end(argptr);

   	m_sStatusBarString = buffer;

    	SetMessageText((LPCTSTR)m_sStatusBarString);
    	return;
}

Step6: Use the new function

That's all there is to it. To set the status bar text use the following to invoke the CMainFrame::OnSetMessageString() function. For example, from a view class:

     CString sReplacementText = "This text will always appear in place of Ready";

    ((CMainFrame*)AfxGetMainWnd())->StatusBarMessage(sReplacementText.GetBuffer(0)); 

Last updated: 08/11/98

Comments:



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds