Click here to Skip to main content
11,430,053 members (76,165 online)
Click here to Skip to main content

WTL Class for ActiveX Hosting

, 6 Nov 2006
Rate this:
Please Sign up or sign in to vote.
WTL Helper classes for Event Sink and ActiveX hosting

Introduction

WTL is the best library for Win32 Programming I have seen, simple and powerful. But sometimes during a period of time I have to change my mind and work with other libraries and tools, and then I forget some basic ATL/WTL concepts like:

  • Event Sink implementations
  • ActiveX instancing
  • Other basic hard-to-forget concepts

For this reason I'm developing a little library in a WTL like fashion that will help me, (and maybe someone out there), to make my life easier with WTL.

CWTLAxControl

This class and other related classes in this article will help you to make your job with ActiveX controls easier.

CWTLAxControl is a class that implements :

  • SmartPointer ( CComPtr<> ).
  • CWindowImpl<> ( CAxWindow ).
  • IDispEventImpl<>.

Maybe it seems to be a hard class to use , but wait a minute and take a look at the next IExplorer implementation, using this class you will have access to the IWebBrowser2 methods interface via "->" ( smart pointer ), window messages handling (Host window) and Sink Events events fired from ActiveX hosted to your own event handlers.

        
#define EVENTFN void __stdcall

class CWTLIExplorer : public CWTLAxControl<CWTLIExplorer,IWebBrowser2>
{
    public:
        // BEGIN_MSG_MAP() ... END_MSG_MAP() is optional
        
        BEGIN_MSG_MAP( CWTLIExplorer  )            
            MESSAGE_HANDLER(WM_CREATE,OnCreate) 
        END_MSG_MAP() 
        
        LRESULT OnCreate(UINT uMsg, WPARAM wParam , LPARAM lParam,
                BOOL& bHandled) 
        { 

            // First you must call CWTLAxControl<...,...>::OnCreate 
            // ( it set bHandled = true )

            return CWTLAxControl<CWTLIExplorer,IWebBrowser2,>::OnCreate(
                    uMsg, wParam, lParam, bHandled );
        }

        // SINK_ENTRY(...,...,...) is optional, BEGIN_SINK_MAP()
        // ... should be there

        BEGIN_SINK_MAP( CWTLIExplorer )
            SINK_ENTRY(0, DISPID_NAVIGATECOMPLETE2, OnNavigateComplete2 )
        END_SINK_MAP()
        
        EVENTFN OnNavigateComplete2( IDispatch* pDisp,  VARIANT* URL )
        {
            MessageBox( "OnNavigateComplete2" );
        }
};
        

Inside CWTLAxControl

Well, if you like the above implementation then it is time to get a more detailed view of how it works.

The first step is to take a look into the main parent class CWTLAxControl that looks like:

template <class T, class Interface>
class CWTLAxControl :    public CComPtr<Interface>,
            public CWindowImpl<CWTLAxControl,CAxWindow>, 
            public CWTLDispEventHelper<T,Interface>
{
    public:

    BEGIN_MSG_MAP(CWTLAxControl)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)
    END_MSG_MAP()

    LRESULT OnCreate( UINT uMsg, WPARAM wParam , LPARAM lParam, 
           BOOL & bHandled )
    {
        LRESULT lRet;
        // We must call DefWindowProc before we can attach to the control.
        lRet = DefWindowProc( uMsg, wParam,lParam );
        // Get the Pointer to the control with Events (true)
        AttachControl(true);
        return lRet;
    }


    HRESULT AttachControl( BOOL bWithEvents = false ) 
    {
        HRESULT hr = S_OK;
        CComPtr<IUnknown> spUnk;
        // Get the IUnknown interface of control
        hr |= AtlAxGetControl( m_hWnd, &spUnk);

        if (SUCCEEDED(hr))
            // Query our interface
            hr |= spUnk->QueryInterface( __uuidof(Interface), 
                   (void**) (CComPtr<Interface>*)this);

        if ( bWithEvents && ! FAILED(hr) )
             // Start events
             hr|= EasyAdvise( spUnk );

        return hr;
    };
};
        

This class helps us to attach our CComPtr to the ActiveX control using the AttachControl method when it receives the WM_CREATE message. Furthermore this class is derived from CWindowImpl that give us the chance to handle all the windows messages that we'll need.

The last class CWTLDispEventHelper will help us to setup the correct IDispEventImpl implementation.

Inside CWTLDispEventHelper

This class will help us to setup the Event Sink for our control and looks like:
template <class T,class Interface>
class CWTLDispEventHelper : public IDispEventImpl<0,T>
{
    public:
                CComPtr<IUnknown> m_pUnk;
        
        HRESULT EasyAdvise(IUnknown* pUnk) 
        {  
            m_pUnk = pUnk;
            AtlGetObjectSourceInterface(pUnk,&m_libid, &m_iid, 
                 &m_wMajorVerNum, &m_wMinorVerNum);
            return DispEventAdvise(pUnk, &m_iid);
        }
        HRESULT EasyUnadvise() 
        { 
            AtlGetObjectSourceInterface(m_pUnk,&m_libid, 
                  &m_iid, &m_wMajorVerNum, &m_wMinorVerNum);
            return DispEventUnadvise(pUnk, &m_iid);
      }

};
        
It has only two methods EasyAdvise to setup the Event Sink handler and EasyUnadvise to deactivate it.

How to create the Control

Well, this is the easiest thing, the normal way we use to create any window in WTL:
[...]
CWTLIExplorer  m_pBrowser;
[...]
            
m_pBrowser.Create(    m_hWnd, rcDefault, _T("about:blank"),
        WS_HSCROLL| WS_VSCROLL| WS_CHILD | WS_VISIBLE | 
        WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
m_pBrowser->Navigate(_bstr_t("http://www.codeproject.com"),NULL,
        NULL,NULL,NULL);

        

We can change the _T("about:blank") by the CLSID of the control we want to create "{XXXXX-XXXXX-XXXXX...}".

Closing Words

Well, I expect you will find this article useful and helpful for you, if this is the case and you find anything wrong here, please, send me an email and I will be very happy to solve the mistake and re-upload this article. Bye!

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

Share

About the Author

Jesus Salas
CEO wave-vs.net
Spain Spain
No Biography provided

Comments and Discussions

 
QuestionProblem with the keyboard responce [modified] Pin
BlackGad25-Jul-07 10:12
memberBlackGad25-Jul-07 10:12 
GeneralCan't compile with VS 2005 Pin
Magnus Persson1-Nov-06 4:43
memberMagnus Persson1-Nov-06 4:43 
GeneralRe: Can't compile with VS 2005 (Solved) [modified] Pin
Jesus Salas6-Nov-06 4:28
memberJesus Salas6-Nov-06 4:28 
GeneralRe: Can't compile with VS 2005 (Solved) Pin
Magnus Persson6-Nov-06 5:28
memberMagnus Persson6-Nov-06 5:28 
GeneralRe: Can't compile with VS 2005 (Solved) [modified] Pin
Jesus Salas6-Nov-06 6:09
memberJesus Salas6-Nov-06 6:09 
GeneralRe: Can't compile with VS 2005 (Solved) Pin
Prabhat.Singh20-Nov-07 3:12
memberPrabhat.Singh20-Nov-07 3:12 
GeneralActiveX in dialog Pin
Anagor20-Apr-05 4:46
sussAnagor20-Apr-05 4:46 
GeneralCompile errors Pin
Robert Edward Caldecott17-Jan-05 1:30
memberRobert Edward Caldecott17-Jan-05 1:30 
GeneralRe: Compile errors Pin
ecmel2-Feb-07 8:54
memberecmel2-Feb-07 8:54 
GeneralRe: Compile errors Pin
Member 34721704-Mar-09 23:15
memberMember 34721704-Mar-09 23:15 
GeneralAmbiguous Pin
Balkrishna Talele3-Jan-04 1:13
memberBalkrishna Talele3-Jan-04 1:13 
GeneralRe: Ambiguous Pin
Vincent J Palodichuk4-Jan-04 17:30
memberVincent J Palodichuk4-Jan-04 17:30 
GeneralRe: Ambiguous Pin
Balkrishna Talele4-Jan-04 19:37
memberBalkrishna Talele4-Jan-04 19:37 
GeneralAdd support for IDocHostUIHandler Pin
Tommy2k21-Jul-03 9:29
memberTommy2k21-Jul-03 9:29 
GeneralRe: Add support for IDocHostUIHandler Pin
Chus21-Jul-03 23:33
memberChus21-Jul-03 23:33 
GeneralRe: Add support for IDocHostUIHandler Pin
Tommy2k26-Jul-03 4:04
memberTommy2k26-Jul-03 4:04 
GeneralRe: Add support for IDocHostUIHandler Pin
David Horner3-Aug-03 19:30
memberDavid Horner3-Aug-03 19:30 
GeneralRe: Add support for IDocHostUIHandler Pin
Chus14-Aug-03 0:02
memberChus14-Aug-03 0:02 
QuestionSample project? Pin
Tommy2k20-Jul-03 2:13
memberTommy2k20-Jul-03 2:13 
AnswerRe: Sample project? Pin
Chus21-Jul-03 2:57
memberChus21-Jul-03 2:57 
GeneralRe: Sample project? Pin
Tommy2k21-Jul-03 6:37
memberTommy2k21-Jul-03 6:37 
GeneralAssertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?" Pin
ohadp21-Apr-03 1:16
sussohadp21-Apr-03 1:16 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?" Pin
.S.Rod.21-Apr-03 1:27
member.S.Rod.21-Apr-03 1:27 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?" Pin
ohadp21-Apr-03 1:37
memberohadp21-Apr-03 1:37 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?" Pin
.S.Rod.21-Apr-03 5:57
member.S.Rod.21-Apr-03 5:57 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?" Pin
Anonymous21-Apr-03 7:03
sussAnonymous21-Apr-03 7:03 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
erez_me7-Mar-05 19:44
membererez_me7-Mar-05 19:44 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
Jesus Salas8-Mar-05 7:05
memberJesus Salas8-Mar-05 7:05 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
shangwa18-Aug-05 0:33
membershangwa18-Aug-05 0:33 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
medovina28-Nov-03 17:17
membermedovina28-Nov-03 17:17 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
lvyu13-Sep-04 20:44
memberlvyu13-Sep-04 20:44 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
R. Douglas Barbieri30-Sep-04 12:45
memberR. Douglas Barbieri30-Sep-04 12:45 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
Robert Edward Caldecott17-Jan-05 0:58
memberRobert Edward Caldecott17-Jan-05 0:58 
GeneralRe: Assertion: !InlineIsEqualGUID(*m_plibid, GUID_NULL) &amp;&amp; &quot;Did you forget to pass the LIBID to CComModule::Init?&quot; Pin
Nguyen Tran Trung21-Feb-05 17:50
memberNguyen Tran Trung21-Feb-05 17:50 
GeneralDISPID_BEFORENAVIGATE2 Pin
arctia1-Apr-03 5:12
memberarctia1-Apr-03 5:12 
GeneralRe: DISPID_BEFORENAVIGATE2 Pin
Chus7-Apr-03 2:40
memberChus7-Apr-03 2:40 
Questionthis should be one of the real advantage of wtl? Pin
johnthan13-Nov-02 12:23
memberjohnthan13-Nov-02 12:23 
QuestionCan this help me use an ActiveX Grid in a View Pin
Jose Cruz4-Oct-02 8:11
memberJose Cruz4-Oct-02 8:11 
GeneralVery Good WTL sample Pin
aefimov6427-Aug-02 4:09
memberaefimov6427-Aug-02 4:09 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150428.2 | Last Updated 6 Nov 2006
Article Copyright 2002 by Jesus Salas
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid