Click here to Skip to main content
13,138,192 members (48,650 online)
Click here to Skip to main content


67 bookmarked
Posted 14 May 2004

A "Don't show this again" checkbox for the .NET MessageBox

, 14 May 2004
A C# class which uses Dino Esposito's LocalCbtHook component to add a "Don't show this again" checkbox to any .NET MessageBox.
using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MsdnMag;			// For LocalCbtHook
using Microsoft.Win32;	// For RegKey

namespace MsgBoxCheck
	public class MessageBox
		protected LocalCbtHook m_cbt;
		protected IntPtr m_hwnd = IntPtr.Zero;
		protected IntPtr m_hwndBtn = IntPtr.Zero;
		protected bool m_bInit = false;
		protected bool m_bCheck = false;
		protected string m_strCheck;

		public MessageBox()
			m_cbt = new LocalCbtHook();
			m_cbt.WindowCreated += new LocalCbtHook.CbtEventHandler(WndCreated);
			m_cbt.WindowDestroyed += new LocalCbtHook.CbtEventHandler(WndDestroyed);
			m_cbt.WindowActivated += new LocalCbtHook.CbtEventHandler(WndActivated);

		public DialogResult Show(string strKey, string strValue, DialogResult dr, string strCheck, string strText, string strTitle, MessageBoxButtons buttons, MessageBoxIcon icon)
			RegistryKey regKey = Registry.CurrentUser.CreateSubKey(strKey);
					return dr;
				// No processing needed...the convert might throw an exception,
				// but if so we proceed as if the value was false.

			m_strCheck = strCheck;
			dr = System.Windows.Forms.MessageBox.Show(strText, strTitle, buttons, icon);

			return dr;

		public DialogResult Show(string strKey, string strValue, DialogResult dr, string strCheck, string strText, string strTitle, MessageBoxButtons buttons)
			return Show(strKey, strValue, dr, strCheck, strText, strTitle, buttons, MessageBoxIcon.None);
		public DialogResult Show(string strKey, string strValue, DialogResult dr, string strCheck, string strText, string strTitle)
			return Show(strKey, strValue, dr, strCheck, strText, strTitle, MessageBoxButtons.OK, MessageBoxIcon.None);
		public DialogResult Show(string strKey, string strValue, DialogResult dr, string strCheck, string strText)
			return Show(strKey, strValue, dr, strCheck, strText, "", MessageBoxButtons.OK, MessageBoxIcon.None);

		private void WndCreated(object sender, CbtEventArgs e)
			if (e.IsDialogWindow)
				m_bInit = false;
				m_hwnd = e.Handle;
		private void WndDestroyed(object sender, CbtEventArgs e)
			if (e.Handle == m_hwnd)
				m_bInit = false;
				m_hwnd = IntPtr.Zero;
				if(BST_CHECKED == (int)SendMessage(m_hwndBtn,BM_GETCHECK,IntPtr.Zero,IntPtr.Zero))
					m_bCheck = true;

		private void WndActivated(object sender, CbtEventArgs e)
			if (m_hwnd != e.Handle)

			// Not the first time
			if (m_bInit)
				m_bInit = true;

			// Get the current font, either from the static text window
			// or the message box itself
			IntPtr hFont;
			IntPtr hwndText = GetDlgItem(m_hwnd, 0xFFFF);
			if(hwndText != IntPtr.Zero)
				hFont = SendMessage(hwndText, WM_GETFONT, IntPtr.Zero, IntPtr.Zero);			
				hFont = SendMessage(m_hwnd, WM_GETFONT, IntPtr.Zero, IntPtr.Zero);			
			Font fCur = Font.FromHfont(hFont);
			// Get the x coordinate for the check box.  Align it with the icon if possible,
			// or one character height in
			int x = 0;
			IntPtr hwndIcon = GetDlgItem(m_hwnd, 0x0014);
			if(hwndIcon != IntPtr.Zero)
				RECT rcIcon = new RECT();
				GetWindowRect(hwndIcon, rcIcon);
				POINT pt = new POINT();
				pt.x = rcIcon.left;
				pt.y =;
				ScreenToClient(m_hwnd, pt);
				x = pt.x;
				x = (int)fCur.GetHeight();

			// Get the y coordinate for the check box, which is the bottom of the
			// current message box client area
			RECT rc = new RECT();
			GetClientRect(m_hwnd, rc);
			int y = rc.bottom -;

			// Resize the message box with room for the check box
			GetWindowRect(m_hwnd, rc);
			MoveWindow(m_hwnd,rc.left,,rc.right-rc.left, + (int)fCur.GetHeight()*2,true);

			m_hwndBtn = CreateWindowEx(0, "button", m_strCheck, BS_AUTOCHECKBOX|WS_CHILD|WS_VISIBLE|WS_TABSTOP, 
				x, y , rc.right-rc.left-x, (int)fCur.GetHeight(),
				m_hwnd, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

			SendMessage(m_hwndBtn, WM_SETFONT, hFont, new IntPtr(1));			

		#region Win32 Imports
		private const int WS_VISIBLE		= 0x10000000;
		private const int WS_CHILD			= 0x40000000;
		private const int WS_TABSTOP        = 0x00010000;
		private const int WM_SETFONT		= 0x00000030;
		private const int WM_GETFONT		= 0x00000031;
		private const int BS_AUTOCHECKBOX	= 0x00000003; 
		private const int BM_GETCHECK       = 0x00F0;
		private const int BST_CHECKED       = 0x0001;

		protected static extern void DestroyWindow(IntPtr hwnd);
		protected static extern IntPtr GetDlgItem(IntPtr hwnd, int id);
		protected static extern int GetWindowRect(IntPtr hwnd, RECT rc);
		protected static extern int GetClientRect(IntPtr hwnd, RECT rc);
		protected static extern void MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool bRepaint);
		protected static extern int ScreenToClient(IntPtr hwnd, POINT pt);
		[DllImport("user32.dll", EntryPoint="MessageBox")]
		protected static extern int _MessageBox(IntPtr hwnd, string text, string caption,
			int options);
		protected static extern IntPtr SendMessage(IntPtr hwnd, 
			int msg, IntPtr wParam, IntPtr lParam);

		protected static extern IntPtr CreateWindowEx(
			int dwExStyle,			// extended window style
			string lpClassName,		// registered class name
			string lpWindowName,	// window name
			int dwStyle,			// window style
			int x,					// horizontal position of window
			int y,					// vertical position of window
			int nWidth,				// window width
			int nHeight,			// window height
			IntPtr hWndParent,      // handle to parent or owner window
			IntPtr hMenu,			// menu handle or child identifier
			IntPtr hInstance,		// handle to application instance
			IntPtr lpParam			// window-creation data
		public class POINT
			public int x;
			public int y;

		public class RECT
			public int left; 
			public int top; 
			public int right; 
			public int bottom; 


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.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Mike Scanlon
Web Developer
United States United States

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170915.1 | Last Updated 15 May 2004
Article Copyright 2004 by Mike Scanlon
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid