//========================================================================
//TITLE:
// CBrowser的世界很精彩
//AUTHOR:
// norains
//DATE:
// Saturday 26-January-2008
//Environment:
// VS2005 + SDK-WINCE5.0-MIPSII(Include WEB browser component)
//========================================================================
真应该感谢微软,在WinCE中有如此丰富的COM控件,让我们得以如此简便地编写浏览器,甚至还能借助该功能为我们的程序增添异样的光彩.
如果要编写一个基于COM的浏览器,我们需要用到如下的接口:IOleContainer,IOleClientSite,IOleInPlaceSite,IOleControlSite,DWebBrowserEvents2,IWebBrowser2,IConnectionPoint,IOleObject.一下子看到如此多既陌生又似熟悉的玩意,不知道有没有人不晕的?反正我罗列出来的时候,自己已经晕了. :-) 幸运的是,本篇文章并不是讲解这些COM接口的具体功能方法,而是将它们聚合起来如何使用.如果你想熟悉以上的接口,强烈建议阅读相关的MSDN文档,比我这小菜在这班门弄斧要强多了.何况,这斧头我也确实不知道该如何挥舞~
还是和往常一样,将以上各大将军的聚合起来的CBrowser类拉出来遛一遛,代码如下:
//
// Browser.cpp: implementation of the CBrowser class.
//
//
#include "stdafx.h"
#include "Browser.h"
#include "exdispid.h"
//====================================================================
//Link the .lib
#pragma comment (lib,"Ole32.lib")
#pragma comment (lib,"Oleaut32.lib")
//====================================================================
/*
DEFINE_GUID(CLSID_WebBrowser, 0x8856F961L, 0x340A, 0x11D0, 0xA9, 0x6B, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2);
DEFINE_GUID(IID_IWebBrowser, 0xEAB22AC1L, 0x30C1, 0x11CF, 0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B);
DEFINE_GUID(IID_IWebBrowser2, 0xD30C1661L, 0xCDAF, 0x11D0, 0x8A, 0x3E, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0x6E);
DEFINE_GUID(DIID_DWebBrowserEvents, 0xEAB22AC2L, 0x30C1, 0x11CF, 0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B);
DEFINE_GUID(DIID_DWebBrowserEvents2, 0x34A715A0L, 0x6587, 0x11D0, 0x92, 0x4A, 0x00, 0x20, 0xAF, 0xC7, 0xAC, 0x4D);
DEFINE_GUID(IID_IWebBrowserApp, 0x0002DF05L, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
const GUID SID_SDocHost = { 0xc6504990, 0xd43e, 0x11cf, { 0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a}};
*/
//====================================================================
//Macro define
#define WND_CLASSTEXT("Browser_main")
#define WND_NAMETEXT("Browser_simple")
//The temporary file name for storing the HTML format text
#define FILE_TEMP_HTML_TEXTTEXT("DispHtmlText.html")
//====================================================================
//Static variable intialize
int CBrowser::m_s_iCountObject = 0;
//====================================================================
//
// Construction/Destruction
//
CBrowser::CBrowser():
m_pWB2(NULL),
m_pCP(NULL),
m_dwEventCookie(0),
m_lRef(0),
m_hInst(NULL),
m_hWndMain(NULL),
m_hWndBrowser(NULL),
m_pOleObj(NULL),
m_bInPlaceActive(FALSE)
{
//Set the temp html text file
m_s_iCountObject ++;
TCHAR szTmp[MAX_PATH] = {0};
_stprintf(szTmp,TEXT("%d%s"),m_s_iCountObject,FILE_TEMP_HTML_TEXT);
GetCurrentDirectory(m_szFileTmpHtml,MAX_PATH);
_tcscat(m_szFileTmpHtml,szTmp);
}
CBrowser::~CBrowser()
{
}
//------------------------------------------------------------------------
//Description:
// Browse to a URL
//
//------------------------------------------------------------------------
BOOL CBrowser::NavigateToURL(const WCHAR * pcszURL)
{
HRESULT hr;
// Check for the browser.
if (!m_pWB2)
{
return E_FAIL;
}
// Package the URL as a BSTR for Navigate.
VARIANT varURL;
V_VT(&varURL) = VT_EMPTY; //It's the same as : varURL.vt = VT_EMPTY;
if(pcszURL && pcszURL[0] != '/0')
{
V_VT(&varURL) = VT_BSTR; //It's the same as : varURL.vt = VT_BSTR;
varURL.bstrVal = SysAllocString(pcszURL);
if(varURL.bstrVal)
{
// Call IWebBrowser2::Navigate2 with no special options.
hr = m_pWB2->Navigate2(&varURL, NULL, NULL, NULL, NULL);
}
}
else
{
// If there is no URL, go to the default homepage.
hr = m_pWB2->GoHome();
}
// Clean up the BSTR if it exists.
VariantClear(&varURL);
return SUCCEEDED(hr);
}
//------------------------------------------------------------------------
//Description:
// Connect up the event sink
//
//------------------------------------------------------------------------
HRESULT CBrowser::RegisterBrowserEventSink()
{
HRESULT hr = S_FALSE;
IConnectionPointContainer *pCPCont = NULL;
DWebBrowserEvents2 *pEvents = NULL;
if (!m_pWB2)
{
goto CLEANUP;
}
// Get the connection point container for the browser object.
hr = m_pWB2->QueryInterface(IID_IConnectionPointContainer, (LPVOID *)&pCPCont);
if (FAILED(hr))
{
hr = S_FALSE;
goto CLEANUP;
}
// Look for DWebBrowserEvents2 connection point.
hr = pCPCont->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pCP);
if (FAILED(hr))
{
m_pCP = NULL;
goto CLEANUP;
}
// Get a DWebBrowserEvents2 pointer from the browser.
hr = QueryInterface(DIID_DWebBrowserEvents2, (LPVOID *)(&pEvents));
if (FAILED(hr))
{
goto CLEANUP;
}
// Add your event sink to the connectionpoint.
hr = m_pCP->Advise(pEvents, &(m_dwEventCookie));
if (FAILED(hr))
{
goto CLEANUP;
}
CLEANUP:
if (pCPCont)
{
pCPCont->Release();
}
if (pEvents)
{
pEvents->Release();
}
return hr;
}
//------------------------------------------------------------------------
//Description:
// IUnknown methods
//
//------------------------------------------------------------------------
STDMETHODIMP CBrowser::QueryInterface (REFIID riid, LPVOID * ppv)
{
if ((riid == IID_IOleContainer) || (riid == IID_IUnknown))
{
*ppv = (IOleContainer *) this;
}
else if (riid == IID_IOleClientSite)
{
*ppv = (IOleClientSite *)this;
}
else if (riid == IID_IOleInPlaceSite)
{
*ppv = (IOleInPlaceSite *)this;
}
else if (riid == IID_IOleWindow)
{
*ppv = (IOleWindow *)this;
}
else if (riid == IID_IOleControlSite)
{
*ppv = (IOleControlSite *)this;
}
else if ((riid == DIID_DWebBrowserEvents2) || (riid == IID_IDispatch))
{
*ppv = (DWebBrowserEvents2 *)this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
//---------------------------------------------------------------------
//Description:
//Increment object ref count
//
//----------------------------------------------------------------------
STDMETHODIMP_(ULONG) CBrowser::AddRef(void)
{
ULONG cnt;
cnt = (ULONG)InterlockedIncrement (&m_lRef);
return cnt;
}
//---------------------------------------------------------------------
//Description:
//Decrement object ref count
//
//----------------------------------------------------------------------
STDMETHODIMP_(ULONG) CBrowser::Release(void)
{
ULONG cnt;
cnt = (ULONG)InterlockedDecrement (&m_lRef);
if (cnt == 0)
{
delete this;
return 0;
}
return cnt;
}
//---------------------------------------------------------------------
//Description:
//static WndProc wrapper and actual WndProc
//
//----------------------------------------------------------------------
LRESULT CALLBACK CBrowser::StaticWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
CBrowser *pBrowser = (CBrowser*)GetWindowLong(hWnd, GWL_USERDATA);
if(pBrowser)
{
return pBrowser->WndProc(hWnd,wMsg,wParam,lParam);
}
else
{
return DefWindowProc(hWnd,wMsg,wParam,lParam);
}
}
//---------------------------------------------------------------------
//Description:
//Actual WndProc
//
//----------------------------------------------------------------------
LRESULT CBrowser::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg)
{
case WM_SIZE:
OnSize(hWnd,wMsg,wParam,lParam);
break;
}
return DefWindowProc(hWnd,wMsg,wParam,lParam);
}
//---------------------------------------------------------------------
//Description:
//Standard Win32 window class registration
//
//----------------------------------------------------------------------
BOOL CBrowser::RegisterMainWnd()
{
static BOOL bRegistered = FALSE;
WNDCLASS wc;
if(!bRegistered)
{
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)CBrowser::StaticWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = WND_CLASS;
if (RegisterClass(&wc))
{
bRegistered = TRUE;
}
}
return bRegistered;
}
//---------------------------------------------------------------------
//Description:
//Create a window to provide a work area for the browser
//
//----------------------------------------------------------------------
BOOL CBrowser::CreateMainWnd()
{
RECT rcWorkArea;
BOOL bResult = FALSE;
// Ensure that the browser window is registered.
if(!RegisterMainWnd())
{
goto Exit;
}
// Retrieve the system's work area in the RECT structure.
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
// Create the top-level browser window.
m_hWndMain = ::CreateWindowEx(WS_EX_TOPMOST,
WND_CLASS,
WND_NAME,
WS_TABSTOP,
rcWorkArea.left,
rcWorkArea.top,
rcWorkArea.right - rcWorkArea.left,
rcWorkArea.bottom - rcWorkArea.top,
NULL, NULL, m_hInst, 0);
if (IsWindow(m_hWndMain) == FALSE)
{
goto Exit;
}
// If the window is created successfully, store this object so the
//static wrapper can pass calls to the real WndProc.
SetWindowLong(m_hWndMain, GWL_USERDATA, (DWORD)this);
bResult = TRUE;
Exit:
return bResult;
}
//---------------------------------------------------------------------
//Description:
//Create the Web browser object.
//
//----------------------------------------------------------------------
HRESULT CBrowser::CreateBrowserObject()
{
HRESULT hr;
IUnknown *pUnk = NULL;
IOleObject *pObject = NULL;
RECT rc; // for activate
if (!m_pWB2)
{
// Create an instance of a web browser object (from Shdocvw.dll).
hr = CoCreateInstance(CLSID_WebBrowser,
NULL,
CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
IID_IUnknown, (LPVOID *)(&pUnk));
if (FAILED(hr))
{
goto CLEANUP;
}
// Retrieve an IOleObject interface to set up OLE activation.
hr = pUnk->QueryInterface(IID_IOleObject, (LPVOID *)(&pObject));
if (FAILED(hr))
{
goto CLEANUP;
}
// Check if Shdocvw requires a client site to be created first.
DWORD dwFlags;
hr = pObject->GetMiscStatus(DVASPECT_CONTENT, &dwFlags);
if (FAILED(hr))
{
goto CLEANUP;
}
if (dwFlags & OLEMISC_SETCLIENTSITEFIRST)
{
// Get an IOleClientSite instance from the browser and pass it to the browser.
IOleClientSite *pClientSite = NULL;
hr = QueryInterface(IID_IOleClientSite, (LPVOID *)(&pClientSite));
if (FAILED(hr))
{
goto CLEANUP;
}
hr = pObject->SetClientSite(pClientSite);
pClientSite->Release();
if (FAILED(hr))
{
goto CLEANUP;
}
}
// Activate the object.
// Store off the IOleObject reference.
m_pOleObj = pObject;
m_pOleObj->AddRef();
::GetClientRect(m_hWndMain, &rc);
hr = m_pOleObj->DoVerb(OLEIVERB_UIACTIVATE, NULL, this, 0, m_hWndMain, &rc);
if (FAILED(hr))
{
goto CLEANUP;
}
// Retrieve the IWebBrowser2 interface from the IOleObject.
hr = m_pOleObj->QueryInterface(IID_IWebBrowser2, (void **)&m_pWB2);
if (FAILED(hr))
{
goto CLEANUP;
}
}
CLEANUP:
if (pUnk)
{
pUnk->Release();
}
if (pObject)
{
pObject->Release();
}
return hr;
}
//---------------------------------------------------------------------
//Description:
//Create the object. After succeeded in call the function, you should
//call the Close() to release the resource when the object is never used.
//
//----------------------------------------------------------------------
BOOL CBrowser::Create(HINSTANCE hInst)
{
m_hInst = hInst;
BOOL bResult = FALSE;
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(FAILED(hr))
{
goto EXIT;
}
if(CreateMainWnd() == FALSE)
{
goto EXIT;
}
if(CreateBrowserWnd() == FALSE)
{
goto EXIT;
}
hr = RegisterBrowserEventSink();
if(FAILED(hr))
{
goto EXIT;
}
bResult = TRUE;
EXIT:
if(bResult == FALSE)
{
Close();
}
return TRUE;
}
//---------------------------------------------------------------------------------
//Description:
//IOleContainer methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::ParseDisplayName(IBindCtx *, LPOLESTR, ULONG *, IMoniker **)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
//IOleContainer methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::EnumObjects(DWORD, IEnumUnknown **)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
//IOleContainer methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::LockContainer(BOOL)
{
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleClientSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::SaveObject (void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleClientSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER * ppmk)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleClientSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetContainer(LPOLECONTAINER * ppContainer)
{
return E_NOINTERFACE;
}
//---------------------------------------------------------------------------------
//Description:
// IOleClientSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::ShowObject(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleClientSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnShowWindow(BOOL fShow)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleClientSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::RequestNewObjectLayout(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::CanInPlaceActivate(void)
{
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnInPlaceActivate(void)
{
m_bInPlaceActive = TRUE;
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnUIActivate(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetWindowContext(LPOLEINPLACEFRAME FAR *lplpFrame, LPOLEINPLACEUIWINDOW FAR *lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
GetClientRect(m_hWndMain, lprcPosRect);
GetClientRect(m_hWndMain, lprcClipRect);
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::Scroll(SIZE scrollExtent)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnUIDeactivate(BOOL fUndoable)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnInPlaceDeactivate(void)
{
m_bInPlaceActive = FALSE;
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::DiscardUndoState(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::DeactivateAndUndo(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleInPlaceSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnPosRectChange(LPCRECT lprcPosRect)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnControlInfoChanged(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::LockInPlaceActive(BOOL fLock)
{
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetExtendedControl(IDispatch** ppDisp)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::TransformCoords(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
{
return S_FALSE;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::OnFocus(BOOL fGotFocus)
{
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleControlSite methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::ShowPropertyFrame(void)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// DWebBrowserEvents and IDispatch methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetTypeInfoCount(UINT FAR* pctinfo)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// DWebBrowserEvents and IDispatch methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetTypeInfo(UINT itinfo,LCID lcid,ITypeInfo FAR* FAR* pptinfo)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// DWebBrowserEvents and IDispatch methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetIDsOfNames(REFIID riid,OLECHAR FAR* FAR* rgszNames,UINT cNames,LCID lcid, DISPID FAR* rgdispid)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// DWebBrowserEvents and IDispatch methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult,EXCEPINFO FAR* pexcepinfo,UINT FAR* puArgErr)
{
return DefDWebBrowserEventInvokeProc(dispidMember,riid,lcid,wFlags,pdispparams, pvarResult,pexcepinfo,puArgErr);
}
//---------------------------------------------------------------------------------
//Description:
// IOleWindow methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::GetWindow(HWND *phwnd)
{
*phwnd = m_hWndMain;
return S_OK;
}
//---------------------------------------------------------------------------------
//Description:
// IOleWindow methods
//
//----------------------------------------------------------------------------------
STDMETHODIMP CBrowser::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
//---------------------------------------------------------------------------------
//Description:
// This method sets an owning parent for the browser window
//
//Parameters:
//hWndParent : [in] The handle of the window parent
//prcPos : [in] The coordinate of the window in the parent window. If NULL, it would be full of the parent window.
//
//----------------------------------------------------------------------------------
void CBrowser::SetOwner(HWND hWndParent,const RECT *prcPos)
{
RECT rcWnd = {0};
LONG lStyle = GetWindowLong(m_hWndMain,GWL_STYLE);
if(hWndParent == NULL)
{
// Retrieve the system's work area in the RECT structure.
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
}
else
{
if(prcPos == NULL)
{
GetClientRect(hWndParent,&rcWnd);
}
else
{
rcWnd = *prcPos;
}
lStyle &= ~WS_POPUP;
lStyle |= WS_CHILD;
SetWindowLong(m_hWndMain,GWL_STYLE,lStyle);
}
SetParent(m_hWndMain,hWndParent);
MoveWindow(m_hWndMain,
rcWnd.left,
rcWnd.top,
rcWnd.right - rcWnd.left,
rcWnd.bottom - rcWnd.top,
TRUE);
if(hWndParent == NULL)
{
lStyle &= ~WS_CHILD;
lStyle |= WS_POPUP;
SetWindowLong(m_hWndMain,GWL_STYLE,lStyle);
}
}
//----------------------------------------------------------------------
//Description:
//Show the browser window
//
//----------------------------------------------------------------------
BOOL CBrowser::Show(BOOL bShow)
{
if(m_hWndMain == NULL)
{
return FALSE;
}
if(bShow == TRUE)
{
::ShowWindow(m_hWndMain,SW_SHOW);
SetForegroundWindow(m_hWndMain);
}
else
{
::ShowWindow(m_hWndMain,SW_HIDE);
}
return TRUE;
}
//---------------------------------------------------------------------
//Description:
//Create a ole window for browsing.
//
//----------------------------------------------------------------------
BOOL CBrowser::CreateBrowserWnd()
{
HRESULT hr = E_FAIL;
hr = CreateBrowserObject();
if(FAILED(hr))
{
return FALSE;
}
if (m_pWB2 != NULL)
{
IOleWindow *pWnd = NULL;
hr = m_pWB2->QueryInterface(IID_IOleWindow, (LPVOID *)(&pWnd));
if (FAILED(hr))
{
return FALSE;
}
if (pWnd != NULL)
{
hr = pWnd->GetWindow(&m_hWndBrowser);
pWnd->Release();
}
}
else
{
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------
//Description:
//On message WM_SIZE
//
//----------------------------------------------------------------------
void CBrowser::OnSize(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
//Move the browser window base on the main window
RECT rcWnd;
GetClientRect(hWnd, &rcWnd);
MoveWindow(m_hWndBrowser,
rcWnd.left,
rcWnd.top,
rcWnd.right - rcWnd.left,
rcWnd.bottom - rcWnd.top,
FALSE);
}
//---------------------------------------------------------------------
//Description:
//Cancels any pending navigation or download operation and stops any dynamic page elements,
//such as background sounds and animations
//
//----------------------------------------------------------------------
BOOL CBrowser::Stop()
{
if(m_pWB2 == NULL)
{
return E_FAIL;
}
return SUCCEEDED(m_pWB2->Stop());
}
//---------------------------------------------------------------------
//Description:
//Navigates backward one item in the history list.
//
//----------------------------------------------------------------------
BOOL CBrowser::GoBack()
{
if(m_pWB2 == NULL)
{
return E_FAIL;
}
return SUCCEEDED(m_pWB2->GoBack());
}
//---------------------------------------------------------------------
//Description:
//Navigates forward one item in the history list.
//
//----------------------------------------------------------------------
BOOL CBrowser::GoForward()
{
if(m_pWB2 == NULL)
{
return E_FAIL;
}
return SUCCEEDED(m_pWB2->GoForward());
}
//---------------------------------------------------------------------
//Description:
//Navigates to the current home or start page.
//
//----------------------------------------------------------------------
BOOL CBrowser::GoHome()
{
if(m_pWB2 == NULL)
{
return E_FAIL;
}
return SUCCEEDED(m_pWB2->GoHome());
}
//---------------------------------------------------------------------
//Description:
//Navigates to the current search page.
//
//----------------------------------------------------------------------
BOOL CBrowser::GoSearch()
{
if(m_pWB2 == NULL)
{
return E_FAIL;
}
return SUCCEEDED(m_pWB2->GoSearch());
}
//---------------------------------------------------------------------
//Description:
//Close the object to release the resource
//
//----------------------------------------------------------------------
void CBrowser::Close()
{
if(m_pOleObj != NULL)
{
m_pOleObj->Release();
m_pOleObj = NULL;
}
if(m_pWB2 != NULL)
{
m_pWB2->Release();
m_pWB2 = NULL;
}
if(m_pCP != NULL)
{
m_pCP->Release();
m_pCP = NULL;
}
//Delete the temporary file
DeleteFile(m_szFileTmpHtml);
}
//---------------------------------------------------------------------
//Description:
//Retrieves the ready state of the object
//
//Parameters:
//NULL
//
//Return Values:
//READYSTATE_UNINITIALIZED : Default initialization state.
//READYSTATE_LOADING : Object is currently loading its properties.
//READYSTATE_LOADED : Object has been initialized.
//READYSTATE_INTERACTIVE : Object is interactive, but not all of its data is available.
//READYSTATE_COMPLETE : Object has received all of its data.
//----------------------------------------------------------------------
READYSTATE CBrowser::GetReadyState()
{
READYSTATE state = READYSTATE_UNINITIALIZED;
if(m_pWB2 != NULL)
{
m_pWB2->get_ReadyState(&state);
}
return state;
}
//---------------------------------------------------------------------
//Description:
//Reloads the file that is currently displayed in the object.
//
//----------------------------------------------------------------------
BOOL CBrowser::Refresh()
{
if(m_pWB2 == NULL)
{
return E_FAIL;
}
return SUCCEEDED(m_pWB2->Refresh());
}
//---------------------------------------------------------------------
//Description:
//Retrieves a BOOL value indicating whether the object is engaged in a navigation or downloading operation
//
//----------------------------------------------------------------------
BOOL CBrowser::GetBusy()
{
if(m_pWB2 == NULL)
{
return FALSE;
}
VARIANT_BOOL varBool;
if(FAILED(m_pWB2->get_Busy(&varBool)))
{
return FALSE;
}
return (varBool == VARIANT_TRUE);
/*
VARIANT var;
VariantInit(&var);
var.vt = VT_BOOL;
if(FAILED(m_pWB2->get_Busy(&var.boolVal)))
{
return FALSE;
}
return (var.boolVal == VARIANT_TRUE);
*/
}
//---------------------------------------------------------------------
//Description:
//Retrieves the name of the resource that Internet Explorer is currently displaying.
// If the resource is an HTML page on the World Wide Web, the name is the title of that page.
// If the resource is a folder or file on the network or local computer, the name is the full path of the folder or file in Universal Naming Convention (UNC) format.
//
//Parameters:
// pszName : [out] The buffer is for storing the name.
// iSize : [in] The buffer size.
//
//----------------------------------------------------------------------
WCHAR * CBrowser::GetLocationName(WCHAR *pszName, int iSize)
{
pszName[0] = '/0';
if(m_pWB2 == NULL)
{
goto EXIT;
}
BSTR bstr;
bstr = SysAllocStringLen(NULL,iSize - 1);
//memset(bstr, 0, (iSize - 1)*2 );
if(FAILED(m_pWB2->get_LocationName((BSTR *)bstr)))
{
goto EXIT;
}
wcscpy(pszName,bstr);
EXIT:
if(bstr != NULL)
{
SysFreeString(bstr);
}
return pszName;
}
//---------------------------------------------------------------------
//Description:
//Retrieves the URL of the resource that Internet Explorer is currently displaying.
// If the resource is a folder or file on the network or local computer, the name is the full path of the folder or file in the Universal Naming Convention (UNC) format.
//
//Parameters:
// pszName : [out] The buffer is for storing the name.
// iSize : [in] The buffer size.
//
//----------------------------------------------------------------------
WCHAR * CBrowser::GetLocationURL(WCHAR *pszURL, int iSize)
{
pszURL[0] = '/0';
if(m_pWB2 == NULL)
{
goto EXIT;
}
BSTR bstr;
bstr = SysAllocStringLen(NULL,iSize - 1);
//memset(bstr, 0, (iSize - 1)*2 );
if(FAILED(m_pWB2->get_LocationURL((BSTR *)bstr)))
{
goto EXIT;
}
wcscpy(pszURL,bstr);
EXIT:
if(bstr != NULL)
{
SysFreeString(bstr);
}
return pszURL;
}
//---------------------------------------------------------------------
//Description:
//My default DWebBroserEvent Invoke interface process
//
//----------------------------------------------------------------------
HRESULT CBrowser::DefDWebBrowserEventInvokeProc(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr)
{
switch (dispidMember)
{
case DISPID_TITLECHANGE:
{
if (pdispparams && pdispparams->rgvarg[0].vt == VT_BSTR)
{
WCHAR szTitle[MAX_URL];
int len = wcslen(pdispparams->rgvarg[0].bstrVal);
wcsncpy(szTitle, pdispparams->rgvarg[0].bstrVal, MAX_URL - 5);
if(len > MAX_URL - 5)
{
wcscat(szTitle, L"...");
}
OnTitleChange(szTitle);
}
return S_OK;
}
case DISPID_ONQUIT:
{
OnQuit();
return S_OK;
}
case DISPID_STATUSTEXTCHANGE:
{
if (pdispparams && pdispparams->rgvarg[0].vt == VT_BSTR)
{
WCHAR szStatus[MAX_URL];
int len = wcslen(pdispparams->rgvarg[0].bstrVal);
wcsncpy(szStatus, pdispparams->rgvarg[0].bstrVal, MAX_URL - 5);
if(len > MAX_URL - 5)
{
wcscat(szStatus, L"...");
}
OnStatusTextChange(szStatus);
}
return S_OK;
}
case DISPID_PROGRESSCHANGE:
{
OnProgressChange(pdispparams->rgvarg[1].lVal,pdispparams->rgvarg[0].lVal);
return S_OK;
}
case DISPID_FILEDOWNLOAD:
{
BOOL bCancel;
OnFileDownload(&bCancel);
if(bCancel == TRUE)
{
*pdispparams->rgvarg[0].pboolVal = VARIANT_TRUE;
}
else
{
*pdispparams->rgvarg[0].pboolVal = VARIANT_FALSE;
}
return S_OK;
}
case DISPID_DOWNLOADBEGIN:
{
OnDownloadBegin();
return S_OK;
}
case DISPID_DOWNLOADCOMPLETE:
{
OnDownloadComplete();
return S_OK;
}
default:
return E_NOTIMPL;
}
return E_NOTIMPL;
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_TITLECHANGE.
//Fires when the title of a document in the object becomes available or changes.
// Because the title might change while an HTML page is downloading, the URL of the document is set as the title. After the title specified in the HTML page, if there is one, is parsed, the title is changed to reflect the actual title.
//
//----------------------------------------------------------------------
void CBrowser::OnTitleChange(const WCHAR *pszTitle)
{
return ;
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_ONQUIT.
// Fires before the Internet Explorer application quits.
//
//----------------------------------------------------------------------
void CBrowser::OnQuit()
{
return ;
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_STATUSTEXTCHANGE.
// The container can use the information provided by this event to update the text of a status bar.
//
//----------------------------------------------------------------------
void CBrowser::OnStatusTextChange(const WCHAR *pszText)
{
return ;
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_PROGRESSCHANGE.
// Fires when the progress of a download operation is updated on the object.
// The container can use the information provided by this event to display the number of bytes downloaded so far or to update a progress indicator.
// To calculate the percentage of progress to show in a progress indicator, multiply the value of Progress by 100 and divide by the value of ProgressMax (unless Progress is -1, in which case the container can indicate that the operation is finished or hide the progress indicator).
//
//Parameters:
//lPrgCur : [in]The current position
//lPrgMax : [in]The max position
//
//----------------------------------------------------------------------
void CBrowser::OnProgressChange(long lPrgCur, long lPrgMax)
{
//UINT nPos = (lPrgCur == -1) ? 999 : ((lPrgCur-1)%1000);
return ;
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_FILEDOWNLOAD.
// Fires to indicate that a file download is about to occur. If a file download dialog is to be displayed, this event is fired prior to the display of the dialog.
//This event allows alternative action to be taken during a file download
//
//Parameters:
//pbCancel : [out] If the parameter set TRUE, it would cancel the download progress. If FALSE, it would begin downloading.
//
//---------------------------------------------------------------------
void CBrowser::OnFileDownload(BOOL *pbCancel)
{
*pbCancel = FALSE;
return ;
/*
//temp -----------------------
pbCancel = TRUE;
HWND hWndParent = GetParent(m_hWndMain);
static BOOL bValue = TRUE;
if(bValue)
{
SetWindowText(hWndParent,TEXT("124"));
}
else
{
SetWindowText(hWndParent,TEXT("567"));
}
bValue = !bValue;
//-------------------------------
*/
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_DOWNLOADBEGIN.
// Fires when a navigation operation is beginning.
// This event is fired shortly after the DWebBrowserEvents::BeforeNavigate or DWebBrowserEvents2::BeforeNavigate2 event, unless the navigation is canceled. Any animation or "busy" indication that the container needs to display should be connected to this event.
//Each DWebBrowserEvents2::DownloadBegin event will have a corresponding DWebBrowserEvents2::DownloadComplete event.
//
//-----------------------------------------------------------------------
void CBrowser::OnDownloadBegin()
{
}
//---------------------------------------------------------------------
//Description:
// On DWebBrowserEvents2 invoke event DISPID_DOWNLOADCOMPLETE.
// Fires when a navigation operation finishes, is halted, or fails.
// Unlike DWebBrowserEvents::NavigateComplete or DWebBrowserEvents2::NavigateComplete2, which are fired only when a URL is successfully navigated to, this event is always fired after a navigation starts. Any animation or "busy" indication that the container needs to display should be connected to this event.
// Each DWebBrowserEvents2::DownloadBegin event will have a corresponding DWebBrowserEvents2::DownloadComplete event.
//
//-----------------------------------------------------------------------
void CBrowser::OnDownloadComplete()
{
}
//---------------------------------------------------------------------
//Description:
//Set the text displayed in the window, it could be HTML format text.
//
//Parameters:
//pszText : [in] The text to display
//---------------------------------------------------------------------
BOOL CBrowser::SetText(const WCHAR *pszText)
{
WCHAR szFileBegin[] = {TEXT("
WCHAR *pszBuf = new WCHAR[_tcslen(szFileBegin) + _tcslen(szFileEnd) + _tcslen(pszText) + 1];
_tcscpy(pszBuf,szFileBegin);
_tcscat(pszBuf,pszText);
_tcscat(pszBuf,szFileEnd);
HANDLE hFile = CreateFile(m_szFileTmpHtml,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD dwWritten = 0;
WriteFile(hFile,pszBuf,_tcslen(pszBuf)* sizeof(WCHAR),&dwWritten,NULL);
CloseHandle(hFile);
delete []pszBuf;
if(dwWritten == 0)
{
//Fail to write
return FALSE;
}
else
{
NavigateToURL(m_szFileTmpHtml);
}
return TRUE;
}
//-------------------------------------------------------------------------------------
//Description:
//Get the current runing path including '/' in last
//
//Parameters:
//pszPath: [out] Get the current path
//ulSize: [in] The size of the buffer. For example: szPath[MAX_NUMBER],the size if MAX_NUMBER.
//
//-------------------------------------------------------------------------------------
WCHAR *CBrowser::GetCurrentDirectory(WCHAR *pszPath, ULONG ulSize)
{
memset(pszPath, 0, sizeof(WCHAR) * ulSize);
WCHAR szBuf[MAX_PATH] = {0};
GetModuleFileName(NULL,szBuf,sizeof(szBuf)/sizeof(TCHAR));
ULONG ulCount = _tcslen(szBuf);
while(--ulCount >= 0)
{
if(szBuf[ulCount] == '//')
{
break;
}
else
{
continue;
}
}
if(ulSize > (DWORD)ulCount)
{
_tcsncpy(pszPath,szBuf,(ulCount + 1));
}
return pszPath;
}
//-------------------------------------------------------------------------------------
//Description:
//Move the main window. If the main window has parent window, the coordinate is client, or is the desktop.
//
//-------------------------------------------------------------------------------------
BOOL CBrowser::Move(const RECT * prcMove)
{
return MoveWindow(m_hWndMain,
prcMove->left,
prcMove->top,
prcMove->right - prcMove->left,
prcMove->bottom - prcMove->top,
TRUE);
}