Professional Documents
Culture Documents
Page 1 of 10
Creating Web-style GUI and easily managing it from MFC code. Creating dialogs based on DHTML, receiving events from DHTML to MFC, and calling JScript functions from MFC.
4.72 (38 votes)
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: Processing web interface events (getting events from DHTML to MFC code). Interactions with the Web elements (modifying DHTML from MFC code). 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 webinterface 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.
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 2 of 10
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).
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 3 of 10
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 4 of 10
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 Internet Explorer context menu to be displayed (except the context menu above the EditBox fields). 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.
<SCRIPT LANGUAGE="JScript"> // Forbid user s mouse selecting for the content // (allow text selection in EditBox only)
function onSelect1(){ if ( window.event.srcElement.tagName !="INPUT" ) { window.event.returnValue = false; window.event.cancelBubble = true; } } // Forbid IE context menu // // // (allow in EditBox only) (if the real context menu must be shown - Advanceв Hosting Interfaces must be used)
function onContextMenu(){ if ( window.event.srcElement.tagName !="INPUT" ) { window.event.returnValue = false; window.event.cancelBubble = true; return false; } } // Install Context Menu and Mark handlers on HTML loading. // function onLoad() { // forbid cursor change (except "INPUT" // entry box and "A" hyperlink) for HTML text. var Objs = document.all; for (i=0; i< Objs.length; i++) // "INPUT" entry box and "A" hyperlink if (Objs(i).tagName!="INPUT" && Objs(i).tagName!="A")
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 5 of 10
Objs(i).style.cursor = "default"; // event handler content selection document.onselectstart = onSelect1; // event handler context menu document.oncontextmenu = onContextMenu; } </SCRIPT> <BODY onload="onLoad();" leftmargin=0 topmargin=0 rightmargin=0 bottommargin=0 style = "background-color: buttonface;" > // the HTML background color will be as in Windows Applications
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 arent 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].
window.navigate("app:1005@" + Txt); // "app:1005@" this is the MFC code command prefix. // Txt } </SCRIPT>; <BODY> data can be transmitted along with the event.
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 6 of 10
. . . <input type=text style="width:50" id=txtBox > <input type=BUTTON value="Ok" onClick="onBtnOk()" style="width:45%"> // the button has an event handler the onBtnOk() script function . . . </BODY> </HTML>
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:
void CHtmlCtrl::OnDocumentComplete(LPCTSTR lpszURL) { . . . HRESULT hr; hr = GetHtmlDocument()->QueryInterface(IID_IHTMLDocument, (void**) &m_pDocument); if (!SUCCEEDED(hr)) { m_pDocument= NULL; return; } IDispatch *disp; m_pDocument->get_Script( &disp); . . . } // get script object
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 7 of 10
Next, the MFC code which calls the specific script function with the parameters:
. . . CStringArray strArray; strArray.Add("Parameter 1"); strArray.Add("Parameter 2"); strArray.Add("Parameter 3"); // the call of "SetParameters" function // from the script, (passing array of strings) m_HtmlCtrl.CallJScript2("SetParameters", strArray); // inside the CallJScript2 function: // // . . . GetIDsOfNames() Invoke() get the ID number of the script function
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 users actions can be moved to the HTML script. If the HTML pages are kept apart from the application, it is possible to change the interfaces logic without recompiling the EXE file.
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 8 of 10
3. Add the CHtmlDialog constructor call in the Dlg4 class constructor in the CPP file (Dlg4.cpp for example).
CDlg4::CDlg4(CWnd* pParent /*=NULL*/) :CHtmlDialog(CDlg4::IDD,pParent, IDR_HTML4, IDC_STATIC1) // the HTML page resource transmission { //{{AFX_DATA_INIT(CDlg4) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT }
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 doesnt 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).
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 9 of 10
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 users 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 users 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: 1. 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) doesnt work. This isnt looking very good. 2. 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 doesnt 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 users 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 WebBrowsers 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). Ill stop at this point. Thank you for your attention.
Usage
Please take a look at the projects in the source files archive.
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011
Page 10 of 10
Revision history
2003 December, Initial public release at Russian dev site. 2004 July, translation into English.
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. A list of licenses authors might use can be found here
http://www.codeproject.com/KB/dialog/web_gui.aspx?display=Print
7/5/2011