Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Balloon Help as a non-modal replacement for MessageBox()

, 7 Aug 2002 CPOL
Although sometimes useful, message boxes used to display information are often just annoying. This article describes a non-modal replacement.
balloonhelpr2_demo.zip
BalloonTest.exe
res
BalloonTest.ico
BalloonTest.manifest
BalloonTest.dsw
BalloonTest.dsp
balloonhelpr2_src.zip
balloonhelpr3_demo.zip
BalloonTest.ico
BalloonTest.manifest
BalloonTest.dsw
BalloonTest.dsp
BalloonTest.exe
balloonhelpr3_src.zip
balloonhelp_demo.zip
BalloonTest.exe
BalloonTest.ico
BalloonTest.manifest
BalloonTest.dsw
BalloonTest.dsp
balloonhelp_src.zip
bh-atl.zip
BalloonTest.dsp
BalloonTest.dsw
BalloonTestps.mk
BalloonTestps.def
BalloonTest.rgs
BalloonTest.ico
BalloonTest.manifest
BalloonTest.suo
wtl_balloonhelp_demo.zip
BalloonTest
BalloonTest.dsp
Release
BalloonTest.exe
res
BalloonTest.exe.manifest
BalloonTest.ico
bob.bmp
#include "stdafx.h"
#include "maindlg.h"


// ctor
CMainDlg::CMainDlg():
	m_wndLButtonDown(this,1),
	m_wndMButtonDown(this,2),
	m_wndRButtonDown(this,3)
{
}
	
//
//			GetBalloonOptions
//
DWORD CMainDlg::GetBalloonOptions()
{
	DWORD dwOptions=0;
	for(int idx=0;idx<MaxOptions;++idx)
		dwOptions|=m_OptionCtrls[idx].GetOption();
	
	return dwOptions;
}

//
//			UpdateOptions
//
void CMainDlg::UpdateOptions(DWORD dwOptions)
{
	for(int idx=0;idx<MaxOptions;++idx)
		m_OptionCtrls[idx].UpdateState(dwOptions);
}

//
//			EnableOptions
//
void CMainDlg::EnableOptions(BOOL bEnable)
{
	for(int idx=0;idx<MaxOptions;++idx)
		m_OptionCtrls[idx].Enable(bEnable);
}

//
//
//
void CMainDlg::ShowBallon(HWND hWndCenter)
{
	ATLASSERT(::IsWindow(hWndCenter));

	//
	//	title
	//
	CString strTitle;

	const int ccTitle=m_edtTitle.GetWindowTextLength()+1;
	m_edtTitle.GetWindowText(strTitle.GetBuffer(ccTitle),ccTitle);
	strTitle.ReleaseBuffer();


	//
	//	content
	//
	CString strContent;

	const int ccContent=m_edtContent.GetWindowTextLength()+1;
	m_edtContent.GetWindowText(strContent.GetBuffer(ccContent),ccContent);
	strContent.ReleaseBuffer();

	//
	// timeout
	//
	BOOL bTranslated=FALSE;
	int nTimeout=GetDlgItemInt(IDC_Timeout,&bTranslated,FALSE);
	if(!bTranslated)
		nTimeout=0;


	//
	// show ballon
	//
	CBalloonHelp* pBalloon=new CBalloonHelp;
	ATLASSERT(pBalloon);

	if(m_btnUseBitmap.GetCheck())
	{
		HBITMAP hBmp=LoadBitmap(_Module.GetResourceInstance(),MAKEINTRESOURCE(IDB_Bob));
		pBalloon->SetIcon(hBmp, RGB(255,255,255)); // bitmap, transparent color
	}
	else
	{
		//pBalloon->SetIcon(IDI_INFORMATION);

		// use the cool WTL Icon (thanks, Josh!!) with a size of 32x32, so everyone can see it :-)
		pBalloon->SetIcon(LoadIcon(_Module.GetResourceInstance(),MAKEINTRESOURCE(IDR_MAINFRAME)));
	}

	if(m_btnFollowMe.GetCheck())
	{
		pBalloon->SetFollowMe(hWndCenter,NULL);// follow center point
	}
	else
	{
		pBalloon->SetAnchorPoint(hWndCenter);
	}
	
	// gray balloon
	//pBalloon->SetBackgroundColor(CBalloonHelp::OleSysColorBits|COLOR_BTNFACE);
	//pBalloon->SetForeGroundColor(CBalloonHelp::OleSysColorBits|COLOR_BTNTEXT);

	// codeproject orange...
	//pBalloon->SetBackgroundColor(RGB(255,153,0));
	//pBalloon->SetForeGroundColor(RGB(0,0,0));
	
	pBalloon->Create(
		m_hWnd,
		strTitle,
		strContent,
		NULL,	// dont't override existing anchor point
		GetBalloonOptions()|CBalloonHelp::BODeleteThisOnClose, // delete pBalloon on close
		NULL,
		nTimeout);

	
}


//
//			OnInitDialog
//
BOOL CMainDlg::OnInitDialog(HWND, LPARAM)
{
	// center the dialog on the screen
	CenterWindow();

	// set icons
	HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
		IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
	SetIcon(hIcon, TRUE);
	HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
		IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
	SetIcon(hIconSmall, FALSE);

	
	m_OptionCtrls[ 0].Init(GetDlgItem(IDC_BOShowCloseButton),		CBalloonHelp::BOShowCloseButton);
	m_OptionCtrls[ 1].Init(GetDlgItem(IDC_BOShowInnerShadow),		CBalloonHelp::BOShowInnerShadow);
	m_OptionCtrls[ 2].Init(GetDlgItem(IDC_BOShowTopMost),			CBalloonHelp::BOShowTopMost);

	m_OptionCtrls[ 3].Init(GetDlgItem(IDC_BOCloseOnLButtonDown),	CBalloonHelp::BOCloseOnLButtonDown);
	m_OptionCtrls[ 4].Init(GetDlgItem(IDC_BOCloseOnMButtonDown),	CBalloonHelp::BOCloseOnMButtonDown);
	m_OptionCtrls[ 5].Init(GetDlgItem(IDC_BOCloseOnRButtonDown),	CBalloonHelp::BOCloseOnRButtonDown);

	m_OptionCtrls[ 6].Init(GetDlgItem(IDC_BOCloseOnLButtonUp),		CBalloonHelp::BOCloseOnLButtonUp);
	m_OptionCtrls[ 7].Init(GetDlgItem(IDC_BOCloseOnMButtonUp),		CBalloonHelp::BOCloseOnMButtonUp);
	m_OptionCtrls[ 8].Init(GetDlgItem(IDC_BOCloseOnRButtonUp),		CBalloonHelp::BOCloseOnRButtonUp);

	m_OptionCtrls[ 9].Init(GetDlgItem(IDC_BOCloseOnMouseMove),		CBalloonHelp::BOCloseOnMouseMove);
	m_OptionCtrls[10].Init(GetDlgItem(IDC_BOCloseOnKeyDown),		CBalloonHelp::BOCloseOnKeyDown);
	m_OptionCtrls[11].Init(GetDlgItem(IDC_BOCloseOnAppDeactivate),	CBalloonHelp::BOCloseOnAppDeactivate);

	m_OptionCtrls[12].Init(GetDlgItem(IDC_BODisableFadeIn),			CBalloonHelp::BODisableFadeIn);
	m_OptionCtrls[13].Init(GetDlgItem(IDC_BODisableFadeOut),		CBalloonHelp::BODisableFadeOut);

	m_btnBoDefault=GetDlgItem(IDC_BODefault);
	ATLASSERT(m_btnBoDefault.IsWindow());

	m_btnUseBitmap=GetDlgItem(IDC_UseBitmap);
	ATLASSERT(m_btnUseBitmap.IsWindow());
	m_btnUseBitmap.SetCheck(1);

	m_btnFollowMe=GetDlgItem(IDC_FollowMe);
	ATLASSERT(m_btnFollowMe.IsWindow());

	m_edtTitle=GetDlgItem(IDC_Title);
	ATLASSERT(m_edtTitle.IsWindow());
	m_edtTitle.SetWindowText(_T("<<title goes here>>"));
	
	m_edtContent=GetDlgItem(IDC_Content);
	ATLASSERT(m_edtContent.IsWindow());
	m_edtContent.SetWindowText(_T("<<content goes here>>"));

	UpdateOptions(CBalloonHelp::BODefault);

	m_wndLButtonDown.SubclassWindow(GetDlgItem(IDC_LButtonDown));
	m_wndMButtonDown.SubclassWindow(GetDlgItem(IDC_MButtonDown));
	m_wndRButtonDown.SubclassWindow(GetDlgItem(IDC_RButtonDown));

	//
	//	create and show welcome ballon
	//
	m_wndBalloon.SetIcon(LoadBitmap(_Module.GetResourceInstance(),MAKEINTRESOURCE(IDB_Bob)),RGB(255,255,255));
   
	CFontHandle FontTitle; // deleted by balloon.
	FontTitle.CreatePointFont(120, _T("Comic Sans MS"));
	m_wndBalloon.SetTitleFont(FontTitle); 
	
	CFontHandle FontContent; // deleted by balloon.
	FontContent.CreatePointFont(100, _T("Comic Sans MS"));
	m_wndBalloon.SetContentFont(FontContent); 

	CRect rcClient;
	GetClientRect(rcClient);
	ClientToScreen(rcClient);

	m_wndBalloon.SetFollowMe(m_hWnd, &rcClient.BottomRight());

	m_wndBalloon.Create(
		m_hWnd,
		_T("Hello!"), 
		_T("Welcome to the Balloon Help test app!"), 
		NULL, // already set by SetFollowMe()
		CBalloonHelp::BOShowInnerShadow|CBalloonHelp::BOShowCloseButton,
		NULL,
		10000
		);

	return TRUE;

}// OnInitDialog

//
//			OnBoDefault
//
void CMainDlg::OnBoDefaultClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl)
{
	if(m_btnBoDefault.GetCheck())
	{
		UpdateOptions(CBalloonHelp::BODefault);
		EnableOptions(FALSE);
	}
	else
	{
		EnableOptions(TRUE);
	}
}

//
//
//
void CMainDlg::OnHelp(LPHELPINFO pHelpInfo)
{
	if(NULL==pHelpInfo->hItemHandle || HELPINFO_WINDOW!=pHelpInfo->iContextType)
		return;

	const HWND hWndControl=(HWND)pHelpInfo->hItemHandle;
	
	CString strTitle;
	CString strMsg;
	switch(pHelpInfo->iCtrlId)
	{
	case IDOK:
		strTitle= _T("Close");
		strMsg	= _T("Click this button to close the program.");
		break;
	case IDC_BOCloseOnLButtonDown:
		strTitle= _T("BOCloseOnLButtonDown");
		strMsg	= _T("Closes window on WM_LBUTTONDOWN.");
		break;
	case IDC_BOCloseOnMButtonDown:
		strTitle= _T("BOCloseOnMButtonDown");
		strMsg	= _T("Closes window on WM_MBUTTONDOWN.");
		break;
	case IDC_BOCloseOnRButtonDown:
		strTitle= _T("BOCloseOnRButtonDown");
		strMsg	= _T("Closes window on WM_RBUTTONDOWN.");
		break;
	case IDC_BOCloseOnLButtonUp:
		strTitle= _T("BOCloseOnLButtonUp");
		strMsg	= _T("Closes window on WM_LBUTTONUP.");
		break;
	case IDC_BOCloseOnMButtonUp:
		strTitle= _T("BOCloseOnMButtonUp");
		strMsg	= _T("closes window on WM_MBUTTONUP.");
		break;
	case IDC_BOCloseOnRButtonUp:
		strTitle= _T("BOCloseOnRButtonUp");
		strMsg	= _T("Closes window on WM_RBUTTON_UP.");
		break;
	case IDC_BOCloseOnMouseMove:
		strTitle= _T("BOCloseOnMouseMove");
		strMsg	= _T("Closes window when user moves mouse past threshhold.");
		break;
	case IDC_BOCloseOnKeyDown:
		strTitle= _T("BOCloseOnKeyDown");
		strMsg	= _T("Closes window on the next keypress message sent to this thread.");
		break;
	case IDC_BOCloseOnAppDeactivate:
		strTitle= _T("BOCloseOnAppDeactivate");
		strMsg	= _T("Closes window when the application is being deactivated.");
		break;
	case IDC_BOShowCloseButton:
		strTitle= _T("BOShowCloseButton");
		strMsg	= _T("Shows close button in upper right.");
		break;
	case IDC_BOShowInnerShadow:
		strTitle= _T("BOShowInnerShadow");
		strMsg	= _T("Draw inner shadow in balloon.");
		break;
	case IDC_BOShowTopMost:
		strTitle= _T("BOShowTopMost");
		strMsg	= _T("Place balloon above all other windows.");
		break;
	case IDC_BODisableFadeIn:
		strTitle= _T("BODisableFadeIn");
		strMsg	= _T("Disable the fade-in effect (overrides system and user settings).");
		break;
	case IDC_BODisableFadeOut:
		strTitle= _T("BODisableFadeOut");
		strMsg	= _T("Disable the fade-out effect (overrides system and user settings).");
		break;
	case IDC_BODefault:
		strTitle= _T("BODefault");
		strMsg	= _T("Apply default options.");
		break;
	case IDC_Title:
		strTitle= _T("Title");
		strMsg	= _T("The title of the balloon.");
		break;
	case IDC_Content:
		strTitle= _T("Content");
		strMsg	= _T("The Content of the balloon.");
		break;
	case IDC_UseBitmap:
		strTitle= _T("Use Bitmap");
		strMsg	= _T("Use \"Bob\" as the balloon's icon.");
		break;
	case IDC_Timeout:
		strTitle= _T("Timeout");
		strMsg	= _T("Number of milliseconds the balloon remains open.  Set to 0 to disable timeout.");
		break;
	case IDC_LButtonDown:
		strTitle= _T("Feedback balloon launcher area");
		strMsg	= _T("Press the left mouse button here.");
		break;
	case IDC_MButtonDown:
		strTitle= _T("Feedback balloon launcher area");
		strMsg	= _T("Press the middle mouse button here.");
		break;
	case IDC_RButtonDown:
		strTitle= _T("Feedback balloon launcher area");
		strMsg	= _T("Press the right mouse button here.");
		break;
	default:
		return;
	}

	CBalloonHelp::Show(
		m_hWnd,			// owner window
		strTitle,		// title of balloon
		strMsg,			// content of balloon
		hWndControl,	// center "anchor" to this control
		IDI_INFORMATION,	// show info icon
		CBalloonHelp::BOCloseOnKeyDown|CBalloonHelp::BOCloseOnMouseMove|CBalloonHelp::BOCloseOnAppDeactivate|CBalloonHelp::BOCloseOnButtonDown
		);
}



// eof

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shog9
Software Developer
United States United States
Poke...

| Advertise | Privacy | Mobile
Web02 | 2.8.141022.1 | Last Updated 8 Aug 2002
Article Copyright 2001 by Shog9
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid