Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Web Win32/WTL Hybrid

, 22 Dec 2005
How to implement a two-way communication path from IExplorer and WTL code
webwin32sample.zip
html
res
toolbar.bmp
WebWin32Sample.exe.manifest
WebWin32Sample.ico
WebWin32SampleDoc.ico
WebWin32EventHandler.rgs
WebWin32HTMLEventHandler.rgs
WebWin32Lib.rgs
WebWin32Sample.rgs
WebWin32Sampleps.def
WebWin32Sampleps.mk
webwin32samplevc6.zip
toolbar.bmp
WebWin32Sample.exe.manifest
WebWin32Sample.ico
WebWin32Sampledoc.ico
WebWin32Sampleps.def
WebWin32Sample.dsp
WebWin32Sample.dsw
WebWin32Sampleps.mk
WebWin32Sample.opt
WebWin32Sample.plg
QQQQ.rgs
WebWin32EventHandler.rgs
WebWin32HTMLEventHandler.rgs
WebWin32Lib.rgs
WebWin32Sample.rgs
WebWin32Sample.idl.seg
WebWin32Sample.tlb
#include "wtlext.h"
#include <ExDispid.h>
#include <mshtml.h>
#include <comdef.h>


#include "WebWin32EventHandler.h"

#define EVENTFN void __stdcall

#define WM_HTML_SETHANDLERS WM_USER + 1

class CWTLIExplorer : public CWTLAxControl<CWTLIExplorer,IWebBrowser2>
{
	public:
		CComPtr<IHTMLDocument2>  pDocument;
		CComPtr<IHTMLWindow2>    pWindow;
		CComPtr<IWebBrowser>     pWebBrowser;

		~CWTLIExplorer()
		{
			// Release Library from external 
			CAxWindow::SetExternalDispatch( ( IDispatch * ) NULL );
			
			ReleaseAll();
		}

		BEGIN_SINK_MAP( CWTLIExplorer )
			SINK_ENTRY(0, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete )
		END_SINK_MAP()

		HRESULT QueryHtmlElement( LPCSTR ElementName, LPDISPATCH * ppDispatch )
		{
			CComPtr<IDispatch>				pDispatch;
			CComPtr<IHTMLElementCollection> pAll;
			_bstr_t FieldToSearch( ElementName );
			HRESULT hr;
			
			hr = pDocument->get_all( &pAll );
			if ( !FAILED( hr ) )
					// query form element
				hr = pAll->item( _variant_t( FieldToSearch ), _variant_t( (LONG)0 ), (IDispatch**) &pDispatch);
			*ppDispatch = pDispatch ;

			return hr;
		}
		HRESULT QueryHtmlElementFormElement( LPCTSTR FormName, LPCTSTR ElementName, LPDISPATCH * ppDispatch )
		{
			CComPtr<IDispatch>				pDispatch;
			CComPtr<IHTMLElementCollection> pAll;
			CComQIPtr<IHTMLFormElement>		pForm;
			
			_bstr_t FormToSearch( FormName );
			_bstr_t FieldToSearch( ElementName );
		

			HRESULT hr;

			// Get document.all from html page

			hr = pDocument->get_all( &pAll );

			if ( !FAILED( hr ) )
					// query form element
				hr = pAll->item( _variant_t( FormToSearch ), CComVariant( 0 ), (IDispatch**) &pDispatch);

			if ( !FAILED( hr ) ) 
			{
				// QueryInterface...
			    pForm = pDispatch;
				// We want to reuse it
				pDispatch.Release();
			}
			// query the field into form items collection 
			if ( !FAILED(hr) )
				 hr = pForm->item( _variant_t( FieldToSearch ), CComVariant( 0 ), (IDispatch**) &pDispatch);
			*ppDispatch = pDispatch ;
			return  hr;
		}

		HRESULT QueryHtmlElementValueTextBox( CString & retVal, LPCTSTR Form, LPCTSTR Field, BOOL bPutValue = false )
		{
			LPDISPATCH pDispatch;
			CComQIPtr<IHTMLInputElement> pElement;
			
			BSTR bstrValue;
			HRESULT hr;
			QueryHtmlElementFormElement( Form, Field, & pDispatch );
			pElement = pDispatch;
			if ( pElement )
			{
				
				if ( ! bPutValue )
				{
					// GetValue
					hr |= pElement->get_value( &bstrValue );
					// set retval
					retVal = bstrValue;
				}
				else
					hr |= pElement->put_value( _bstr_t( retVal ) );
			}
			return hr;
		}
		HRESULT QueryHtmlElementValueCheckBox( BOOL & retVal, LPCTSTR Form, LPCTSTR Field, BOOL bPutValue = false )
		{
			LPDISPATCH pDispatch;
			CComQIPtr<IHTMLInputElement> pElement;
			
			HRESULT hr;
			QueryHtmlElementFormElement( Form, Field, & pDispatch );
			pElement = pDispatch;
			if ( pElement )
			{
				
				if ( ! bPutValue )
				{
					// GetValue
					VARIANT_BOOL bChecked;
					hr |= pElement->get_checked( &bChecked);
					// set retval
					retVal = bChecked == VARIANT_TRUE ? true : false;
				}
				else
				{
					VARIANT_BOOL bChecked;
					bChecked = retVal == TRUE ? VARIANT_TRUE : VARIANT_FALSE;
					hr |= pElement->put_checked( bChecked );
				}
			}
			return hr;
		}

		HRESULT SetObjectHandler( INT iType, LPCTSTR objectName,  DWORD pMember, DWORD pThis)
		{
			LPDISPATCH				ppHandler;
			CComPtr<IDispatch>		pDispatch;
			CComQIPtr<IHTMLElement> pElement;

			IWebWin32EventHandler * pEventHandler;

			// Create a new COM-Dual Interface-IDispatch-Object
			CComPtr<IWebWin32EventHandler> pp;
			HRESULT hr ;
			
			hr = ::CoCreateInstance( _uuidof( WebWin32EventHandler  ), NULL, CLSCTX_ALL, __uuidof(IWebWin32EventHandler), (void**) &pEventHandler );

			// Set the pointer to the member that will handle this event...
			pEventHandler->SetHandler( pThis, pMember );

			// Query object for IDispatch implementation
			pEventHandler->QueryInterface( IID_IDispatch, (void**)& ppHandler );

			// Query the object to set it handle (part 1)
			if ( !FAILED( QueryHtmlElement( objectName, &pDispatch ) ) )
			{
				// Query the IHTMLElement Interface (part 2)
				pElement = pDispatch;
				_variant_t vHandler(ppHandler);

				// Put the new object handler, we should use a VARIANT type
				pElement->put_onclick( vHandler ) ;
			}
			pEventHandler->Release();

			return S_OK;
		}


		HRESULT QueryHtmlElementValueListBox( CString & retVal, LPCTSTR Form, LPCTSTR Field, BOOL bPutValue = false )
		{
			LPDISPATCH pDispatch;
			CComQIPtr<IHTMLSelectElement> pElement;
			

			HRESULT hr;
			hr = QueryHtmlElementFormElement( Form, Field, & pDispatch );
			pElement = pDispatch;
			if ( pElement )
			{
				
				if ( ! bPutValue )
				{
					LONG p;
					pElement->get_selectedIndex( &p );
					if ( p != -1 ) // we have some option selected
					{	
						CComPtr<IDispatch> pValue;
						CComQIPtr<IHTMLOptionElement> pOption;
						pElement->item( _variant_t( p ),  CComVariant( 0 ), &pValue );
						pOption = pValue;
						BSTR value;
						pOption->get_value( &value );
						retVal = CString( value );
					}
					else
					{
						retVal = "";
					}
					// GetValue

				}
				else
				{
				}
			}
			return hr;
		}

		void ReleaseAll()
		{
			// If we are an old page... we must free some pointers...
			if ( pWebBrowser )
				 pWebBrowser.Release();

			if ( pDocument )
				 pDocument.Release();

			if ( pWindow )
				 pWindow.Release();
		}


		EVENTFN OnDocumentComplete( IDispatch* pDisp,  VARIANT* URL )
		{
			CComPtr<IHTMLWindow2>    pWindow2;

			HRESULT hr;

			ReleaseAll();

			hr = pDisp->QueryInterface( __uuidof( IWebBrowser2 ) , (void**) & pWebBrowser );

			hr |= pWebBrowser->get_Document( ( LPDISPATCH * ) &pDocument );

			IHTMLLocation *p;
			pDocument->get_location( &p );
			BSTR Q;
			p->toString(&Q );
			p->Release();
			
			hr |= pDocument->get_parentWindow( & pWindow );
			
			CAxWindow::SetExternalDispatch( (IDispatch*) _Module.m_LibraryObject );
			

			// ignore about:blank
			if ( _bstr_t( Q ) != _bstr_t("about:blank") )
				 CWindow(GetParent()).SendMessage( WM_HTML_SETHANDLERS ,0,0 );
			
		}

		CComPtr<IHTMLElement2> & GetHtmlElement( CString & name )
		{
		}
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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

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