// ObjVwCtl.cpp : Implementation of CObjVw
#include "stdafx.h"
#include "ObjVw.h"
#include "ObjVwCtl.h"
/////////////////////////////////////////////////////////////////////////////
// CObjVw
STDMETHODIMP CObjVw::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IObjVw,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
HRESULT CObjVw::SetClientSite(IOleClientSite *pClientSite)
{
HRESULT hr = S_OK;
if(NULL != pClientSite)
{
ATLTRACE(_T("SetClientSite called\n"));
if(m_spClientSite)
m_spClientSite->Release();
m_spClientSite = pClientSite; // This AddRefs the client site
}
else
{
_ASSERT(0 != m_dwAdviseCookie);
_ASSERT(m_spWebBrowser != NULL);
ATLTRACE(_T("SetClientSite NULL called\n"));
hr = AtlUnadvise( m_spWebBrowser, __uuidof(SHDocVw::DWebBrowserEvents2),
m_dwAdviseCookie );
m_spWebBrowser.Release();
returnS_OK;
}
try
{
IServiceProviderPtr spSP((LPOLECLIENTSITE)m_spClientSite);
if(NULL == spSP)
return hr;
spSP->QueryService(__uuidof(SHDocVw::IWebBrowserApp),
__uuidof(SHDocVw::IWebBrowser2), (void**)&m_spWebBrowser);
hr = AtlAdvise(m_spWebBrowser, GetControllingUnknown(),
__uuidof(SHDocVw::DWebBrowserEvents2), &m_dwAdviseCookie);
}
catch(...)
{
return S_FALSE;
}
return hr;
}
HRESULT CObjVw::OnDraw(ATL_DRAWINFO& di)
{
return S_OK;
}
STDMETHODIMP CObjVw::Recalc()
{
EnumFrames();
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// CIEDriveView message handlers
void CObjVw::EnumFrames()
{
// Empty the tree view
TreeView_DeleteAllItems(m_ctlSysTreeView32.m_hWnd);
try
{
MSHTML::IHTMLDocument2Ptr spDocument(m_spWebBrowser->GetDocument());
RecurseWindows(spDocument);
}
catch(_com_error Error)
{
ATLTRACE(Error.ErrorMessage());
}
catch(...)
{
ATLTRACE(_T("Unspecified exception thrown in OnTestEnumlinks\n"));
}
HTREEITEM hFirst = TreeView_GetRoot(m_ctlSysTreeView32.m_hWnd);
TreeView_Expand(m_ctlSysTreeView32.m_hWnd, hFirst, TVE_EXPAND);
}
void CObjVw::RecurseWindows(MSHTML::IHTMLDocument2Ptr spDocument, LPVOID pvTreeParent)
{
// I am passing in a pointer to the parent node to insert items in the Tree View.
// Obviously this is specific to this application and has little to do with
// enumerating frames in a document.
LPVOID ppvTree = NULL;
if(spDocument == NULL)
// Not an HTLM document
return;
try
{
// Insert a root node for this page.
_bstr_t bstrDocTitle = spDocument->Gettitle();
_bstr_t bstrNoTitle("");
if(bstrDocTitle == bstrNoTitle)
bstrDocTitle = "Untitled Document";
InsertTreeItem(bstrDocTitle, pvTreeParent, &ppvTree);
// Find out if this page has a "BODY". If it does, it will not have a
// <FRAMESET> but may still have a floating frame.
MSHTML::IHTMLElementPtr spBodyElement = spDocument->Getbody();
_bstr_t bstrBody("BODY");
_bstr_t bstrTagName = spBodyElement->GettagName();
if(bstrBody == bstrTagName)
{
ATLTRACE(_T("Found a body\n"));
GetPageContents(spDocument, ppvTree);
}
MSHTML::IHTMLFramesCollection2Ptr spFrameset = spDocument->Getframes();
for(long i = 0; i < spFrameset->Getlength(); i++)
{
_variant_t va(i, VT_I4);
MSHTML::IHTMLWindow2Ptr spWindow2Next = spFrameset->item(&va);
MSHTML::IHTMLDocument2Ptr spNextDocPtr;
try
{
// This will die in the case of a cross frame security violation.
// It would be a security risk to allow a page to access the contents
// of a page in another domain or zone.
spNextDocPtr = spWindow2Next->Getdocument();
}
catch(_com_error Error)
{
HRESULT hr = 0x80070005;
ATLTRACE(Error.ErrorMessage());
if(hr == Error.Error())
InsertTreeItem(_T("Page - Access Denied"), ppvTree, NULL);
continue;
}
catch(...)
{
ATLTRACE(_T("Unspecified exception thrown in RecurseWindows\n"));
continue;
}
RecurseWindows(spNextDocPtr, ppvTree);
}
}
catch(_com_error Error)
{
ATLTRACE(Error.ErrorMessage());
}
catch(...)
{
ATLTRACE(_T("Unspecified exception thrown in RecurseWindows\n"));
}
}
void CObjVw::GetPageContents(MSHTML::IHTMLDocument2Ptr spDocument, LPVOID pvTreeParent)
{
try
{
MSHTML::IHTMLElementPtr spAnElement;
MSHTML::IHTMLElementCollectionPtr spAllElements = spDocument->Getall();
for(long i = 0; i < spAllElements->Getlength(); i++)
{
_variant_t va(i, VT_I4);
spAnElement = spAllElements->item(va);
_bstr_t bstrIsControl("OBJECT");
_bstr_t bstrIsLink("A");
_bstr_t bstrTagName = spAnElement->GettagName();
if(bstrTagName == bstrIsControl)
{
// This will get you any ActiveX controls in a page. It is possible
// to call methods and properties of the control off the IHTMLElementPtr.
////This is for illustration only
//{
//OLECHAR* rgwzCaption[] = {OLESTR("Caption")};
//DISPID rgdispidCaption[1];
//
//_bstr_t bstrLabel1("Label1");
//if(spAnElement->Getid() == bstrLabel1)
//{
//IDispatchPtr pDispatch(spAnElement);
//HRESULT hr = pDispatch->GetIDsOfNames(IID_NULL, rgwzCaption, 1,
//LOCALE_SYSTEM_DEFAULT, rgdispidCaption);
//
//if(SUCCEEDED(hr))
//{
//// You would call Invoke at this point
//}
//}
//}
_bstr_t bstrTagID("ActiveX Control - ");
bstrTagID += spAnElement->Getid();
InsertTreeItem(bstrTagID, pvTreeParent, NULL);
}
if(bstrTagName == bstrIsLink)
{
MSHTML::IHTMLAnchorElementPtr spAnchor(spAnElement);
_bstr_t bstrHref = spAnchor->Gethref();
InsertTreeItem(bstrHref, pvTreeParent, NULL);
}
}
}
catch(_com_error Error)
{
ATLTRACE(Error.ErrorMessage());
}
catch(...)
{
ATLTRACE(_T("Unspecified exception thrown in GetPageContents\n"));
}
}
bool CObjVw::InsertTreeItem(LPTSTR pszItemText, LPVOID pvTreeParent, LPVOID* ppvTree)
{
TV_ITEM tvitem;
TV_INSERTSTRUCT tvis;
HTREEITEM* ppTree = (HTREEITEM*)ppvTree;
HTREEITEM pTreeParent = (HTREEITEM)pvTreeParent;
HTREEITEM pretTree;
tvitem.mask = TVIF_TEXT;
tvitem.pszText = pszItemText;
tvitem.cchTextMax = _tcslen(pszItemText);
tvis.item = tvitem;
tvis.hInsertAfter = (HTREEITEM)TVI_LAST;
tvis.hParent = pTreeParent;
pretTree = (HTREEITEM)::SendMessage(m_ctlSysTreeView32.m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis);
if(!pretTree)
return false;
if ( ppvTree )
(*ppvTree) = (LPVOID)pretTree;
return true;
}
// DWebBrowserEvents2
STDMETHODIMP CObjVw::StatusTextChange(BSTR Text)
{
ATLTRACE(_T("StatusTextChange called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::ProgressChange(long Progress, long ProgressMax)
{
ATLTRACE(_T("ProgressChange called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::CommandStateChange(long Command, VARIANT_BOOL Enable)
{
ATLTRACE(_T("CommandStateChange called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::DownloadBegin()
{
ATLTRACE(_T("DownloadBegin called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::DownloadComplete()
{
ATLTRACE(_T("DownloadComplete called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::TitleChange(BSTR Text)
{
ATLTRACE(_T("TitleChange called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::PropertyChange(BSTR szProperty)
{
ATLTRACE(_T("PropertyChange called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::BeforeNavigate2(IDispatch* pDisp, VARIANT* URL, VARIANT* Flags,
VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers,
VARIANT_BOOL* Cancel)
{
ATLTRACE(_T("BeforeNavigate2 called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::NewWindow2(IDispatch** ppDisp, VARIANT_BOOL* Cancel)
{
ATLTRACE(_T("NewWindow2 called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::NavigateComplete2(IDispatch* pDisp, VARIANT* URL)
{
ATLTRACE(_T("NavigateComplete2 called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::DocumentComplete(IDispatch* pDisp, VARIANT* URL)
{
// DocumentComplete is fired for each frame that has completed loading.
// The outer most frame will fire last.
ATLTRACE(_T("DocumentComplete called\n"));
if(m_spWebBrowser == pDisp)
{
EnumFrames();
}
return S_OK;
}
STDMETHODIMP CObjVw::OnQuit()
{
ATLTRACE(_T("OnQuit called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::OnVisible(VARIANT_BOOL Visible)
{
ATLTRACE(_T("OnVisible called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::OnToolBar(VARIANT_BOOL ToolBar)
{
ATLTRACE(_T("OnToolBar called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::OnMenuBar(VARIANT_BOOL MenuBar)
{
ATLTRACE(_T("OnMenuBar called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::OnStatusBar(VARIANT_BOOL StatusBar)
{
ATLTRACE(_T("OnStatusBar called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::OnFullScreen(VARIANT_BOOL FullScreen)
{
ATLTRACE(_T("OnFullScreen called\n"));
return S_OK;
}
STDMETHODIMP CObjVw::OnTheaterMode(VARIANT_BOOL TheaterMode)
{
ATLTRACE(_T("OnTheaterMode called\n"));
return S_OK;
}