Introduction

Every developer is familiar with the Windows MessageBox, but sometimes we need just a little bit more. For instance, what if I want a "Don't show this warning again" checkbox at the bottom of my MessageBoxes, enabling the user to turn off certain alerts, but I don't want to write my own dialog from scratch, covering every possible button combination? The MsgBoxCheck class does just that.

Background

This article, and the MsgBoxCheck class, is built on two columns by Dino Esposito which appeared in MSDN Magazine's "Cutting Edge" in October and November of 2002. These describe the use of Windows Hooks in C#, in particular how to hook the creation and activation of the Windows MessageBox.

Using the code

Using the MsgBoxCheck class is as simple as using the Windows MessageBox. First, add a reference to MsgBoxCheck.dll in your C# project. Most people will invoke the class as follows:

MsgBoxCheck.MessageBox dlg = new MsgBoxCheck.MessageBox();
DialogResult dr =
dlg.Show(@"Software\PricklySoft\TestMsgBoxCheck",
"DontShowAgain",DialogResult.OK,
"Don't ask me this again",
"Now is the time for all good men to check this message box",
"Hello",
MessageBoxButtons.OK, MessageBoxIcon.Information);

The first two parameters describe the registry key, and value name used to store a boolean variable which determines if the user does not want this message box shown. The third parameter is the default return value, which will be returned immediately if the message box is not shown. Next is the text for the check box, then the message box text itself, the title, button code, and icon code.

License

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.

I just want to know if there's a license attached on the usage of the dll file. Can I use it freely on the project I'm developing. What are the limitations?

The only negative thing I've noted is the checkbox size. I think it is not set to AutoSize as it catches mouse events until the right end of the form. This could lead to accidental checking of the checkbox.

It is soeasy to implement this is VB2005. Just add reference to MsgBoxCheck.dll (To do this, double click on "My Project" then click on "References" tab, click "Add" button then browse to the folder location of MsgBoxCheck.dll. Click on it then hit "OK".

After adding the reference create a button then put the code below on the click event.

Dim dlg As MsgBoxCheck.MessageBox = New MsgBoxCheck.MessageBox()
Dim dr As DialogResult = dlg.Show("Software\PricklySoft\TestMsgBoxCheck", "DontShowAgain", System.Windows.Forms.DialogResult.OK, "Don't ask me this again", "Now is the time for all good men to check this message box", "Hello", MessageBoxButtons.OK, MessageBoxIcon.Information).

You can find the registry entry at HKEY_CURRENT_USER\Software\PricklySoft\TestMsgBoxCheck

In .NET we rather stay away from registry. We have configs, UserSettings ...

So I think it would be better if instead of passing registry path I could pass object implementing ICheckStateSaver so I could store check state in registry, database, UserSettings in user scope and so on.

Would you be willing to post the source for WindowsHook.dll and cbthook.dll? The tool works great standalone but inside a project with strongly typed assemblies it will not compile as these two dll's are not strongly type.

This also worked great in my VB.NET program however I had a couple of problems that were easily resolved but should be mentioned.

1. The msgboxcheck.dll requires two others also included in the zip file, windowshook.dll and cbthook.dll. All three need to be added as references before you can use it. Note for vb.net programmers add this to your global variables section of your code:

Public gbMsgboxCheck = New MsgBoxCheck.MessageBox

2. Another problem was that intellisense didn't work. I think this is because my code is vb.net and the dll is C#. The way around this is to write a function that simply calls gbMsgboxCheck with the proper parameters. This is good because you can setup default parameters. My function is called MsgCheck and looks like this:

MsgCheck("This is the message", "CallingProcedure")

I use the name of the calling procedure or function as my registry section to save the checkbox answer.

You have a yesno messagebox for confirmation of closing an application.

I check "don't ask me this again" but select the "no" button. It doesn't exit the program, but it does set my registry value to true..so the 2nd time I click exit, the message box warning doesn't appear..and it should!

It´s a good idea,but it doesn´t work on my app, because i use Joaqs.Ui (WinXP visual style), but i´ve learn write/read from registry.
In my particular problem i´ve got a class called "myMessageBox" inherit form Windows.Form.Form that has a behaviour similar to MessageBox. Now i´ve added 3 params called "showDontShowAgain","registry","key". So when i want "don´t show again" behavior i just construct like this:

I had the same problem - I needed a YesNo messagebox, but it needed to reappear if No was selected - even if the checkbox was checked. I worked around the problem by catching the dialogresult and using a conditional statement, I simply deleted the key that was produced (if the checkbox was checked). This effectivly made it impossible to make a key when No was selected.

I'm pretty new to VS2005 (and programming in general for that matter), so it may be a "hack" workaround - but it works!

(i.e.)
DialogResult dr = ckMB.Show(strKey, "Answer", DialogResult.Yes, "Don't ask me this again", "This action will reset the color ramp and any changes will be lost.\nAre you sure you want to continue?","Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

One extension to this would be a "Don't ask again" box that always selects the same option that was first selected. That way you could have a yes/no message box that, once the user has answered once, will always stay the same.