Mirror

Creating HTML Dialogs (Views: 702)

Problem/Question/Abstract:

Creating HTML Dialogs in Borland Delphi

Answer:

Introduction

Microsoft, having taken over the desktop with Windows™, seems to want to take over the Internet with their Internet Explorer. As they are a very generous company at heart they give away their browser for free and, more importantly, it's associated software development kit. The purpose of this article is to demonstrate the use of one of the Internet Explorer technologies, namely HTML Dialog boxes using Borland Delphi. What does an HTML Dialog box look like? How does it differ from a normal Dialog Box or Form?


Figure 1: An example of an HTML Dialog


OK. I know it doesn't look like much compared with what you can achieve with Delphi or Visual Basic (for Visual C++ programmers this will look pretty cool but we'll ignore them!). The big advantage of an HTML dialog is the ease and flexibility offered by building large portions of the UI in HTML. Practically all graphic/design type persons know how to concoct some pretty impressive web sites. All the programmer has to do is define the basic operation using either JavaScript or VBScript and then pass the HTML to a graphic designer to work their magic. Another plus is the availability of DynamicHTML and all the other whizzy features of Internet Explorer which can give you quick easy access to fancy multimedia effects. Another reason for choosing HTML Dialog Boxes is the internet integration features. If you are already integrating IE into your application then there should be little overhead in using HTML Dialogs and it might help your overall interface design look more consistent.

Requirements

The system requirements for the target and devlopment machines are fairly steep. They must have Internet Explorer 4.0 or later installed. To develop using Delphi you will need Delphi 2.0 or later and an image/HTML editor of your choice.

Setting up the MSHTML library

The first step in creating a HTML Dialog Box is to define the ShowHTMLDialog function and load the MSHTML.DLL. The ShowHTMLDialog function is the main function used to bring an HTML Dialog to life. It is contained in the MSHTML.DLL which forms the core of Internet Explorer. You must load this library explicitly rather than use an Import Unit like you would do with most other APIs.

Before you can use ShowHTMLDialog you must first define it as a procedural type(it's being dynamically loaded remember:

type
TShowHTMLDialogFn = function(const hwndParent: HWND; const pmk: IMoniker;
const pvarArgIn: Variant; const pchOptions: POleStr;
var pvarArgOut: Variant): HResult stdcall;

The procedural type is very similar to the definitions you will find of other Windows/OLE API functions. For further details about the ShowHTMLDialog function see the Further Information Section below.

In the initialisation section of your main form or application add the following code:

var
hInstHTML: THandle;
ShowHTMLDialog: TShowHTMLDialogFn;

initialization
hInstHTML := LoadLibrary('MSHTML.DLL');
if hInstHTML = 0 then
MessageDlg('Unable to LoadLibrary(''MSHTML.DLL'') - Nothing will work!', mtError,
[mbOK], 0);

if hInstHTML > 0 then
@ShowHTMLDialog := GetProcAddress(hInstHTML, 'ShowHTMLDialog')
else
@ShowHTMLDialog := nil;

finalization
FreeLibrary(hInstHTML);

When the unit or application is initialised this code calls the Window LoadLibrary function to load the DLL and then uses the GetProcAddress function to bind to the ShowHTMLDialog function. The function is bound to a global varable, ShowHTMLDialog, which allows it to be used like a normal function.

One final step is required. As Delphi 2.0 doesn't have header files for the "old" Internet Explorer 3.0 SDK it is missing a URLMon function required to generate a Moniker which refers to an internet URL. I've defined it here for conveneice, Delphi 3.0 users ignore this and put "UrlMon" in your uses clause:

function CreateURLMoniker(const pmkContext: IMoniker; const szURL: POleStr;
var ppmk: IMoniker): HResult stdcall; external 'URLMON.DLL';

Running an HTML Dialog Box

An HTML Dialog Box is run by calling the ShowHTMLDialog function. Before we can do this though we have to do some setup work. We need to create a URL Moniker that represents the URL for the dialog HTML code. Yes, that's right, a URL! HTML Dialogs get their data using a standard internet URL which usually points to the applications resources rather than a web server or separate file. This effect is achived using the "res:" protocol. The URL for our dialog HTML is "res://htmldlg.exe/RT_HTML/HTML_RESOURCE" where RT-HTML is the resource type (i.e. RT_HTML, ICON, BITMAP, etc). A Moniker is just a standard way of allowing OLE applications to talk about a location or pointer or in this case a URL. The code to create the Moniker is:

GetModuleFileName(hInstance, ModuleName, 100);
ResURLStr := StringToOleStr('res://' + StrPas(ModuleName) + '/RT_HTML/HTML_RESOURCE');
OleCheck(CreateURLMoniker(nil, ResURLStr, pmk));
SysFreeString(ResURLStr);

This creates an OLE string (Wide/Unicode string) for the URL and calls the CreateURLMoniker function. After the Moniker is created the OLE string memory is freed.

The dialog box takes in parameters in the form of a variant variable. In this simple example we just pass in an OLE string but a whole OLE object or integer or array could be passed in.

TVarData(InParam).VType := varOleStr;
TVarData(InParam).VOleStr :=
StringToOleStr('Argument 1;Argument 2;Argument 3;Argument 4;' +
'Pleasant discussion 1');

The variable InParam is just a standard Delphi variant variable which we explicitly set to be an OLE string. If there is a better or more correct way of doing this please let me know.

We can now safely call the ShowHTMLDialog function:

OleCheck(ShowHTMLDialog(Handle, pmk, InParam, nil, OutParam));

As with all OLE functions we wrap the call with OleCheck which would generate an EOleError exception. The call constist of passing in the parent form's window handle, the URL Moniker and the input and output parameter variables.

All that remains is to check the result of the dialog and act accordingly:

if VarType(OutParam) = varOleStr then
MessageDlg('Dialog returned ' + OutParam, mtInformation, [mbOK], 0)
else
MessageDlg('Dialog canceled!', mtInformation, [mbOK], 0);
InParam := Unassigned;
OutParam := Unassigned;

The input and output parameters are cleaned up at this point.

Creating the HTML for the Dialog

Creating the HTML for the dialog is very straight forward and is very similar to creating a standard Web page with JavaScript or VBScript. One of the main things to do is explicitly set the size of the dialog:



The input parameter can be accessed using the "window.dialogArguments" object and the return parameter is "window.returnValue". Which are access in the same way as you would access other IE internal variables.

For further information on what you can do in an HTML dialog read the information on how to create Modal Dialogs and Using Dynamic HTML in the Internet Client SDK.

Creating a resource file for Delphi

The last stage in the process is to create the resource file which the HTML dialog can read. This process encapsulates all the graphics, HTML, java, etc that you've used in your dialog in one place. For my simple example I used one graphic and the HTML for the dialog itself. The first step is to create an RC file which we compile to create a binary RES file which is linked in by Delphi to the EXE. My html.rc file contains:

HTML_RESOURCE RT_HTML DISCARDABLE "HTMLDlg.htm"

TITLEGIF      RT_HTML DISCARDABLE "hwlogo.GIF"


This stores the local files "HTMLDlg2.htm" and "hwlogo.gif" as HTML_RESOURCE and TITLEGIF both of resource type RT_HTML. The RC file compiled by runing "brcc32 html.rc" The brcc32 program is contained in the Delphi\bin directory.

The RES file is included into the Delphi program by placing:

{$R html.res}

which tells Delphi to link the file along with the rest of the program.

All you have to do now is compile and run your program.

Conculsion

Well that's all there is to it! I have taken all the steps above and put them together into a zipped package which you can build with Delphi 2.0 or 3.0. Using HTML Dialogs is a brave step at the moment particularly with Microsoft under the threat of having to remove IE 4.0 from Windows 98/ NT 5.0 but could well be worth while in your application. I'm still very undecided about it all at the moment and I'm just treating this as a big experiment at the moment. Email me to find out if I've changed my mind....

Download

The complete source for the program descirbed in this article is contianed in htmldlg.ziphttp://sca.uwaterloo.ca/www.calm.hw.ac.uk/davidf/papers/htmldlg.zip

Further Information and Links

The majority of the information I needed for this paper came from the Microsoft Internet Client SDKhttp://msdn.microsoft.com/. Check out the documentation and the htmldlg sample application on which my example is based. There is a whole section of the SDK docs for HTML Dialog Boxes.



<< Back to main page