去除CHtmlView边框和滚动条,增加javascript调用接口(VC6)
需要先调用EnableAutomation打开自动化,然后重写虚函数NavigateComplete2/OnNavigateComplete2或DocumentComplete/OnDocumentComplete,使用以上代码即可。Javascript中使用document.body.external.function()调用C++方法。
代码示例:
HtmlCtrl.h
#if !defined(AFX_HTMLCTRL_H__D2444B51_11E9_489E_98AE_FDB23EC0C958__INCLUDED_) #define AFX_HTMLCTRL_H__D2444B51_11E9_489E_98AE_FDB23EC0C958__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXEXT_H__ #include <afxext.h> #endif #include <afxhtml.h> class CHtmlCtrl : public CHtmlView { public: CHtmlCtrl(); virtual ~CHtmlCtrl(); public: void InternalName(LPCTSTR pszMsg); public: virtual void PostNcDestroy(); public: virtual void OnDocumentComplete(LPCTSTR lpszURL); virtual void OnNavigateComplete2(LPCTSTR strURL); virtual BOOL OnInitDispatch(LPCTSTR pszJsFunc, IDispatch* pDisp, VARIANT* pvarRet); public: DECLARE_MESSAGE_MAP() DECLARE_DISPATCH_MAP() }; #endif // !defined(AFX_HTMLCTRL_H__D2444B51_11E9_489E_98AE_FDB23EC0C958__INCLUDED_)
HtmlCtrl.cpp
#include "StdAfx.h" #include <mshtml.h> #include <comdef.h> #include "HtmlCtrl.h" CHtmlCtrl::CHtmlCtrl() { EnableAutomation(); } CHtmlCtrl::~CHtmlCtrl() { } void CHtmlCtrl::PostNcDestroy() { } BEGIN_MESSAGE_MAP(CHtmlCtrl, CHtmlView) END_MESSAGE_MAP() BEGIN_DISPATCH_MAP(CHtmlCtrl, CHtmlView) DISP_FUNCTION(CHtmlCtrl, "ExternalName", InternalName, VT_EMPTY, VTS_BSTR) END_DISPATCH_MAP() void CHtmlCtrl::InternalName(LPCTSTR pszMsg) { AfxMessageBox(_T("Test Code...")); } void CHtmlCtrl::OnDocumentComplete(LPCTSTR lpszURL) { IHTMLDocument2Ptr pDocument = GetHtmlDocument(); if (pDocument) { IHTMLElementPtr pBody = NULL; pDocument->get_body(&pBody); if (pBody) { // 此处设置external代码落后于html中的js代码执行 // pBody->setAttribute(L"external", _variant_t(GetIDispatch(TRUE), false), 0); IHTMLStylePtr pStyle = NULL; pBody->get_style(&pStyle); if (pStyle) { pStyle->put_overflow(L"hidden"); pStyle->put_border(L"none"); } } // 回调到js函数 OnInitDispatch(_T("OnInitDispatch"), GetIDispatch(TRUE), NULL); } } void CHtmlCtrl::OnNavigateComplete2(LPCTSTR strURL) { IHTMLDocument2Ptr pDocument = GetHtmlDocument(); if (pDocument) { IHTMLElementPtr pBody = NULL; pDocument->get_body(&pBody); if (pBody) { // 此处代码先于html中的js代码执行,但需要只有body标签中包含script标签 // pBody->setAttribute(L"external", _variant_t(GetIDispatch(TRUE), false), 0); } } } BOOL CHtmlCtrl::OnInitDispatch(LPCTSTR pszJsFunc, IDispatch* pDisp, VARIANT* pvarRet) { BOOL bReturn(FALSE); IHTMLDocument2Ptr pDocument = GetHtmlDocument(); if (pDocument) { IDispatchPtr spScript = NULL; HRESULT hr = pDocument->get_Script(&spScript); if (SUCCEEDED(hr)) { DISPID dispid; _bstr_t bstrFunc(pszJsFunc); LPOLESTR pszFunc = bstrFunc; hr = spScript->GetIDsOfNames(IID_NULL, (LPOLESTR*)&pszFunc, 1, LOCALE_USER_DEFAULT, &dispid); if (SUCCEEDED(hr)) { _variant_t varParam(pDisp); DISPPARAMS dispparams = { &varParam, NULL, 1, 0}; hr = spScript->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL); if (SUCCEEDED(hr)) { bReturn = TRUE; } } } } return bReturn; }