#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( LPCTSTR 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( 0 ), (IDispatch**) &pDispatch);
*ppDispatch = pDispatch ;
return hr;
}
HRESULT QueryHtmlElementFormElement( LPCTSTR FormName, LPCTSTR ElementName, LPDISPATCH * ppDispatch )
{
CComPtr<IDispatch> pDispatch;
CComPtr<IHTMLElementCollection> pAll;
CComPtr<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 ), _variant_t( 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 ), _variant_t( 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
::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 IDisptach 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 ) ;
}
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;
CComPtr<IHTMLOptionElement> pOption;
pElement->item( _variant_t( p ), _variant_t( NULL ), &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") )
GetParent().SendMessage( WM_HTML_SETHANDLERS ,0,0 );
}
CComPtr<IHTMLElement2> & GetHtmlElement( CString & name )
{
}
};