Introduction

This article describes ways of creating a Web-style GUI in an MFC application. Under the formula “application with Web-style GUI” I mean that the user interface or a part of it is made on HTML basis. There is an example of Web-style dialog in the picture.

In an attempt to use such an interface in applications, I faced the following problems:

In order to solve these questions, MSDN library advices to use DHTML COM interfaces (see also Handling HTML Element Events). It seemed to me that this is a bad alternative to the simple interaction with GUI model in MFC: event maps and direct handling with control objects.

This article gives an explanation of some work methods which make easier the creation of web-interface and the work with it from the application. Namely:

Receiving events from the web-interface through OnBeforeNavigate2() event.

The interaction with the web GUI through the HTML script functions in the HTML code.

In this article, I describe CHtmlDialog, CHtmlScript, CHtmlCtrl classes for the creation of Web style GUI in this article. An archive including ChtmlDialog class and examples of its use is attached to the article (read readme.txt before use).

Examples of Web-style GUI implementations

The web-style GUI for applications was certainly used for the first time in Microsoft Applications which are part of Windows OS.

HTML display using CHtmlView class

We need to change the HTML code for the application to look different from Internet Explorer.

Displaying HTML in an MFC application is quite simple. All you have to do is to use CHtmlView class. To try it, you have to start a new project with the help of “MFC AppWizard (exe)”. Choose «Single Document» type and turn on Document View architecture support. And on the last page of the **View class wizard, set «CHtmlView» as a base class. Next, add the HTML page into application resources.

In order to make our program to look more like an application than an Internet Explorer window, it is necessary to change something in the HTML page code:

To set the standard background color for Windows Applications as background color.

To forbid the mouse selection for the HTML content. Allow selection only for the text in the EditBox fields.

Forbid the mouse cursor change over the static text. In IE, the cursor placed over the text becomes an edit cursor - “I” (as in EditBox fields) so as the user to be able to mark and copy the text from the HTML page. In Windows applications, the text cursor usually appears only in EditBoxes.

The following HTML code executes these changes. These actions are possible due to DHTML technology.

In such a way, we have created an application that displays HTML as its interface. The Menu, Toolbar and status line remained, but this is normal, because we aren’t forced to give up using traditional controls, and in this way gain a certain flexibility.

At this step, we faced the DHTML technology due to which everything here is possible. The DHTML technology itself is possible due to DOM (Document Object Model) technology. The DOM represents the HTML document as objects [MSDN Library].

HTML window event processing

What is missing in CHtmlView?

A typical script working with interface elements presumes receiving events from them (buttons for example) and data placing (for example, into a text field). Particularly in our case, it is necessary to organize an interaction of the HTML window with the MFC code. This in not a complicate thing to do – the idea is to transmit the event from HTML to MFC code using the function OnBeforeNavigate2 of the CHtmlView class [Thomas Aust].

In HTML, or being more specific Dynamic HTML, also exists the conception of event. The possibilities of the event model in DHTML are very large, for example, an event can be stopped at a certain step of its processing.

At the occurrence of the event in HTML, it can be transformed into a window.navigate(%line%) call. The MFC code will receive such an event as a OnBeforeNavigate2 call with the %line% parameter. It is possible to transmit any HTML parameters in %line%, and MFC code will be able to process the user’s action. The transmission of event "click OK button", at the same time the text from txtBox is transmitted:

As not only the HTML but also the MFC code can be the event source, it is necessary for the MFC code to be able to transmit data into HTML. In order to make it possible, we can call scripts (Jscript\VBScript) in HTML and transmit data as script-functions’ parameters. The idea and realization of this method belong to [Eugene Khodakovsky]. The acquisition of “Script” object from HTML:

The scripts in HTML are very powerful and easy tools. It is possible to write a whole program with it which will handle the HTML content and react to users’ actions. The DHTML object model makes this programming quite easy.

In this way, the part of the MFC code which works with the interface and user’s actions can be moved to the HTML script. If the HTML pages are kept apart from the application, it is possible to change the interface’s logic without recompiling the EXE file.

CHtmlDialog – the HTML-based dialog window

Why it is necessary to use Advanced Hosting Interfaces?

Every application has dialogs besides the main window. These dialogs can have a quite complicated user interface. I mean not only the design, but also the reaction to user’s actions. So, it makes sense to use DHTML here too. The problem "How to place a class derived from CView on a dialog" is solved in the article by [Paul DiLascia, MSDN]. After the changes in CHtmlView, we have a CHtmlCtrl class (derived from CView) which can be placed on a dialog. The CHtmlDialog class solves two problems – setting the dialog window name and its size. These parameters are indicated on the HTML page. The CHtmlDialog class use:

Insert the dialog into resources. Place the STATIC element on it (STATIC will be replaced with the HTML control item). Next, create an MFC based class on this dialog (inherited from CDialog).

Change the inheritance class to ChtmlDialog in the header file (Dlg4.h for example).

The ChtmlDialog class also allow to change dialog size from HTML. (See _onHtmlCmd in CHtmlDialog).

Dialog window screenshots.

The hereby given Dialog example is taken from real life: it is necessary to give the user the possibility to add data blocks of a certain type on the smart-card. Although, it can be not a smart-card, but the file database of this card. So, this dialog must be logical: show the necessary icon – of a document or a smart-card (in the top left corner), use the text “Key” instead of “Document”. In general, the dialog must be adaptable. But this is not all.

Next, the things from Usability area come – the Dialog is displayed in a shorten variant at first, because the user has no need to know how many free space is available. The program was developed for Administrators and Developers. For example, the Administrator doesn’t have to know and see every time the free space number and the message that new data block size can be changed. The information about free space is given to the user at the very beginning, here it is needed to the Developer mostly (testing while developing smart-card applications).

If there is no free space on the smart-card, the Dialog will react – show the “Question” icon, the explanatory text and will disable the “OK” button. Next, the Dialog does user’s work – chooses the block which does not exist on the smart-card (or in the document) at the opening. If the user chooses an existing block , the Dialog will react – show the “Question” icon, the explanatory text, and will disable the “OK” button.

The main program calls this dialog at any time – even if the smart-card is full. In this situation, the dialog appears in an extended variant with the “Question” icon, explanatory text, and blocked “OK” button. Here the Dialog plays an informational role, otherwise the error message “there left no free space” must be shown, and instead a known dialog will appear – as a result, the user’s memory is not so loaded. As a result, such “interface logic” takes a lot of C++ code. And imagine that the application has 5 such dialogs.

Everything is almost finished, but there still are two problems:

The window which displays HTML in our application (ActiveX element) will always have a “pressed in” border and this cannot be changed. The explicit window options setting through SetWindowLong( GWL_STYLE) doesn’t work. This isn’t looking very good.

If the user changes the HTML display options (Internet Explorer Properties-> General Tab, Colors, Fonts,.. Buttons), it will influence the HTML appearance in our application, in other words, the fonts and colors will change. This doesn’t suit anyone. The application user may simply not recognize it when it is launched next time.

If the first problem can be tolerated, the second one is very serious. It is possible such a situation will occur when the application will look different depending on user’s IE settings.

Here is the way an HTML dialog looks if the user changes display settings in IE options. To solve this problem, it is necessary to provide the Advanced Hosting Interfaces support. Advanced Hosting Interfaces (AHI) are such COM interfaces which the WebBrowser’s ActiveX element has (starting with version 4.0). They help to take full control over the WebBrowser element [MSDN Library]. The realization of AHI in applications and this interfaces’ advantages are well demonstrated in [Ethan Akhgari]’s examples.

The problems described here are solved by OnGetHostInfo and OnGetOptionKeyPath event redefinition (see Html_Host_Handlers.cpp). I’ll stop at this point. Thank you for your attention.

Usage

Revision history

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'm actually new to this "combination of C++ & HTML". I find it easiest to catch events generated by HTML using the onBeforeNavigate2. I'm setting location.href to some predefined string.

But I know javascript can by disabled by user in IE options.
This will result in non execution of location.href=something and my program will fail to catch HTML events.
Moreover, user-interface is easy to do in javascript/html than C++, which is obstructed if javascript is disabled.

So, Is there any way we can temporarily force-enable javascript?

(I don't think it would be a security hole if such an option exists bcoz already my program is a EXE which has more power than javascript. So it would be meaningless to prevent developers from doing this on security grounds)