HTML COMCONTROL

 

You can display rendered HTML in WIL Dialogs using either the WebBrowser Control or the MSHTML component of Windows.

In order to use HTML rendering controls in WIL Dialogs on older systems you must have at least version 4.0 of Internet Explorer installed on the system. Some features shown in the accompanying examples may require more recent version of Windows.

Choosing the Correct Component

The WebBrowser Control adds browsing, document viewing, and data downloading capabilities to your WIL dialogs. The WebBrowser Control also acts as a container for the MSHTML component which provides parsing and rendering of HTML.

The WebBrowser Control and the MSHTML component each have their own events and MSHTML document events do not bubble up to the WebBrowser Control. This means that you cannot set your Dialog Callback Procedure as the event handler for MSHTML component events when it is hosted by the WebBrowser Control. Therefore, if you wish to handle HTML document events like onClick or onkeypress in your dialog callback, you should use the MSHTML component. On the other hand, if you wish to simply add web or local file browsing to your dialog, consider the WebBrowser Control.

It is still possible to handle MSHTML component events when MSHTML is hosted by the WebBrowser Control. However, it requires using the ObjectEventAdd function with a separate event handling user-defined function or subroutine for each event.

Using the MSHTML Component

You use the MSHTML component by specifying the programmatic identifier with colon "MSHTML:" in the text attribute of a COMCONTROL control definition string. Optionally, you can add standard HTML following the colon. The added HTML will be parsed and rendered by the component. For example, the following control definition will display a gif image in a dialog

; (Note: control definition strings must be on a single line.)

Exam001=`001,001,327,161,COMCONTROL,"Com_Mshtml",DEFAULT,MSHTML:<IMG SRC= "C:\Projects\Example\nebula.gif">,DEFAULT,1,DEFAULT,DEFAULT,DEFAULT, DEFAULT`

 

More sophisticated HTML content can become problematic because it needs to conform to both HTML and WIL Dialog template syntax in the control definition string. Also, the amount of HTML is restricted by WinBatch line limit. For these reasons, it is recommended that you dynamically create HTML content for an MSHTML control when the content involves more than a simple, single tag.

You can create HTML dynamically by placing a "MSHTML:" without any HTML text in the control's definition string. You then add HTML text using the MSHTML object's writeln or write method in the initialization (0) call to the Dialog Callback Procedure.

Here is a simple example that illustrates creating HTML dynamically to produce a visual affect not possible with standard WIL dialogs.

#DefineSubRoutine ExamProc( Exam_Handle,Exam_Message,Exam_ControlName, Exam_EventInfo, Exam_ChangeInfo)
   Switch Exam_Message
      Case @deinit
         ; Get the control's object
         objHtmlDoc = DialogObject(Exam_Handle, "Com_Mshtml", @dogetobject)
         objHtmlDoc.write('<HTML>')
         objHtmlDoc.write('<HEAD>')
         objHtmlDoc.write('<TITLE>MSHTML Example</TITLE>')
         objHtmlDoc.write('<STYLE> .textRed { COLOR: red }') ; Requires IE 5.0
         objHtmlDoc.write('.textBlue { COLOR: blue } </STYLE>')
         objHtmlDoc.write('</HEAD>')
         objHtmlDoc.write('<BODY>')
         objHtmlDoc.write(`<H1 class="textBlue" onmouseover="this.className='textRed'"`)
         objHtmlDoc.write(`onmouseout="this.className='textBlue'">`)
         objHtmlDoc.write('Mouse over this text to see the color change ')
         objHtmlDoc.write('from blue to red and back to blue')
         objHtmlDoc.write('</H1>')
         objHtmlDoc.write('<INPUT id="Button1" type="button" value="OK" name="Button1"')
         objHtmlDoc.write('style="Z-INDEX: 101; LEFT: 168px; WIDTH: 72px;')
         objHtmlDoc.write('POSITION: relative">')
         objHtmlDoc.write('</BODY>')
         objHtmlDoc.write('</HTML>')
         ; Add an event
         DialogObject(Exam_Handle, "Com_Mshtml", @doaddevent, "onclick", 1)
         Return(@retdefault)
      Case @decomevent
         ; Test in case more events or COM controls are added later
         If Exam_EventInfo.identifier == 1 && Exam_ControlName == "Com_Mshtml"
            ; Get event source object associated with the event
            objSource=objHtmlDoc.parentWindow.event.srcElement
            ; Button clicked?
            If objSource.tagName == "INPUT"
               If objSource.value == "OK" ; In case more added later.
                   Pause("User Pressed", "OK")
               EndIf
            EndIf
            ; Release object references
            objSource = 0
            objHtmlDoc = 0
            Exam_EventInfo = 0
            Return(1) ; Quit dialog
         EndIf
      EndSwitch ; Exam_Message
      Return(@retdefault) ; Do default processing
#EndSubRoutine ; End of Dialog Callback ExamProc

ExamFormat=`WWWDLGED,6.2` ExamCaption=`MSHTML Example` ExamX=021 ExamY=058 ExamWidth=179 ExamHeight=147 ExamNumControls=001 ExamProcedure=`ExamProc` Exam001=`002,001,178,145,COMCONTROL,"Com_Mshtml",DEFAULT,"mshtml:",DEFAULT,1,DEFAULT,DEFAULT,DEFAULT,DEFAULT` ButtonPushed=Dialog("Exam")

 

Events and the MSHTML Component

While most COM controls use the Dialog Callback Procedure's Event Information Object parameter to pass event information to your callback procedure, the MSHTML component uses a different mechanism. This means that the Event Information Object passed to your Dialog Callback will have values for the Identifier and EventName properties but the Count property will be set to zero (0) and the Parameters property will not have any values. Instead, the MSHTML component provides its own event object. The object contains event information; such as the element in which the event occurred, the state of the keyboard keys, the location of the mouse and the state of the mouse buttons.

Accessing the MSHTML Event Object

The event object is accessed via the Event property of a window object that represents a window associated with the MSHTML component. Typically, the component creates one window object when it opens an HTML document. However, if a document defines one or more frames, the component creates one window object for the original document.

; Get the MSHTML component's object
objHtmlDoc = DialogObject( Dlg_Handle, "Com_Mshtml", @dogetobject )

;  Access the event object for a main window event objEvent = objHtmlDoc.parentWindow.event
Using the MSHTML Event Object

The event object is provided by the MSHTML component for all events but its use can vary depending on the event being handled. All event properties are available to all event objects, but some properties might not have meaningful values during some events. For example, the fromElement and toElement properties are meaningful only when processing the onmouseover and onmouseout events. For this reason it is important to examine the srcElement property of the event object to identify the HTML element that is associated with the event before using other properties of the event object. Also keep in mind that the properties of the object returned by srcElement will vary with the type of element.

You can find more information on the objects, properties and methods of the event object on Microsoft's MSDN web site.

Using the WebBrowser Control

The WebBrowser Control contains the MSHTML component plus additional features including navigation, hyper linking, history lists and favorites. You add the WebBrowser Control to a dialog by placing a quoted URL moniker in the text attribute of a COMCONTROL control definition string. The moniker can be a URL to a World Wide Web site, a local file path/name or any other moniker recognized by Internet Explorer.

While the WebBrowser Control does contain an MSHTML component, MSHTML events do not bubble up to the WebBrowser Control. This means that the dialog callback procedure can be used to handle events fired by the WebBrowser control but it cannot be used to handle events fired by the MSHTML component when the component is hosted by the WebBrowser Control.

The following example uses the URL to the WinBatch Tech Support Database Web site to initialize a WebBrowser Control in a WIL Dialog. The newWindow2 and the commandStateChange WebBrowser events are used to control navigation and update the state of other dialog controls respectively. For demonstration purposes the initial URL only points to the left hand frame of the site's page. This is done to illustrate a technique for handling navigation to a nonexistent frame as happens if a user clicks on a search result after executing a Tech Data Base search. Special handling is necessary because the WebBrowser control will create a new unhosted window when there is targeted navigation to a frame name that does not yet exist. "Unhosted" means that the new window is not displayed as part of the dialog and the dialog procedure will not receive the new window's events.

Several things can be done to prevent the creation of an unhosted window. You could simply set the second parameter of the newWindow2 event to @TRUE to cancel the window

 

Exam_EventInfo.Parameters(2).value == @True

 

However, this not only cancels the window, it also cancels the navigation. If you want the user to be able to navigate to a targeted frame from your dialog's WebBrowser Control, you need a second dialog control to serve as a navigation target. In the example, this is accomplished by creating a hidden second WebBrowser Control and assigning its reference to the first parameter of the newWindow2 event.

 

Exam_EventInfo.Parameters(1).value = DialogObject(Exam_Handle, nHidden, @doGetObject)

 

Now when the newWindow2 event fires, the second WebBrowser control is made visible and accepts the navigation request.

Notice that since the controls occupy the same location on the dialog, the original control's style is changed to invisible. Also notice that the second parameter of the event is not changed. This is because the default setting for this parameter is @FALSE which tells the control not cancel new window navigation.

The dialog also handles the commandStateChange event. The event is used to adjust the state of the Forward and Back dialog buttons to match the presence or absence of the corresponding navigation history.

#DefineSubRoutine ExamProc( Exam_Handle, Exam_Message, Exam_ControlName, Exam_EventInfo, Exam_ChangeInfo)
   ; WebBrowser state change constants.
   CSC_NAVIGATEFORWARD = 1
   CSC_NAVIGATEBACK    = 2
   Switch Exam_Message
      Case @deinit
         ; Initialize variable used to track hidden browser window.
         sVisible = "ComControl_1"
         sHidden  = "ComControl_2"
         ; Want button messages.
         DialogProcOptions(Exam_Handle, @depbpush, 1)
         ; Add a COM event for both WebBrowser controls
         DialogObject(Exam_Handle, "ComControl_1", @doaddevent,  "CommandStateChange",1)
         DialogObject(Exam_Handle, "ComControl_2", @doaddevent,  "CommandStateChange",1)
         DialogObject(Exam_Handle, "ComControl_1", @doaddevent,  "NewWindow2", 2)
         DialogObject(Exam_Handle, "ComControl_2", @doaddevent,  "NewWindow2", 2)
         Return(@retdefault)
      Case @decomevent ;  COM event message
         ; Test in case more events or COM controls are added later
         If Exam_ControlName == "ComControl_1" || Exam_ControlName == "ComControl_2"
            Switch Exam_EventInfo.identifier
               Case 1 ; CommandStateChange - use to update button status
                  ; Event parameter 1 contains the command that is about to change
                  If Exam_EventInfo.Parameters(1).value == CSC_NAVIGATEFORWARD
                     sControl = "PushButton_Forward"  ; Forward button
                  Else
                     If  Exam_EventInfo.Parameters(1).value == CSC_NAVIGATEBACK
                        sControl = "PushButton_Back" ; Back button
                     Else
                        Break ; Do nothing.
                     EndIf
                  EndIf
                  ; Event parameter 2 indicates whether the command is
                  ; being activated or deactivated
                  If Exam_EventInfo.Parameters(2).value
                     nRequest = @dcsremstyle ; Command active
                  Else
                     nRequest = @dcsaddstyle  ; Command inactive
                  EndIf
                  DialogControlState( Exam_Handle, sControl, nRequest , @csdisabled)
                  Break
               Case 2 ; NewWindow2 - catches new window launches
                  ; Set event parameter 1 to the other window to prevent IE creating
                  ; an unhosted window
                  Exam_EventInfo.Parameters(1).value = DialogObject(Exam_Handle, sHidden, @dogetobject)
                  ; Change visibility of WebBrowser controls
                  DialogControlState(Exam_Handle, sHidden,@dcsremstyle,@csinvisible )
                  DialogControlState(Exam_Handle, Exam_ControlName,@dcsaddstyle,@csinvisible)
                  ; Update hidden variable to reflect change.
                  sVisible = sHidden
                  sHidden  = Exam_ControlName
                  DialogControlState(Exam_Handle, "PushButton_Other", @dcsremstyle,@csdisabled)
                  Break
            EndSwitch
         EndIf
         Break
      Case @depbpush  ; Navigation buttons
         If  Exam_ControlName == "PushButton_Back"  ; Back button
            objWebBrowser = DialogObject(Exam_Handle, sVisible, @dogetobject)
            objWebBrowser.GoBack()
            objWebBrowser = 0
            Return @retnoexit  ; Don't quit.
         EndIf
         If  Exam_ControlName == "PushButton_Forward"  ; Forward button
            objWebBrowser = DialogObject(Exam_Handle, sVisible, @dogetobject)
            objWebBrowser.GoForward()
            objWebBrowser = 0
            Return @retnoexit  ; Don't quit.
         EndIf
         If  Exam_ControlName == "PushButton_Other"  ; Other Window button - switch controls
            DialogControlState(Exam_Handle, sVisible, @dcsaddstyle,@csinvisible )
            DialogControlState(Exam_Handle, sHidden, @dcsremstyle,@csinvisible )
            objWebBrowser = DialogObject(Exam_Handle, sVisible, @dogetobject)
            objWebBrowser.stop
            objWebBrowser = DialogObject(Exam_Handle, sHidden, @dogetobject)
            objWebBrowser.Refresh2(1) ; 1 means normal refresh
            objWebBrowser = 0
            sTemp    = sHidden
            sHidden  = sVisible
            sVisible = sTemp
            Return @retnoexit  ; Don't quit.
         EndIf
         If  Exam_ControlName == "PushButton_Quit"  ; Quit button
            Exam_EventInfo = 0  ; Free reference - appropriate when using subroutine
            Break  ; Done
         EndIf
         Break
   EndSwitch       ; Exam_Message
   Return(@retdefault)      ; Do default processing
#EndSubRoutine     ; End of Dialog Callback ExamProc
ExamFormat=`WWWDLGED,6.2`
ExamCaption=`WebBrowser Example`
ExamX=021
ExamY=058
ExamWidth=350
ExamHeight=240
ExamNumControls=006
ExamProcedure=`ExamProc`
Exam001=`001,001,343,214,COMCONTROL,"ComControl_1",DEFAULT,"http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web",
DEFAULT,1,0,DEFAULT,DEFAULT,DEFAULT`
Exam002=`001,001,343,214,COMCONTROL,"ComControl_2",DEFAULT,"about:blank",DEFAULT,1,0,DEFAULT,DEFAULT,DEFAULT`
Exam003=`014,222,041,010,PUSHBUTTON,"PushButton_Back",DEFAULT,"Back",1,3,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
Exam004=`063,222,041,010,PUSHBUTTON,"PushButton_Forward",DEFAULT,"Foreward",2,4,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
Exam005=`126,222,041,010,PUSHBUTTON,"PushButton_Other",DEFAULT,"Other Window",3,5,2,DEFAULT,DEFAULT,DEFAULT`
Exam006=`295,222,041,010,PUSHBUTTON,"PushButton_Quit",DEFAULT,"Quit",4,6,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
ButtonPushed=Dialog("Exam")
                
WIL Additional Properties for Internet Explorer Components

WinBatch adds several properties to the programming models of Internet Explorer components. These properties give you additional control over the appearance and behavior of both the WebBrowser Control and the MSHTML component.

Gaining Access to Additional Properties

To access the properties when using the MSHTML component use the DialogObject function to obtain a references to the component for inside the Dialog callback procedure. You then need to obtain a reference to the parent window of the MSHTML component by calling the parentWindow property and then the window object's external property to get and set the WIL supplied additional properties. Here is an example

; Get the MSHTML component's object
objHtmlDoc = DialogObject( Dlg_Handle, "Com_Mshtml", @doGetObject )

;  Access the event object for a main window event objEvent = objHtmlDoc.parentWindow.event

Since the WebBrowser Control hosts the MSHTML component you need to use the document property to reference the MSHTML component before accessing WIL provided properties. Here is an example

; Get the control's object.
objWebBrowser = DialogObject( Dlg_Handle, "Com_Mshtml", @dogetobject )

;  Turn off Context menu objWebBrowser.document.parentWindow.external.contextMenu = @false

The WebBrowsers document property does not automatically return a valid object when the control is created because the document object is not instantiated until after the contents of the document are loaded into the control. This means you should not set WIL additional properties from case zero (0) of your dialog procedure as you can with the MSHTML component. The best time to set these properties is when your dialog procedure is called by the DownloadComplete event. This insures that document creation is completed and the document property will return a valid object reference. See the Dialog function topic for more information on control events.

The Additional Properties

The following properties are provided by WIL to modify the behavior and appearance of both of the WebBrowser Control and the MSHTML component.

Scrollable

Set this property to @TRUE to allow the user to scroll the content displayed by the control. The user cannot scroll the content of the control when the property is set to @FALSE. When set to @TRUE scroll bars are displayed in the control. The default for this property is @TRUE.

FlatScrollBars

When this property is set to @TRUE control scrollbars have a flat appearance. This property has no effect unless the Scrollable property is set to @TRUE. The FlatScrollBars property is set to @FALSE by default.

ContextMenu

This property controls the display of context menus when a user right-clicks on the control. When set to @TRUE the controls context menu is displayed. When set to @FALSE a right-click has no effect. The default for this property is @TRUE.

ThreeDBorder

Use this property to control the appearance of the controls border. This property affects the displayed documents border and any framesets within the document. Set the property to @TRUE to turn on 3-D borders.  The default for this property is @FALSE.

 
 

 

§         Dialog

§         Dialog Overview

§         Defining the Dialog

§         Defining the Dialog Controls

§         Dialog Control Types

§         Dynamic Dialogs

§         InternetExplorer Controls

§         Dialog Units

§         Dialog Fonts

 

Control Types

§         Calendar

§         Checkbox

§         ComControl

§         DropListbox

§         Editbox

§         FileListbox

§         Groupbox

§         Itembox

§         MenuBar

§         MenuItem

§         MultiLinebox

§         Picture

§         PictureButton

§         PushButton

§         RadioButton

§         ReportView

§         Spinner

§         StaticText

§         VaryText

 

Internet Explorer WebBrowser Example:
#DefineSubRoutine ExamProc( Exam_Handle, Exam_Message, Exam_ControlName, Exam_EventInfo, Exam_ChangeInfo)
   ; WebBrowser state change constants.
   CSC_NAVIGATEFORWARD = 1
   CSC_NAVIGATEBACK    = 2
   Switch Exam_Message
      Case @deinit
         ; Initialize variable used to track hidden browser window.
         sVisible = "ComControl_1"
         sHidden  = "ComControl_2"
         ; Want button messages.
         DialogProcOptions(Exam_Handle, @depbpush, 1)
         ; Add a COM event for both WebBrowser controls
         DialogObject(Exam_Handle, "ComControl_1", @doaddevent,  "CommandStateChange",1)
         DialogObject(Exam_Handle, "ComControl_2", @doaddevent,  "CommandStateChange",1)
         DialogObject(Exam_Handle, "ComControl_1", @doaddevent,  "NewWindow2", 2)
         DialogObject(Exam_Handle, "ComControl_2", @doaddevent,  "NewWindow2", 2)
         Return(@retdefault)
      Case @decomevent ;  COM event message
         ; Test in case more events or COM controls are added later
         If Exam_ControlName == "ComControl_1" || Exam_ControlName == "ComControl_2"
            Switch Exam_EventInfo.identifier
               Case 1 ; CommandStateChange - use to update button status
                  ; Event parameter 1 contains the command that is about to change
                  If Exam_EventInfo.Parameters(1).value == CSC_NAVIGATEFORWARD
                     sControl = "PushButton_Forward"  ; Forward button
                  Else
                     If  Exam_EventInfo.Parameters(1).value == CSC_NAVIGATEBACK
                        sControl = "PushButton_Back" ; Back button
                     Else
                        Break ; Do nothing.
                     EndIf
                  EndIf
                  ; Event parameter 2 indicates whether the command is
                  ; being activated or deactivated
                  If Exam_EventInfo.Parameters(2).value
                     nRequest = @dcsremstyle ; Command active
                  Else
                     nRequest = @dcsaddstyle  ; Command inactive
                  EndIf
                  DialogControlState( Exam_Handle, sControl, nRequest , @csdisabled)
                  Break
               Case 2 ; NewWindow2 - catches new window launches
                  ; Set event parameter 1 to the other window to prevent IE creating
                  ; an unhosted window
                  Exam_EventInfo.Parameters(1).value = DialogObject(Exam_Handle, sHidden, @dogetobject)
                  ; Change visibility of WebBrowser controls
                  DialogControlState(Exam_Handle, sHidden,@dcsremstyle,@csinvisible )
                  DialogControlState(Exam_Handle, Exam_ControlName,@dcsaddstyle,@csinvisible)
                  ; Update hidden variable to reflect change.
                  sVisible = sHidden
                  sHidden  = Exam_ControlName
                  DialogControlState(Exam_Handle, "PushButton_Other", @dcsremstyle,@csdisabled)
                  Break
            EndSwitch
         EndIf
         Break
      Case @depbpush  ; Navigation buttons
         If  Exam_ControlName == "PushButton_Back"  ; Back button
            objWebBrowser = DialogObject(Exam_Handle, sVisible, @dogetobject)
            objWebBrowser.GoBack()
            objWebBrowser = 0
            Return @retnoexit  ; Don't quit.
         EndIf
         If  Exam_ControlName == "PushButton_Forward"  ; Forward button
            objWebBrowser = DialogObject(Exam_Handle, sVisible, @dogetobject)
            objWebBrowser.GoForward()
            objWebBrowser = 0
            Return @retnoexit  ; Don't quit.
         EndIf
         If  Exam_ControlName == "PushButton_Other"  ; Other Window button - switch controls
            DialogControlState(Exam_Handle, sVisible, @dcsaddstyle,@csinvisible )
            DialogControlState(Exam_Handle, sHidden, @dcsremstyle,@csinvisible )
            objWebBrowser = DialogObject(Exam_Handle, sVisible, @dogetobject)
            objWebBrowser.stop
            objWebBrowser = DialogObject(Exam_Handle, sHidden, @dogetobject)
            objWebBrowser.Refresh2(1) ; 1 means normal refresh
            objWebBrowser = 0
            sTemp    = sHidden
            sHidden  = sVisible
            sVisible = sTemp
            Return @retnoexit  ; Don't quit.
         EndIf
         If  Exam_ControlName == "PushButton_Quit"  ; Quit button
            Exam_EventInfo = 0  ; Free reference - appropriate when using subroutine
            Break  ; Done
         EndIf
         Break
   EndSwitch       ; Exam_Message
   Return(@retdefault)      ; Do default processing
#EndSubRoutine     ; End of Dialog Callback ExamProc

ExamFormat=`WWWDLGED,6.2` ExamCaption=`WebBrowser Example` ExamX=021 ExamY=058 ExamWidth=350 ExamHeight=240 ExamNumControls=006 ExamProcedure=`ExamProc` Exam001=`001,001,343,214,COMCONTROL,"ComControl_1",DEFAULT,"http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web", DEFAULT,1,0,DEFAULT,DEFAULT,DEFAULT` Exam002=`001,001,343,214,COMCONTROL,"ComControl_2",DEFAULT,"about:blank",DEFAULT,1,0,DEFAULT,DEFAULT,DEFAULT` Exam003=`014,222,041,010,PUSHBUTTON,"PushButton_Back",DEFAULT,"Back",1,3,DEFAULT,DEFAULT,DEFAULT,DEFAULT` Exam004=`063,222,041,010,PUSHBUTTON,"PushButton_Forward",DEFAULT,"Foreward",2,4,DEFAULT,DEFAULT,DEFAULT,DEFAULT` Exam005=`126,222,041,010,PUSHBUTTON,"PushButton_Other",DEFAULT,"Other Window",3,5,2,DEFAULT,DEFAULT,DEFAULT` Exam006=`295,222,041,010,PUSHBUTTON,"PushButton_Quit",DEFAULT,"Quit",4,6,DEFAULT,DEFAULT,DEFAULT,DEFAULT` ButtonPushed=Dialog("Exam")