Custom WebBrowser Message Boxes

Imagine you have written an application which uses rich HTML user interface, with a lot of scripting and DHTML effects.  Maybe somewhere in your script codes, you have used the window.alert( ) function, and as soon as the alert message pops up, what do the users see?  A message box titled "Microsoft Internet Explorer"!  Hey, of course you are using the IE technology, but you don’t like the normal user notice it, do you?!

OK, to defeat this problem, you promise yourself not to use the alert( ) function.  But sometimes you will see that there is no way better than showing an alert box!  Well, you can’t have much control on it, really.  Of course, you may be able to do something by setting up different kinds of hooks and spying utilities, but there is a better and simpler way.

Microsoft has provided the interface IDocHostShowUI which (as its name implies) provides a means for your application to show its own user interface elements instead of those which are the default for the WebBrowser control.  This interface has two methods, ShowHelp( ) and ShowMessage( ).  The ShowHelp( ) function is used for showing your own help files or help context instead of those default to the WebBrowser control.  I won’t discuss this function in this article.

The ShowMessage( ) function is prototyped like this:

HRESULT ShowMessage(HWND     hwnd,
LPOLESTR lpstrText,
LPOLESTR lpstrCaption,
DWORD dwType,
LPOLESTR lpstrHelpFile,
DWORD dwHelpContext,
LRESULT* plResult
);

The hwnd parameter is the handle to the parent window.  If you show your UI using ::MessageBox( ) for example, this should be passed as the first parameter.  The lpstrText is the message text to be shown.  This is the default text that MSHTML provides.  You can modify it if necessary.  The lpstrCaption parameter is the caption for the message box.  You can change it to suit your own needs inside the application.  You will most likely want to change it to your application’s name; I will describe how you should do it later.  The dwType parameter is exactly like the fourth parameter of the ::MessageBox( ) function.  The lpstrHelpFile parameter indicates the help file path name.  If you want to show the help file, you must store this string somewhere, add a MB_HELP style to the message box, handle the WM_HELP messages inside the owner window (the window that is specified by the hwnd parameter), and inside the WM_HELP message handler, call ::WinHelp( ) and pass this string as the help file name.  The dwHelpContext specifies the context identifier of the help file which is also useful when you want to display a help file.  The plResult parameter points to an LRESULT variable.  This LRESULT variable should be set to the return value of the ::MessageBox( ) function, which specifies which button the user has clicked.

To use this function, you should provide an implementation of IDocHostShowUI.  This is a relatively tricky task, especially when you want to do it in a CHtmlView based application.  I have provided a set of classes inside my Advanced CHtmlView Hosting article which simplify things a lot.  See that article if you haven’t already.  To use ShowMessage( ) with my classes, you must derive your HTML view class from CDocHostHtmlView instead of CHtmlView, and override the virtual OnShowMessage( ) function.  Inside this function, you can show your own message box with custom text or caption.

The sample application which can be downloaded at the bottom of this article demonstrates a simple OnShowMessage( ) that replaces the caption of the message box with its own caption if it is the default "Microsoft Internet Explorer" caption.  Note that the WebBrowser control may show other message boxes which have a different caption, so you shouldn’t change the caption blindly.  My application uses the standard way to see if the caption of the message box is set to the standard caption or not.  It loads SHDOCLC.DLL, and loads the string resource number 2213.  This is the string resource which the WebBrowser control obtains its default message box title from.  If the lpstrCaption parameter equals this string, OnShowMessage( ) will change the caption.  If not, it does not touch it.  It also checks to see if the message box style contains the style for showing an exclamation mark.  If so, it changes it so that the message box would show the information icon.

One small note here.  You can’t customize the message boxes that come from within the scripting engine this way.  For example, for a JavaScript runtime error, the WebBrowser control does not show any message box, what you see is the message box being displayed by JSCRIPT.DLL, so even the WebBrowser control can’t control it!  The best way to avoid these kinds of message boxes is of course writing your script code in a way that it does not generate a runtime error.

 Download source code for the article

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Posted in Visual C++

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>