类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);
}