我的元件之HtmlCtrl

LiuYinChina發表於2013-01-31
前一篇介紹了 Thread,這裡再演示一下 OwnerPolicy 的妙用。以下是我的 HtmlCtrl 類(VS2005 及以上版本)。

#ifndef HtmlCtrl_H
#define HtmlCtrl_H

//////////////////////////////////////////////////////////////////////////

#include <AfxOle.h>
#include <AfxHtml.h>
#include <AtlBase.h>

//////////////////////////////////////////////////////////////////////////

#include "OwnerPolicy.h"

//////////////////////////////////////////////////////////////////////////

template <typename OwnerT>
class HtmlCtrlT	:	public CHtmlView, 
			public OwnerPolicy<OwnerT>
{
public:
	virtual HRESULT OnShowContextMenu(DWORD dwID, LPPOINT ppt, LPUNKNOWN pcmdtReserved, LPDISPATCH pdispReserved)
	{
		return S_OK;
	}
	virtual HRESULT OnGetExternal(LPDISPATCH *lppDispatch)
	{
		OwnerT *pOwner = owner();
		*lppDispatch = (pOwner == NULL) ? NULL : (owner()->GetIDispatch(TRUE));
		return S_OK;
	}
	HRESULT SetHTMLText(LPCTSTR lpszHTML)
	{
		HRESULT hr = E_FAIL;

		COleStreamFile fileOleStream;
		fileOleStream.CreateMemoryStream();

		CString strHTML(lpszHTML);
		fileOleStream.Write(strHTML.GetBuffer(0), strHTML.GetLength() * sizeof(TCHAR));
		strHTML.ReleaseBuffer();

		fileOleStream.SeekToBegin();

		CComQIPtr<IPersistStreamInit> pPersistStreamInit(GetHtmlDocument());
		if (pPersistStreamInit == NULL) {
			Navigate(TEXT("about:blank"));
		}

		pPersistStreamInit = GetHtmlDocument();
		if (pPersistStreamInit) {
			hr = pPersistStreamInit->Load(static_cast<IStream *>(fileOleStream.GetStream()));
		}
		return hr;
	}

 	virtual void PostNcDestroy()
	{
		//	disable CView::PostNcDestroy(), he will call (delete this);
	}
};

//////////////////////////////////////////////////////////////////////////

#endif

對話方塊的標頭檔案

#pragma once

#include <AfxWin.h>

#include "Resource.h"

#include "HtmlCtrl.h"

//////////////////////////////////////////////////////////////////////////

class CMainDialog	:	public CDialog
{
	typedef HtmlCtrlT<CMainDialog> CHtmlCtrl;

public:
	CMainDialog(CWnd *pParent = NULL);

	enum { IDD = IDD_DEMOHTMLCTRL_DIALOG };

protected:
	virtual void DoDataExchange(CDataExchange *pDX);

protected:
	HICON m_hIcon;

	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();

	DECLARE_MESSAGE_MAP()
	DECLARE_DISPATCH_MAP()

private:
	void MessageBox(BSTR bstrMessage);

private:
	CHtmlCtrl m_htmlCtrl;
};

對話方塊的 cpp 檔案

#include "MainDialog.h"

//////////////////////////////////////////////////////////////////////////

BEGIN_DISPATCH_MAP(CMainDialog, CDialog)
	DISP_FUNCTION(CMainDialog,	"MessageBox",	MessageBox,	VT_EMPTY,	VTS_BSTR)
END_DISPATCH_MAP()

//////////////////////////////////////////////////////////////////////////

CMainDialog::CMainDialog(CWnd *pParent)
	:	CDialog(CMainDialog::IDD, pParent)
{
	EnableAutomation();

	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMainDialog::DoDataExchange(CDataExchange *pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
	//{{AFX_MSG_MAP
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CMainDialog::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);

	//////////////////////////////////////////////////////////////////////////

	CStatic wndStatic;
	if (!wndStatic.SubclassDlgItem(IDC_HTML_CTRL, this)) {
		return FALSE;
	}

	CRect rect;
	wndStatic.GetWindowRect(&rect);
	ScreenToClient(&rect);
	wndStatic.DestroyWindow();

	m_htmlCtrl.owner(this);
	m_htmlCtrl.Create(NULL, NULL, WS_CHILD|WS_VISIBLE, rect, this, IDC_HTML_CTRL, NULL);
	m_htmlCtrl.SetHTMLText(TEXT("<HTML><BODY><Button OnClick=\"external.MessageBox('Hello, JavaScript!');\">Message</Button></BODY></HTML>"));
	return TRUE;
}

void CMainDialog::OnPaint() 
{
	if (IsIconic()) {
		CPaintDC dc(this);

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else {
		CDialog::OnPaint();
	}
}

HCURSOR CMainDialog::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMainDialog::MessageBox(BSTR bstrMessage)
{
	::MessageBoxW(GetSafeHwnd(), bstrMessage, L"Title", MB_ICONINFORMATION);
}




相關文章