1. 程式人生 > >使用IWebBrowser2建立簡單瀏覽器

使用IWebBrowser2建立簡單瀏覽器

使用ie核心的瀏覽器怎麼搞

IWebBrowser2 ie核心的瀏覽器控制元件

CAxWindow 容器

CreateWindow 建立windows視窗

直接上程式碼

// ncPatternFlyweight.h


#ifndef __NC_PATTERN_FLYWEIGHT_H__
#define __NC_PATTERN_FLYWEIGHT_H__

#pragma once

#include "ncAutoLock.h"
#include "ncMutex.h"

#include 
using namespace std;


template
class ncPatternFlyweight
{
public:
	static U* getMapFlyweightInstance (T t)
	{
		ncAutoLock autolock (&_lock);
		std::map::iterator it = _mapFlyweightInstance.find (t);
		if (it != _mapFlyweightInstance.end ()) {
			return it->second;
		}
		else {
			return NULL;
		}
	}

	static void addMapFlyweightInstance (T t, U* u)
	{
		ncAutoLock autolock (&_lock);
		_mapFlyweightInstance[t] = u;
	}

	static void removeMapFlyweightInstance (T t)
	{
		ncAutoLock autolock (&_lock);
		std::map::iterator it = _mapFlyweightInstance.find (t);
		if (it != _mapFlyweightInstance.end ()) {
			_mapFlyweightInstance.erase (it);
		}
	}

	static bool existenceMapFlyweightInstance (T t)
	{
		ncAutoLock autolock (&_lock);
		return _mapFlyweightInstance.find (t) != _mapFlyweightInstance.end ();
	}

protected:
	static std::map _mapFlyweightInstance;
	static ncMutex _lock;
};

template
ncMutex 
ncPatternFlyweight::_lock;

template
std::map 
ncPatternFlyweight::_mapFlyweightInstance;

#endif

// ncAutoLock.h


#ifndef __NC_AUTO_LOCK_H__
#define __NC_AUTO_LOCK_H__

#pragma once


template
class ncAutoLock
{
public:
	ncAutoLock(T* lock) 
		: _lock(lock)
	{
		_lock->lock();
	}

	~ncAutoLock()
	{
		_lock->unlock();
	}

protected:
	T* _lock;
};

#endif

// ncMutex.h


#ifndef __NC_MUTEX_H__
#define __NC_MUTEX_H__

#pragma once

#include 


class ncMutex
{
public:
	ncMutex();
	~ncMutex();

public:
	bool lock();
	bool unlock();

private:
	CRITICAL_SECTION _cs;
};

#endif

// ncMutex.cpp



#include "ncMutex.h"


ncMutex::ncMutex()
{
	InitializeCriticalSection(&_cs);
}

ncMutex::~ncMutex()
{
	DeleteCriticalSection (&_cs);
}

bool 
ncMutex::lock()
{
	EnterCriticalSection(&_cs);
	return true;
}

bool 
ncMutex::unlock()
{
	LeaveCriticalSection(&_cs);
	return true;
}

// ncSimpleBrowser.h


#ifndef __NC_SIMPLE_BROWSER_H__
#define __NC_SIMPLE_BROWSER_H__

#pragma once

#include 
#include 
#include 
#include 

#include 
using namespace std;

#include "Wininet.h"
#pragma comment (lib, "Wininet.lib")


class ncSimpleBrowser
	: public IDispatch
{
public:
	ncSimpleBrowser(const string& addr, const string& redirectServer);
	~ncSimpleBrowser();

	void init (CAxWindow& cAxWindow);
	void connectEvent();
	void exit();

public:
	STDMETHODIMP Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pDispParams,VARIANT FAR* pVarResult,EXCEPINFO FAR* pExcepInfo,unsigned int FAR* puArgErr);  
	STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
	{
		HRESULT hr = E_NOINTERFACE;
		if (riid == __uuidof(IDispatch)) {
			*ppvObject = (IDispatch*)this;
			AddRef();
			hr = S_OK;
		}
		else if (riid == __uuidof(DWebBrowserEvents2)) {
			*ppvObject = (DWebBrowserEvents2*)this;
			AddRef();
			hr = S_OK;
		}
		return hr;
	}

	STDMETHOD_(ULONG, AddRef)()
	{
		return 1;
	}

	STDMETHOD_(ULONG, Release)()
	{
		return 1;
	}

	STDMETHOD(GetTypeInfoCount)(UINT*)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**)
	{
		return E_NOTIMPL;
	}

	STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR *rgszNames, UINT, LCID, DISPID *rgDispId) 
	{
		return E_NOTIMPL;
	}

protected:
	CComPtr _iWebBrowser;
	CComQIPtr _iConnectionPoint;
	DWORD _dwCookie;

	string _addr;
	string _redirectServer;
	string _url;
};

#endif

// ncSimpleBrowser.cpp


#include "ncSimpleBrowser.h"


ncSimpleBrowser::ncSimpleBrowser(const string& addr, const string& redirectServer)
	: _dwCookie (0)
	, _addr(addr)
	, _redirectServer(redirectServer)
	, _url("")
{
}

ncSimpleBrowser::~ncSimpleBrowser()
{
	exit();
}

void 
ncSimpleBrowser::init(CAxWindow& cAxWindow)
{
	LPOLESTR pszName = OLESTR ("shell.Explorer.2");	// 通過那個字串獲取了IE的字元

	VARIANT varMyURL;
	cAxWindow.CreateControl (pszName);	// 建立該類名對應的Actvie控制元件
	cAxWindow.QueryControl (__uuidof(IWebBrowser2), (void**)&_iWebBrowser); 
	VariantInit (&varMyURL);
	varMyURL.vt = VT_BSTR; 
	wstring addr(_addr.begin(), _addr.end());
	varMyURL.bstrVal = SysAllocString (CT2COLE(addr.c_str()));
	_iWebBrowser->Navigate2 (&varMyURL,  0, 0, 0, 0);
	VariantClear (&varMyURL);

	connectEvent();
}

void 
ncSimpleBrowser::connectEvent()
{
	CComQIPtr pCPC;
	if (SUCCEEDED(_iWebBrowser->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC))) {
		if (SUCCEEDED(pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &_iConnectionPoint))) {
			if(SUCCEEDED(_iConnectionPoint->Advise((IUnknown*)(void*)this, &_dwCookie))) {

			}
		}
	}
}

void 
ncSimpleBrowser::exit()
{
	if (_iConnectionPoint && SUCCEEDED(_iConnectionPoint->Unadvise(_dwCookie))) {

	}

	InternetSetOption(NULL, INTERNET_OPTION_END_BROWSER_SESSION, NULL, NULL);
}

STDMETHODIMP
ncSimpleBrowser::Invoke(DISPID dispIdMember, REFIID riid,LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr)
{
	USES_CONVERSION;
	if (!pDispParams) {
		return E_INVALIDARG;
	}

	switch (dispIdMember)
	{
	case DISPID_NAVIGATECOMPLETE2:
		if (pDispParams->rgvarg[0].vt == (VT_BYREF | VT_VARIANT)) {
			CComVariant varUrl (*pDispParams->rgvarg[0].pvarVal);
			varUrl.ChangeType(VT_BSTR);
			wstring url = OLE2T(varUrl.bstrVal);
		}
		break;

	default:
		break;
	}
	return S_OK;
}

// ncCreateWebBrowserWnd.h


#ifndef __NC_CREATE_WEB_BROWSER_WND_H__
#define __NC_CREATE_WEB_BROWSER_WND_H__

#pragma once

#include "ncPatternFlyweight.h"
#include "ncSimpleBrowser.h"

#include 
using namespace std;

class ncCreateWebBrowserWnd
	: public ncPatternFlyweight
{
public:
	static void creatNewWindow (const string& id, const string& url, const string& appName, UINT style, int nWidth, int nHeight, HINSTANCE hInstance);

	void destory (void);
	void move (void);

public:
	void popToFront ();

protected:
	ncCreateWebBrowserWnd (const string& id, const string& url, const string& appName, UINT style, int nWidth, int nHeight, HINSTANCE hInstance);
	~ncCreateWebBrowserWnd ();

protected:
	HWND _hWnd;

	CAxWindow _cAxWindow;
	ncSimpleBrowser _browser;

	string _id;
	string _url;
};

#endif

// ncCreateWebBrowserWnd.cpp


#include "ncCreateWebBrowserWnd.h"


LRESULT CALLBACK 
WndProc (HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	ncCreateWebBrowserWnd* wnd = reinterpret_cast(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
	
	switch (message) 
	{
	case WM_DESTROY:
		wnd->destory ();
		PostQuitMessage (0);		// 使整個程式退出
		break;

	case WM_SIZE:
		wnd->move ();
		break;

	case WM_PAINT:
		BeginPaint(hWnd, NULL);
		EndPaint(hWnd, NULL);
		break;

	default:
		return (int)DefWindowProc (hWnd, message, wParam, lParam);
	}
	return 0;
}

ncCreateWebBrowserWnd::ncCreateWebBrowserWnd (const string& id, const string& url, const string& appName, UINT style, int nWidth, int nHeight, HINSTANCE hInstance)
	: _browser (url, url)
	, _id (id)
	, _url (url)
{
	addMapFlyweightInstance(_url, this);

	HWND hWndParent = NULL;

	wstring appClass = _T("ncCreateWebBrowserWnd");

	WNDCLASS wndclass;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon (hInstance, NULL);
	wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = appClass.c_str();
	RegisterClass (&wndclass);

	wstring wappName(appName.begin(), appName.end());
	_hWnd = CreateWindow (appClass.c_str()
		, wappName.c_str()
		, style
		, CW_USEDEFAULT
		, 0
		, nWidth
		, nHeight
		, hWndParent
		, NULL
		, hInstance
		, this);
	
	::SetWindowLongPtr(_hWnd, GWLP_USERDATA, reinterpret_cast(this));

	RECT rc;
	GetClientRect (_hWnd, &rc);
	_cAxWindow.Create (_hWnd, rc, 0, WS_CHILD | WS_VISIBLE);
	_browser.init(_cAxWindow);

	// 居中
	int scrWidth,scrHeight;
	scrWidth = GetSystemMetrics(SM_CXSCREEN);
	scrHeight = GetSystemMetrics(SM_CYSCREEN);
	rc.left = (scrWidth - rc.right) / 2;
	rc.top = (scrHeight - rc.bottom) / 2;
	SetWindowPos(_hWnd, HWND_TOP, rc.left, rc.top, rc.right, rc.bottom, SWP_SHOWWINDOW);
}

ncCreateWebBrowserWnd::~ncCreateWebBrowserWnd()
{
	removeMapFlyweightInstance(_url);
}

void
ncCreateWebBrowserWnd::creatNewWindow (const string& id, const string& url, const string& appName, UINT style, int nWidth, int nHeight, HINSTANCE hInstance)
{
	ncCreateWebBrowserWnd* wnd = new ncCreateWebBrowserWnd (id, url, appName, style, nWidth, nHeight, hInstance);

	ShowWindow (wnd->_hWnd, SW_SHOW);
	UpdateWindow (wnd->_hWnd);
}

void
ncCreateWebBrowserWnd::destory (void)
{
	delete this;
}

void
ncCreateWebBrowserWnd::move (void)
{
	RECT rc;
	GetClientRect(_hWnd, &rc);
	_cAxWindow.MoveWindow (0, 0, rc.right - rc.left, rc.bottom - rc.top);
}

void 
ncCreateWebBrowserWnd::popToFront ()
{
	SwitchToThisWindow (_hWnd, true);
}

// main.cpp



#include 

#include "ncCreateWebBrowserWnd.h"



int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	CComModule _Module;

	string webSite = ("www.baidu.com");
	string appName = ("www.google.com");
	ncCreateWebBrowserWnd* pWnd = ncCreateWebBrowserWnd::getMapFlyweightInstance (webSite);
	if (pWnd != NULL) {
		pWnd->popToFront ();
	}
	else {
		ncCreateWebBrowserWnd::creatNewWindow (webSite, webSite, appName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 1000, 600, hInstance);
	}

	MSG msg = { 0 };
	GetMessage(&msg, NULL, NULL, NULL);
	while (msg.message != WM_QUIT) {
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
}