我的元件之HtmlCtrl
前一篇介紹了 Thread,這裡再演示一下 OwnerPolicy 的妙用。以下是我的 HtmlCtrl 類(VS2005 及以上版本)。
對話方塊的標頭檔案
對話方塊的 cpp 檔案
#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);
}
相關文章
- 我的元件之OwnerPolicy元件
- 我的元件之執行緒類元件執行緒
- 我的元件之產生式程式設計元件程式設計
- 我的vue-router+webpack之動態非同步元件之旅VueWeb非同步元件
- joomla中聯絡我們元件的配置OOM元件
- 我的 vue 學習記錄2: 子元件呼叫父元件的方法Vue元件
- 【洋小洋同學】 我大膽地修改了父元件傳來的prop之後?元件
- Vue子元件與父元件之間的通訊Vue元件
- react元件與元件之間的資料傳遞React元件
- React之元件(component)之間的通訊React元件
- vue元件之間的通訊Vue元件
- React - 元件之間的通訊React元件
- React之受控元件和非受控元件React元件
- React 之受控元件和非受控元件React元件
- React元件之ClockReact元件
- Vue元件之TooltipVue元件
- 我的前端元件 —- 16:9固定寬高比例的div前端元件
- 我們或許不需要 React 的 Form 元件ReactORM元件
- 那些年我們用過的元件-結構化日誌元件 Serilog元件
- DiffUtil之我的封裝思路封裝
- 我的前端筆記 之 JavaScript前端筆記JavaScript
- 圖靈改版之我的想法圖靈
- 建立網站之我的思路網站
- Vue - 元件之間的傳值方式Vue元件
- 元件之間的通訊LiveDataBus元件LiveData
- flutter的進階之路之常用元件Flutter元件
- vue之router-view元件的使用VueView元件
- vue元件巢狀之 - 父元件向子元件傳值Vue元件巢狀
- 我學react之父子元件通訊React元件
- 簡單談談我理解的React元件生命週期React元件
- 聊聊我們那些年用過的表示式引擎元件元件
- Angular 之我見Angular
- Flutter元件之ChoiceChip教程Flutter元件
- vue之元件理解(一)Vue元件
- vue之元件註冊Vue元件
- jmeter之JDBC類元件JMeterJDBC元件
- TarsCpp 元件之 MySQL 操作元件MySql
- 父子元件之間的傳值問題元件