一、CHtmlCtrl 在 EXE 中应用
CHtmlCtrl 在网上一找一堆,这里只简要介绍一下,给出源码:
1、CHtmlView可实现显示HTML,CHtmlCtrl 是继承此类而来
2、CHtmlView的实现是基于COM的。通过IWebBrowser2接口来实现,而且IWebBrowser2与MFC文档/视图结构之间没有任何关系。
3、创建一个静态控制,这个控制的ID及大小位置与界面上的控制相同。
4、避免主控程序将CHtmlView对象看作是文档/视图框架,需要重载,CView::OnMouseActivate和CView::OnDestroy。此外,当用户在控制中单击时,OnMouseActivate要负责响应(WM_MOUSEACTIVATE)。
5、为了实现“app:” 伪协议,重载导航处理器OnBeforeNavigate2()。传递“app:”链接到一个虚拟协议处理器。因为app:是假协议,所以在浏览起重要取消掉这个导航。
6、调用方式:
大家在EXE中如何应用过行,但在DLL中就会存在报错问题,下面来解决掉这个问题:
1、加入
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CoInitialize(NULL); [一般都是在线程开始时调用CoInitialize(NULL);线程结束时调用CoUninitialize();]
2、不要在 virtual BOOL OnInitDialog(); 中调用,而要在ShowWindow(SW_SHOW);前以函数形式调用。
3、介绍一下CoInitialize的功能吧:
Coinitialize
CoInitialize是Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
语法:HRESULT CoInitialize(_in_opt LPVOID pvReserved);
参数被保留,且必须为NULL。
返回值S_OK : 该线程中COM库初始化成功S_FALSE 该线程中COM库已经被初始化 CoInitialize () 标明以单线程方式创建。
使用 CoInitialize 创建可以使对象直接与线程连接,得到最高的性能。
CoInitialize并不装载COM 库,它只用来初始化当前线程使用什么样的套间。使用这个函数后,线程就和一个套间建立了对应关系。线程的套间模式决定了该线程如何调用COM对象,是否需要列集等。
CoInitialize ()并不会干扰客户和服务器之间的通信,它所做的事情是让线程注册一个套间,而线程运行过程中必然在此套间。
CoInitialize和CoUninitialize必须成对使用。
创建新的就手程序用该调用CoInitializeEx代替CoInitialize。
CHtmlCtrl 在网上一找一堆,这里只简要介绍一下,给出源码:
1、CHtmlView可实现显示HTML,CHtmlCtrl 是继承此类而来
2、CHtmlView的实现是基于COM的。通过IWebBrowser2接口来实现,而且IWebBrowser2与MFC文档/视图结构之间没有任何关系。
3、创建一个静态控制,这个控制的ID及大小位置与界面上的控制相同。
4、避免主控程序将CHtmlView对象看作是文档/视图框架,需要重载,CView::OnMouseActivate和CView::OnDestroy。此外,当用户在控制中单击时,OnMouseActivate要负责响应(WM_MOUSEACTIVATE)。
5、为了实现“app:” 伪协议,重载导航处理器OnBeforeNavigate2()。传递“app:”链接到一个虚拟协议处理器。因为app:是假协议,所以在浏览起重要取消掉这个导航。
6、调用方式:
CHtmlCtrl m_page;
m_page.CreateFromStatic(IDC_HTML,this);
CString sIndex = "file:///F:\\index.html";
m_page.Navigate(sIndex);
7、上代码:
/头文件///
// HtmlCtrl.h: interface for the CHtmlCtrl class.
//
//
#if !defined(AFX_HTMLCTRL_H__A72A39FF_3D2D_431F_9802_D731A902E6E1__INCLUDED_)
#define AFX_HTMLCTRL_H__A72A39FF_3D2D_431F_9802_D731A902E6E1__INCLUDED_
#include <afxhtml.h>
#include "resource.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CHtmlCtrl :public CHtmlView
{
public:
CHtmlCtrl();
virtual ~CHtmlCtrl();
BOOL CreateFromStatic(UINT nID, CWnd* pParent);
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT msg);
afx_msg void OnDestroy();
virtual void PostNcDestroy() { }
virtual void OnBeforeNavigate2( LPCTSTR ,DWORD ,LPCTSTR ,CByteArray& ,LPCTSTR ,BOOL* );
virtual void OnAppCmd(LPCTSTR lpszWhere){ /*default: do nothing*/}
DECLARE_DYNCREATE(CHtmlCtrl)
DECLARE_MESSAGE_MAP()
};
#endif // !defined(AFX_HTMLCTRL_H__A72A39FF_3D2D_431F_9802_D731A902E6E1__INCLUDED_)
/
/
/cpp文件///
// HtmlCtrl.cpp: implementation of the CHtmlCtrl class.
//
//
#include "stdafx.h"
#include "HtmlCtrl.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
IMPLEMENT_DYNAMIC(CHtmlCtrl, CHtmlView)
BEGIN_MESSAGE_MAP(CHtmlCtrl, CHtmlView)
ON_WM_DESTROY()
ON_WM_MOUSEACTIVATE()
END_MESSAGE_MAP()
//
// Construction/Destruction
//
CHtmlCtrl::CHtmlCtrl(){}
CHtmlCtrl::~CHtmlCtrl(){}
BOOL CHtmlCtrl::CreateFromStatic(UINT nID, CWnd* pParent)
{
CStatic wndStatic; //静态控件对象;
if (!wndStatic.SubclassDlgItem(nID, pParent))
return FALSE;
// 获取静态控制的矩形区域并转换为父窗口的客户区坐标
CRect rc;
wndStatic.GetWindowRect(&rc);
pParent->ScreenToClient(&rc);
wndStatic.DestroyWindow();
// 创建 HTML 控制 (CHtmlView)
BOOL bT=FALSE;
bT= Create(NULL, // 类名;
NULL,// 标题
(WS_CHILD | WS_VISIBLE), // 风格;
rc, // 矩形区域;
pParent, // 父窗口;
nID, // 控制的ID号;
NULL); //取消文档框架支持;
return bT;
}
int CHtmlCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT msg)
{
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, msg);
}
void CHtmlCtrl::OnDestroy()
{
if (m_pBrowserApp)
{
// m_pBrowserApp.Release();
m_pBrowserApp = NULL;
}
CWnd::OnDestroy();
CHtmlView::OnDestroy();
}
void CHtmlCtrl::OnBeforeNavigate2( LPCTSTR lpszURL,
DWORD nFlags,
LPCTSTR lpszTargetFrameName,
CByteArray& baPostedData,
LPCTSTR lpszHeaders,
BOOL* pbCancel )
{
const char APP_PROTOCOL[] = "app:";
int len = _tcslen(APP_PROTOCOL);
if (_tcsnicmp(lpszURL, APP_PROTOCOL, len)==0)
{
OnAppCmd(lpszURL + len);
*pbCancel = TRUE;
}
return CHtmlView::OnBeforeNavigate2(lpszURL,
nFlags,
lpszTargetFrameName,
baPostedData,
lpszHeaders,
pbCancel);
}
/
二、CHtmlCtrl 在 DLL 中的应用
大家在EXE中如何应用过行,但在DLL中就会存在报错问题,下面来解决掉这个问题:
1、加入
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CoInitialize(NULL); [一般都是在线程开始时调用CoInitialize(NULL);线程结束时调用CoUninitialize();]
2、不要在 virtual BOOL OnInitDialog(); 中调用,而要在ShowWindow(SW_SHOW);前以函数形式调用。
3、介绍一下CoInitialize的功能吧:
Coinitialize
CoInitialize是Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
语法:HRESULT CoInitialize(_in_opt LPVOID pvReserved);
参数被保留,且必须为NULL。
返回值S_OK : 该线程中COM库初始化成功S_FALSE 该线程中COM库已经被初始化 CoInitialize () 标明以单线程方式创建。
使用 CoInitialize 创建可以使对象直接与线程连接,得到最高的性能。
CoInitialize并不装载COM 库,它只用来初始化当前线程使用什么样的套间。使用这个函数后,线程就和一个套间建立了对应关系。线程的套间模式决定了该线程如何调用COM对象,是否需要列集等。
CoInitialize ()并不会干扰客户和服务器之间的通信,它所做的事情是让线程注册一个套间,而线程运行过程中必然在此套间。
CoInitialize和CoUninitialize必须成对使用。
创建新的就手程序用该调用CoInitializeEx代替CoInitialize。