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
// BalloonHelp.cpp : header file
// Copyright 2001, Joshua Heyer
//  You are free to use this code for whatever you want, provided you
// give credit where credit is due.
//  I'm providing this code in the hope that it is useful to someone, as i have
// gotten much use out of other peoples code over the years.
//  If you see value in it, make some improvements, etc., i would appreciate it 
// if you sent me some feedback.
//

#pragma once

class CBalloonHelp : public CWindowImpl<CBalloonHelp>
{
public:
	CBalloonHelp();
	virtual ~CBalloonHelp();

	static ATL::CWndClassInfo& GetWndClassInfo() 
	{ 
		static ATL::CWndClassInfo wc = 
		{ 
//			{ sizeof(WNDCLASSEX), CS_DBLCLKS | CS_SAVEBITS | CS_DROPSHADOW, StartWindowProc, 
			{ sizeof(WNDCLASSEX), CS_DBLCLKS | CS_SAVEBITS, StartWindowProc, 
			0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, _T("BalloonHelpClass"), NULL}, 
			NULL, NULL, IDC_ARROW, TRUE, 0, _T("") 
		}; 
		return wc; 
	}

	// options
	static const unsigned int unCLOSE_ON_LBUTTON_UP;   // closes window on WM_LBUTTON_UP
	static const unsigned int unCLOSE_ON_RBUTTON_UP;   // closes window on WM_RBUTTON_UP
	static const unsigned int unCLOSE_ON_MOUSE_MOVE;   // closes window when user moves mouse past threshhold
	static const unsigned int unCLOSE_ON_KEYPRESS;     // closes window on the next keypress message sent to this thread.    (!!! probably not thread safe !!!)
	static const unsigned int unDELETE_THIS_ON_CLOSE;  // deletes object when window is closed.  Used by LaunchBalloon(), use with care
	static const unsigned int unSHOW_CLOSE_BUTTON;     // shows close button in upper right
	static const unsigned int unSHOW_INNER_SHADOW;     // draw inner shadow in balloon
	static const unsigned int unSHOW_TOPMOST;          // place balloon above all other windows
	static const unsigned int unDISABLE_FADEIN;        // disable the fade-in effect (overrides system and user settings)
	static const unsigned int unDISABLE_FADEOUT;       // disable the fade-out effect (overrides system and user settings)
	static const unsigned int unDISABLE_FADE;          // disable the fade-in/fade-out effects (overrides system and user settings)

	BOOL Create(const CString& strTitle,         // title of balloon
				const CString& strContent,       // content of balloon
				const CPoint& ptAnchor,          // anchor (tail position) of balloon
				unsigned int unOptions,          // options (see above)
				HWND pParentWnd = NULL,         // parent window (NULL == MFC main window)
				const CString strURL = "",       // URL to open (ShellExecute()) when clicked
				unsigned int unTimeout = 0,      // delay before closing automatically (milliseconds)
				HICON hIcon = NULL);             // icon to display

	// Show a help balloon on screen.
	static void LaunchBalloon(const CString& strTitle, const CString& strContent, 
				const CPoint& ptAnchor, 
				LPCTSTR szIcon = IDI_EXCLAMATION,
				unsigned int unOptions = unSHOW_CLOSE_BUTTON,
				HWND pParentWnd = NULL, 
				const CString strURL = "",
				unsigned int unTimeout = 10000);

	// Sets the font used for drawing the balloon title.  Deleted by balloon, do not use CFont* after passing to this function.
	void SetTitleFont(HFONT);
	// Sets the font used for drawing the balloon content.  Deleted by balloon, do not use CFont* after passing to this function.
	void SetContentFont(HFONT);
	// Sets the icon displayed in the top left of the balloon (pass NULL to hide icon)
	void SetIcon(HICON hIcon);
	// Sets the icon displayed in the top left of the balloon (pass NULL hBitmap to hide icon)
	void SetIcon(HBITMAP hBitmap, COLORREF crMask);
	// Sets the icon displayed in the top left of the balloon
	void SetIcon(HBITMAP hBitmap, HBITMAP hMask);
	// Set icon displayed in the top left of the balloon to image # nIconIndex from pImageList
	void SetIcon(HIMAGELIST pImageList, int nIconIndex);
	// Sets the URL to be opened when balloon is clicked.  Pass "" to disable.
	void SetURL(const CString& strURL);
	// Sets the number of milliseconds the balloon can remain open.  Set to 0 to disable timeout.
	void SetTimeout(unsigned int unTimeout);
	// Sets the distance the mouse must move before the balloon closes when the unCLOSE_ON_MOUSE_MOVE option is set.
	void SetMouseMoveTolerance(int nTolerance);
	// Sets the CPoint to which the balloon is "anchored"
	void SetAnchorPoint(CPoint ptAnchor);
	// Sets the title of the balloon
	void SetTitle(const CString& strTitle);
	// Sets the content of the balloon (plain text only)
	void SetContent(const CString& strContent);
	// Sets the forground (text and border) color of the balloon
	void SetForegroundColor(COLORREF crForeground);
	// Sets the background color of the balloon
	void SetBackgroundColor(COLORREF crBackground);
	protected:
	// layout constants
	static const int nTIP_TAIL;
	static const int nTIP_MARGIN;
	// mouse move tolerance
	static const int nMOUSE_MOVE_TRIGGER;

	enum BALLOON_QUADRANT { BQ_TOPRIGHT, BQ_TOPLEFT, BQ_BOTTOMRIGHT, BQ_BOTTOMLEFT };
	BALLOON_QUADRANT GetBalloonQuadrant();

	// Calculate the dimensions and draw the balloon header
	virtual CSize DrawHeader(HDC pDC, bool bDraw = TRUE);
	// Calculate the dimensions and draw the balloon contents
	virtual CSize DrawContent(HDC pDC, int nTop, bool bDraw = TRUE);
	// Calculate the dimensions required to draw the balloon header
	CSize CalcHeaderSize(HDC pDC) { return DrawHeader(pDC, FALSE); }
	// Calculate the dimensions required to draw the balloon content
	CSize CalcContentSize(HDC pDC) { return DrawContent(pDC, 0, FALSE); }
	// Calculate the total size needed by the balloon window
	CSize CalcWindowSize();
	// Calculate the total size needed by the client area of the balloon window
	CSize CalcClientSize();
	// Size and position the balloon window on the screen.
	void PositionWindow();

	// Displays the balloon on the screen, performing fade-in if enabled.
	void ShowBalloon(void);
	// Removes the balloon from the screen, performing the fade-out if enabled
	void HideBalloon(void);

BEGIN_MSG_MAP(CBalloonHelp)
	MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
	MESSAGE_HANDLER(WM_PAINT, OnPaint)
	MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
	MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
	MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
	MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
	MESSAGE_HANDLER(WM_TIMER, OnTimer)
	MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
	MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
	MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp)
	MESSAGE_HANDLER(WM_CLOSE, OnClose)
END_MSG_MAP()

	LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnRButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

private:
	// keyboard hook callback
	static LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam);
	// handle to the hook, if set
	static HHOOK            s_hKeyboardHook;
	// windows to close when user hits a key
	static CAtlArray<HWND>  s_apKeyboardCloseWnds;
	// synchronization
	static CComCriticalSection s_KeyboardHookSection;

	// Sets up the keyboard hook; adds this to list to close
	void SetKeyboardHook();
	// Removes this from the list of windows to close; removes hook if not in use.
	void RemoveKeyboardHook();

	// Wrapper for possibly-existing API call
	BOOL SetLayeredWindowAttributes(COLORREF crKey, int nAlpha, DWORD dwFlags);
	// layered window API, if available
	typedef BOOL (WINAPI* FN_SET_LAYERED_WINDOW_ATTRIBUTES)(HWND,COLORREF,BYTE,DWORD);
	FN_SET_LAYERED_WINDOW_ATTRIBUTES m_fnSetLayeredWindowAttributes;

	unsigned int   m_unOptions;
	unsigned int   m_unTimeout;      // max time to show, in milliseconds
	CString        m_strContent;     // text to show in content area
	CString        m_strURL;         // url to open, if clicked.
	CPoint          m_ptAnchor;       // "anchor" (CPoint of tail)
	HIMAGELIST     m_ilIcon;         // icon

	HFONT          m_pTitleFont;     // font to use for title
	HFONT          m_pContentFont;   // font to use for content
	   
	COLORREF       m_crBackground;   // Background color for balloon   
	COLORREF       m_crForeground;   // Foreground color for balloon
	   
	HRGN           m_rgnComplete;    // Clipping / Drawing region
	int            m_nAlpha;         // current alpha, for fade in / fade out
	CPoint          m_ptMouseOrig;    // original mouse position; for hiding on mouse move
	UINT           m_uCloseState;    // current state of the close button
	int            m_nMouseMoveTolerance;  // distance mouse has to move before balloon will close.

protected:
	void OnFinalMessage(HWND);
};

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 | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 8 Aug 2002
Article Copyright 2001 by Shog9
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid