Click here to Skip to main content
13,448,170 members (55,522 online)
Click here to Skip to main content
Add your own
alternative version


50 bookmarked
Posted 29 Aug 2002

Web Win32/WTL Hybrid

, 22 Dec 2005
Rate this:
Please Sign up or sign in to vote.
How to implement a two-way communication path from IExplorer and WTL code


Normally, when we see applications like, for instance, MS Money, that looks like an Internet Explorer layout and has the functionality of a Win32 application, we don't know if Microsoft guys are hiding some technical concepts from us, (I don't know any, I promise you ;) ), or maybe we can't read Microsoft MSDN documentation properly than they can.

This article will expose the way to fully reuse IExplorer for your applications, and will try to explain the implementation of this sample. In fact, it is a sample and is not a "real" library to be used in a "real" application. I only want to show one way to do this kind of implementations. The code has no full error handling, so if you want to use it in a "real" application, keep in your mind, you will need to review some of the critical steps.

Before taking on the next sections, I invite you to get the sample source code, and compile it, I think it will be great for you to understand the following sections better.


There are two versions of the code, one for VC6/WTL7.0 and the other for VC7/WTL7.0.

You should have installed the latest Platform SDK or you will receive errors in interface declarations like IHTMLElement2.

You can find the Platform SDK as a free download at

Once you compile the program, you might receive a "library not registered" error; if this occurs, you only need to go to the project directory and execute RegTLib WebWin32Sample.tlb. Sometimes, you might need to register the COM server in this way: WebWin32Sample.exe /RegServer, run both only once.

Final class

First of all, I want to show you how the "host" class looks, and then I will explain each piece of code and the underlying tricks:

class CWebWin32SampleView : public 
    DECLARE_WND_SUPERCLASS(NULL, CAxWindow::GetWndClassName())

    // Our internet explorer control
    CWTLIExplorer m_pBrowser;

    // Our vars to Exchange information with HTML page...
    CString m_FirstName;
    CString m_LastName;
    CString m_Address;
    CString m_Country;
    BOOL m_ILikeThisSample;

    // html-hosted-page-form-based DDX
        BEGIN_FORM( "testForm" ) // Our Form Name ( at HTML page )
          // Our exchange definitions...
          DDX_HTML_STRING( m_FirstName ,"firstName" ) 
          DDX_HTML_STRING( m_LastName  ,"lastName" )
          DDX_HTML_STRING( m_Address,"address" )
          DDX_HTML_LISTBOX( m_Country, "country" );
          DDX_HTML_CHECKBOX( m_ILikeThisSample, "ILikeIt" )

    // HTML Handlers
    // Here we can define HTML handlers hooks related to element at the 
    // page loaded
        // Set an event handler on buttonSumbmit.onclick 
        COMMAND_HTML_HANDLER( ID_HTML_CLICK, "buttonSubmit", OnSubmit )

    LRESULT OnSubmit( BOOL & bHandled )
        // Do Data Exchange with HTML page...
        DDX_HTML_EXCHANGE( m_pBrowser, false /* false=get | true=set */ )

        // MessageBox text Composite 
        CString totalMessage = m_FirstName + CString(" - ") + m_LastName + 
                                                CString(" - " ) + m_Address;

        if ( m_ILikeThisSample )
             totalMessage += CString("\n\nYou have checked it." );
             totalMessage += CString("\n\nYou have not checked it." );

        totalMessage += CString("\n\nCountry Selected: ") + m_Country;

        // Show a message box
        MessageBox( totalMessage,
                "From CWebWin32SampleView::OnSubmit event handler.", 
                MB_ICONINFORMATION );

        // set handled
        bHandled = true;
        return 0;

    BOOL PreTranslateMessage(MSG* pMsg);


        // We receive this message when IExplorer is on a ready state for us
        // and we can Set handlers to the page...
                                                OnHTMLSetHandlers )

    LRESULT OnHTMLSetHandlers(UINT /*uMsg*/, WPARAM /*wParam*/, 
                            LPARAM /*lParam*/, BOOL& /*bHandled*/ )
        // Activate event handlers map
        return 0;

// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, 
//                         LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, 
//                         HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, 
//                                         BOOL& /*bHandled*/)

    LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, 
                    LPARAM /*lParam*/, BOOL& /*bHandled*/);
    LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, 
                    LPARAM /*lParam*/, BOOL& /*bHandled*/);


In fact, all HTML elements at IExplorer derive from IHTMLElement. In this interface, we can find the possibility to use some methods to get/set event handlers at element level, like put_onclick( VARIANT handler), the variant should hold a VT_IDISPATCH variable that references a COM object. When this event is fired, IExplorer tries to call the default method of this IDispatch object. This is perfect for our intentions, so we need to define a COM object that holds a default method, when this method is called we only need to "jump" into our event handler.

The object I use to do this work is WebWin32.WebWin32EventHandler that has only two methods SetHandler(LONG,LONG) and CallHandler which is the object's default method.

SetHandler(LONG,LONG) is called to set the "callback" address. To do this, we need to pass our object address (this) and the member address callback entry point.

We need to do some code level "crack" to convert the Pointer member variable which holds the member address into a LONG.

// ( This is a simulation )
DWORD pointer_part_2 = (DWORD) this;
DWORD pointer_part_1;

// pointer member prototype
LRESULT (CWebWin32SampleView::*pVar) ( BOOL & );

// load our member pointer
pVar = OnSubmit;

// extract address
memcpy( &pointer_part_1, ( char * )  &pVar, 4 );
pHandler->SetHandler( pointer_part_1, pointer_part_2 );
SetHandlerIntoHtmlElementOnClick( pHandler, "addressField" );

Later, when IExplore fires our method, we need to do another "trick" to "jump" into our "callback":

STDMETHODIMP CWebWin32EventHandler::CallHandler(void)
    // __thiscall asm implementation

    DWORD pMember;
    DWORD pThis;

    pThis   = m_pThis;
    pMember = m_pMember;

    BOOL bHandled=false;
    // this the same like do pObject->MemeberToCall( bParam ) 
    // but we don't have
    // problems about what type of object or method prototype was defined, 
    // this is a generic "thiscall"
        lea eax,[bHandled]      ; BOOL & 
        push eax                ; push it
        mov ecx,[pThis]         ; "this" object into ecx
        call pMember            ; call the member pointer
    return S_OK;

That is all we need to know to fire events from an HTML element to our code.


As we have a reference to the IExplorer instance, this is the easiest of the things, we only need to query the current document's collections to find the correct element and query for the value at it.

Web -> Win32 Path

As you have seen in the sample, by pushing an HTML button, you can hide/show a treeview, set the status bar text, and so on.

Well, we can do this work in two ways, using handlers as described above, or using another technique:

You can put an object reference (COM Object Dual Interface) using the CAxWindow::SetExternalDisptach() method. Once you have put a reference to this method, you can access methods of this object using script code at the Explorer page level external.MyMethod)().

The steps needed to do this are:

EVENTFN CWTLIExplorer::OnDocumentComplete( IDispatch* pDisp,  VARIANT* URL )

    CAxWindow::SetExternalDispatch( (IDispatch*) _Module.m_LibraryObject );

    // ignore about:blank
    if ( _bstr_t( bstrLocation ) != _bstr_t("about:blank") )
        // Notify parent window we are ready and loaded...
    CWindow(GetParent()).SendMessage( WM_HTML_SETHANDLERS ,0,0 );


Once you have set the main object library, as you can see at the sample.html script code, you can do calls to the methods:

     window.external.MyMessageBox "Hello!","Bye!"
     window.external.statusbartext = text
     window.external.AddChildToTree( window.document.all("newitem").value )

You can use VBScript or JScript, there is no problem.

Closing words

I'm sure I will update this article soon, so any comment will be appreciated.

Well, that's all, I expect you find this article useful and helpful. If you think you have found anything wrong, feel free to contact me or solve it by yourself, I will be very happy to fix anything. Bye!!


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


About the Author

Jesus Salas
Spain Spain
No Biography provided

You may also be interested in...


Comments and Discussions

Questionwhen execute the demo in vs2008,the ie say the library not registered. Pin
bobbyj9715-May-12 15:18
memberbobbyj9715-May-12 15:18 
Questionit breaks in VC++ 8 Pin
2simple17-Sep-06 9:14
member2simple17-Sep-06 9:14 
AnswerRe: it breaks in VC++ 8 (Solved) Pin
Jesus Salas6-Nov-06 3:32
memberJesus Salas6-Nov-06 3:32 
GeneralHere are couple bugs Pin
vildanov21-Dec-05 13:05
membervildanov21-Dec-05 13:05 
GeneralRe: Here are couple bugs Pin
Jesus Salas22-Dec-05 2:03
memberJesus Salas22-Dec-05 2:03 
GeneralRe: Here are couple bugs Pin
Jesus Salas22-Dec-05 2:12
memberJesus Salas22-Dec-05 2:12 
Questionhow can i make this? Pin
Alex Chew7-Dec-05 19:47
memberAlex Chew7-Dec-05 19:47 
AnswerRe: how can i make this? Pin
Jesus Salas14-Dec-05 10:09
memberJesus Salas14-Dec-05 10:09 
GeneralUsing put_onclick in MFC CHTMLView Pin
Crercio O. Silva12-May-05 14:58
memberCrercio O. Silva12-May-05 14:58 
GeneralRe: Using put_onclick in MFC CHTMLView Pin
Jesus Salas13-May-05 13:55
memberJesus Salas13-May-05 13:55 
Generalprogram not quit Pin
billhao3-Aug-03 18:13
memberbillhao3-Aug-03 18:13 
GeneralRe: program not quit Pin
Chus13-Aug-03 22:53
memberChus13-Aug-03 22:53 
Generalregistering server Pin
Anonymous10-Sep-02 3:13
sussAnonymous10-Sep-02 3:13 
GeneralRe: registering server Pin
Chus12-Sep-02 12:03
memberChus12-Sep-02 12:03 
GeneralRe: registering server Pin
Anonymous15-Sep-02 1:13
sussAnonymous15-Sep-02 1:13 
GeneralRe: registering server Pin
David Horner3-Aug-03 8:55
memberDavid Horner3-Aug-03 8:55 
GeneralMoving between element Pin
Davide Zaccanti9-Sep-02 6:17
memberDavide Zaccanti9-Sep-02 6:17 
GeneralRe: Moving between element Pin
Chus9-Sep-02 9:11
memberChus9-Sep-02 9:11 
GeneralRe: Moving between element Pin
barcarole20-Nov-02 14:46
memberbarcarole20-Nov-02 14:46 
GeneralNo Trabaja...Your code does not compile on my VC7 Pin
JuanValdez30-Aug-02 17:49
sussJuanValdez30-Aug-02 17:49 
GeneralRe: No Trabaja...Your code does not compile on my VC7 Pin
Chus30-Aug-02 23:54
memberChus30-Aug-02 23:54 
GeneralRe: No Trabaja...Your code does not compile on my VC7 Pin
Carl Berg3-Sep-02 3:48
memberCarl Berg3-Sep-02 3:48 
QuestionWorkspace for VC 6.0? Pin
clintsinger30-Aug-02 13:30
memberclintsinger30-Aug-02 13:30 
AnswerRe: Workspace for VC 6.0? Pin
Chus30-Aug-02 23:56
memberChus30-Aug-02 23:56 
GeneralRe: Workspace for VC 6.0? Pin
HENRYTEHRANI15-Jun-07 11:18
memberHENRYTEHRANI15-Jun-07 11:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02-2016 | 2.8.180318.3 | Last Updated 22 Dec 2005
Article Copyright 2002 by Jesus Salas
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid