MFC使用CHtmlView实现js与dialog的交互

类CBaseHtmlView

// BaseHtmlView.cpp : 实现文件
//

#include "stdafx.h"
#include "HtmlDialog.h"
#include "BaseHtmlView.h"


// CBaseHtmlView

IMPLEMENT_DYNCREATE(CBaseHtmlView, CHtmlView)

// --> 实现 JS 调用 Cpp   begin 
//  例如:   function fun3(){
//				var studyid = "NJ20036653";
//				window.external.CallCpp2(studyid + ";");
//			}
//
BEGIN_DISPATCH_MAP(CBaseHtmlView, CHtmlView)
	DISP_FUNCTION(CBaseHtmlView, "CallCpp", GetJsMsg, VT_BOOL, VTS_I4 VTS_I4)
	DISP_FUNCTION(CBaseHtmlView, "CallCpp2", GetJsString, VT_BOOL, VTS_VARIANT)
END_DISPATCH_MAP()

BOOL CBaseHtmlView::GetJsMsg(int a, int b)
{
	TRACE("\nCBaseHtmlView::GetJsMsg a:%d b:%d\n", a, b);
	return 1;
}

BOOL CBaseHtmlView::GetJsString(const VARIANT& var)
{
	if (VT_BSTR == var.vt)
	{
		AfxMessageBox((LPCTSTR)(_bstr_t)(_variant_t(var)));
		CString str(var);
		// to do sth.
		//
	}
	return FALSE;
}



HRESULT CBaseHtmlView::OnGetExternal(LPDISPATCH *lppDispatch)
{
	*lppDispatch = GetIDispatch(TRUE);
	return S_OK;
}
// <-- 实现 JS 调用 Cpp   end  

CBaseHtmlView::CBaseHtmlView()
{
	EnableAutomation();
}

CBaseHtmlView::~CBaseHtmlView()
{
}

void CBaseHtmlView::DoDataExchange(CDataExchange* pDX)
{
	CHtmlView::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CBaseHtmlView, CHtmlView)
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_MOUSEACTIVATE()
END_MESSAGE_MAP()


// CBaseHtmlView 诊断

#ifdef _DEBUG
void CBaseHtmlView::AssertValid() const
{
	CHtmlView::AssertValid();
}

void CBaseHtmlView::Dump(CDumpContext& dc) const
{
	CHtmlView::Dump(dc);
}
#endif //_DEBUG


// CBaseHtmlView 消息处理程序


void CBaseHtmlView::OnDestroy()
{
	if (m_pBrowserApp)
	{
		m_pBrowserApp.Release();
		m_pBrowserApp = NULL;
	}
	CWnd::OnDestroy(); //为了跳过CView(doc/frame)的OnDestroy
}

void CBaseHtmlView::OnInitialUpdate()
{
	CHtmlView::OnInitialUpdate();
	CString url;
	if (theApp.m_mapCmdArg.find(_T("url")) != theApp.m_mapCmdArg.end())
	{
		url = theApp.m_mapCmdArg[_T("url")];
		Navigate2(url, NULL, NULL); //这里的网站可以任意更换
		//Navigate2(_T("D:/123.html"), NULL, NULL); //这里的网站可以任意更换
	}
	else
	{
		::GetPrivateProfileString(_T("Web"), _T("url"), _T(""), url.GetBuffer(_MAX_PATH), _MAX_PATH, theApp.m_strCfgFilePath);
		url.ReleaseBuffer();
		Navigate2(url, NULL, NULL); //这里的网站可以任意更换
	}
}


void CBaseHtmlView::OnSize(UINT nType, int cx, int cy)
{
	//CHtmlView::OnSize(nType, cx, cy);
//	CFormView::OnSize(nType, cx, cy);

	// TODO:  在此处添加消息处理程序代码
	if (::IsWindow(m_wndBrowser.m_hWnd))
	{
		CRect rect;
		GetClientRect(rect);
		//LONG lWindows = GetWindowLong(GetParent()->GetSafeHwnd(), GWL_EXSTYLE);
		///*		::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_CLIPSIBLINGS);*/
		//::AdjustWindowRectEx(rect, GetStyle(), FALSE, lWindows);
		m_wndBrowser.SetWindowPos(NULL, rect.left, rect.top, cx, cy, SWP_NOACTIVATE | SWP_NOZORDER);
	}
}


int CBaseHtmlView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

	//return CHtmlView::OnMouseActivate(pDesktopWnd, nHitTest, message);
	return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); //为了跳过CView(doc/frame)的OnMouseActivate
}


void CBaseHtmlView::PostNcDestroy()
{
	// TODO:  在此添加专用代码和/或调用基类

	//CHtmlView::PostNcDestroy();   注释掉,防止CView 销毁自己
}


void CBaseHtmlView::OnDocumentComplete(LPCTSTR lpszURL)
{
	// TODO:  在此添加专用代码和/或调用基类

	CHtmlView::OnDocumentComplete(lpszURL);

	SetScriptDocument(); //初始化com组件 IID_IHTMLDocument2接口

	//::PostMessage(GetParent()->GetSafeHwnd(), WM_MAINJS_INITDATA, NULL, NULL);
}

BOOL CBaseHtmlView::CreateFromStatic(UINT nID, CWnd* pParent)
{
	CWnd* pStatic = pParent->GetDlgItem(nID);
	if (pStatic == NULL)
		return FALSE;

	CRect rc;
	pStatic->GetWindowRect(&rc);
	pParent->ScreenToClient(&rc);
	pStatic->DestroyWindow();

	if (!CHtmlView::Create(NULL, NULL, (WS_CHILD | WS_VISIBLE), rc, pParent, nID, NULL))
		return FALSE;

	OnInitialUpdate();  //加载网页或html
	SetSilent(TRUE);//add by wh ,bid pop script dlg  true表示允许界面弹出对话框
	return TRUE;
}

BOOL CBaseHtmlView::CreateFromClientRect(CWnd* wnd)
{
	CRect rc;
	wnd->GetClientRect(rc);
	UINT nID = 10001;
	if (!CHtmlView::Create(NULL, NULL, (WS_CHILD | WS_VISIBLE), rc, wnd, nID, NULL))
		return FALSE;

	OnInitialUpdate();  //加载网页或html
	SetSilent(TRUE);//add by wh ,bid pop script dlg  true表示允许界面弹出对话框
	return TRUE;
}

BOOL CBaseHtmlView::SetScriptDocument()
{
	CComPtr<IDispatch> spDisp = GetHtmlDocument(); //获取com 初始接口指针
	if (spDisp == NULL)
	{
		ASSERT(FALSE);
		return FALSE;
	}

	m_spDoc = NULL;
	HRESULT hr = spDisp->QueryInterface(IID_IHTMLDocument2, (void **)&m_spDoc);
	if (FAILED(hr))
	{
		MessageBox(L"Failed to get HTML document COM object");
		return FALSE;
	}

	return TRUE;
}

BOOL CBaseHtmlView::GetJScript(CComPtr<IDispatch>& spDisp)
{
	if (m_spDoc == NULL)
		return FALSE;

	HRESULT hr = m_spDoc->get_Script(&spDisp); //获取Script接口
	ATLASSERT(SUCCEEDED(hr));
	return SUCCEEDED(hr);
}

const CString CBaseHtmlView::GetSystemErrorMessage(DWORD dwError)
{
	CString strError;
	LPTSTR lpBuffer;

	if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		NULL, dwError,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
		(LPTSTR)&lpBuffer, 0, NULL))
	{
		strError = "FormatMessage Netive Error";
	}
	else
	{
		strError = lpBuffer;
		LocalFree(lpBuffer);
	}
	return strError;
}

BOOL CBaseHtmlView::CallJScript(const CString strFunc, const CStringArray& paramArray, _variant_t* pVarResult /*= NULL*/)
{
	CComPtr<IDispatch> spScript;
	if (!GetJScript(spScript))
	{
		MessageBox(L"函数GetJScrip调用失败!");
		return FALSE;
	}

	CComBSTR bstrFunc(strFunc);
	DISPID dispid = NULL;
	//根据名称strFunc 获取 ids
	HRESULT hr = spScript->GetIDsOfNames(IID_NULL, &bstrFunc, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
	if (FAILED(hr))
	{
		MessageBox(GetSystemErrorMessage(hr));
		return FALSE;
	}

	DISPPARAMS dispparams;
	memset(&dispparams, 0, sizeof dispparams);

	INT_PTR arraySize = paramArray.GetSize();
	dispparams.cArgs = (UINT)arraySize; //参数个数
	dispparams.rgvarg = new VARIANT[dispparams.cArgs];

	for (int i = 0; i < arraySize; i++)
	{
		CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading
		bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
		dispparams.rgvarg[i].vt = VT_BSTR;
	}
	dispparams.cNamedArgs = 0;

	EXCEPINFO excepInfo;
	memset(&excepInfo, 0, sizeof excepInfo);
	_variant_t vaResult;
	UINT nArgErr = (UINT)-1;  // initialize to invalid arg

	//调用JaveScript接口
	hr = spScript->Invoke(dispid, IID_NULL, 0,
		DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr);

	delete[] dispparams.rgvarg;
	if (FAILED(hr))
	{
		MessageBox(GetSystemErrorMessage(hr));
		return FALSE;
	}

	if (pVarResult)
	{
		*pVarResult = vaResult;
	}
	return TRUE;
}

BOOL CBaseHtmlView::CallJScript(const CString strFunc, _variant_t* pVarResult /*= NULL*/)
{
	CStringArray paramArray;
	return CallJScript(strFunc, paramArray, pVarResult);
}

BOOL CBaseHtmlView::CallJScript(const CString strFunc, const CString strArg1, _variant_t* pVarResult /*= NULL*/)
{
	CStringArray paramArray;
	paramArray.Add(strArg1);
	return CallJScript(strFunc, paramArray, pVarResult);
}

BOOL CBaseHtmlView::CallJScript(const CString strFunc, const CString strArg1, const CString strArg2, _variant_t* pVarResult /*= NULL*/)
{
	CStringArray paramArray;
	paramArray.Add(strArg1);
	paramArray.Add(strArg2);
	return CallJScript(strFunc, paramArray, pVarResult);
}

BOOL CBaseHtmlView::CallJScript(const CString strFunc, const CString strArg1, const CString strArg2, const CString strArg3, _variant_t* pVarResult /*= NULL*/)
{
	CStringArray paramArray;
	paramArray.Add(strArg1);
	paramArray.Add(strArg2);
	paramArray.Add(strArg3);
	return CallJScript(strFunc, paramArray, pVarResult);
}

头文件

#pragma once

#ifdef _WIN32_WCE
#error "Windows CE 不支持 CHtmlView。"
#endif 

// CBaseHtmlView Html 视图

class CBaseHtmlView : public CHtmlView
{
	DECLARE_DYNCREATE(CBaseHtmlView)
	/// JS调用Cpp  begin ///
	DECLARE_DISPATCH_MAP()
	HRESULT OnGetExternal(LPDISPATCH *lppDispatch);
	/// JS调用Cpp  end   ///
	
public:
	CBaseHtmlView();           // 动态创建所使用的受保护的构造函数
	virtual ~CBaseHtmlView();

public:
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnDestroy();
//	afx_msg void OnNcDestroy();
	virtual void OnInitialUpdate();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
	virtual void PostNcDestroy();
	virtual void OnDocumentComplete(LPCTSTR lpszURL);
	BOOL CreateFromStatic(UINT nID, CWnd* pParent);
	BOOL GetJsMsg(int a, int b);
	virtual BOOL GetJsString(const VARIANT& var);
	BOOL CreateFromClientRect(CWnd* wnd);


	/******************************************
	****** MFC call Javascript 相关函数********
	*******************************************/
	//MFC 通过com 调用 JavaScript接口
	CComPtr<IHTMLDocument2>	m_spDoc; //com组件的 IHTMLDocument2接口
	BOOL SetScriptDocument();  //获取IHTMLDocument2接口m_spDoc
	BOOL GetJScript(CComPtr<IDispatch>& spDisp);  //获取JScript接口
	const CString GetSystemErrorMessage(DWORD dwError);
	//无参调用
	BOOL CallJScript(const CString strFunc, _variant_t* pVarResult = NULL);
	//一个CString参数的调用
	BOOL CallJScript(const CString strFunc, const CString strArg1, _variant_t* pVarResult = NULL);
	//两个CString参数的调用
	BOOL CallJScript(const CString strFunc, const CString strArg1, const CString strArg2, _variant_t* pVarResult = NULL);
	//三个CString参数的调用
	BOOL CallJScript(const CString strFunc, const CString strArg1, const CString strArg2, const CString strArg3, _variant_t* pVarResult = NULL);
	//真正的调用JavaScript方法
	BOOL CallJScript(const CString strFunc, const CStringArray& paramArray, _variant_t* pVarResult = NULL);

};



使用方法

在Dialog类中,声明成员变量,CBaseHtmlView m_HtmlView;
在OnInitDialog()中,添加,m_HtmlView.CreateFromClientRect(this);
在OnSize()中,添加

	if (m_HtmlView.GetSafeHwnd())
	{
		CRect rc;
		GetClientRect(rc);
		m_HtmlView.MoveWindow(rc, 0);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值