VC++ 6.0 的 HTML 编辑器






4.90/5 (34投票s)
2004年5月25日
7分钟阅读

368082

8975
VC++ 6.0 的 HTML 编辑控件,功能相当于 MFC7 的 CHtmlEditCtrlBase 类。
引言
如今,应用程序常常需要丰富的用户界面。其中一项功能就是能够以简单、有效且可靠的方式撰写或编辑 HTML 文档。本文以及附带的源代码提供了一个用于完成此任务的优秀控件。最棒的是:此控件在 Microsoft VC++ 6.0 中也能正常工作!
背景
我是 Tray Helper 应用程序的作者。很长一段时间以来,我一直想为应用程序添加一个发送彩色 HTML 邮件的功能。经过一番研究,我发现 Microsoft 实现的 IHTMLDocument2
接口(以及与之相关的其他几个接口)非常出色——但直接操作原始 COM 接口并不简单、高效或对开发者友好。我想 Microsoft 的人也意识到了这一点,并且在 MFC 7.0 中提供了一个非常好的 COM 封装:CHtmlEditCtrlBase
类。在仔细研究了该类的代码后,我决定将其移植到 MFC 4.0 和 VC++ 6.0。
使用代码
我在此介绍的 CHtmlEditCtrl2
类不仅仅是从 CHtmlEditCtrlBase
移植过来的——我还对原始代码进行了一些其他改进和修改——因此它不仅能在 VC++ 6.0 下编译,还具有一些新功能,并且在现有项目中更容易使用。主要的改变是 CHtmlEditCtrl2
类继承自 CWebBrowser2
。这意味着,如果您的项目已经使用标准的浏览器控件来显示 HTML 文档——那么添加编辑功能将轻而易举(请阅读下文以获取完整说明)。
将 HTML 编辑器添加到您的项目中
第一步:将一个普通的浏览器控件添加到您的项目中。
如果您的项目已经在使用浏览器控件——请跳过此段,从“第二步”开始阅读。
假设您想将 HTML 编辑控件添加到基于对话框的应用程序中。首先,您需要添加一个将用于存放 HTML 文档的浏览器控件。
- 为此,请进入 Visual Studio 的对话框模板编辑器,然后点击“项目 / 添加到项目 / 组件和控件”。在弹出的对话框中,选择“已注册的 ActiveX 控件”,最后选择“Web 浏览器控件”(控件的名称取决于您 PC 的语言——例如,在我使用的波兰语 Windows 版本中,它叫做“Przegladarka Przeglądarka sieci Web firmy Microsoft”)。为确保您选择的是正确的控件,请检查文件列表下方的描述——它应该是“WebBrowser control”。
- 选择控件后,会出现一个关于创建
CWebBrowser2
类的对话框。请在不进行任何修改的情况下点击“确定”。 - 请注意,工具栏上会新增一个用于插入对话框控件的列表项。所以,选择它,然后添加一个浏览器控件!
- 最后,使用类向导(Ctrl+W)为刚刚添加的项添加一个类型为
CWebBrowser2
的成员变量。 - 接下来,您可以在对话框的
OnInitdialog
方法中,使用CWebBrowser2
类的Navigate
方法请求浏览器加载 HTML 文档。
第二步:为浏览器添加编辑功能。
这非常容易。只需按照以下几个步骤操作:
- 将 HtmlEditCtrl2.H 和 HtmlEditCtrl2.cpp 文件复制到您的源文件目录并添加到项目中。
- 修改声明
CWebBrowser2
成员变量的头文件,将其更改为CHtmlEditCtrl2
。 - 将
#include "WebBrowser2.H"
更改为#include "HtmlEditCtrl2.H"
。 - 在加载 HTML 文档后(例如,使用
Navigate
方法),调用SetDesignMode(TRUE)
方法启用编辑模式。 - 如果编辑完成后,您想获取 HTML 文档的源代码,请调用
GetDocumentHTML
函数。
控件最重要的几个方法(您很可能需要用到它们)
void Navigate(LPCTSTR URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers)
使用此函数加载 HTML 文档。将 URL 参数设置为要打开的文件路径字符串。它可以是远程站点或本地文件。其余参数可以为 null。
示例
Navigate("https://codeproject.org.cn/", NULL, NULL, NULL, NULL); Navigate("C:\\my_file.html", NULL, NULL, NULL, NULL);
BOOL SetDesignMode(BOOL bMode);
启用或禁用编辑模式。在 6.0 之前的 Internet Explorer 版本中,必须先加载文档才能进入设计模式。
HRESULT GetDocumentHTML(CString& szHTML, BOOL a_bClearDirtyFlag = FALSE);
获取 HTML 文档的内容。
HRESULT SetDocumentHTML(LPCTSTR szHTML);
设置 HTML 文档的新内容。请注意,不能对空控件调用此函数。您需要先加载文档(例如,通过调用
Navigate
方法)。
CHtmlEditCtrl2 类的完整公共成员函数列表
这些成员函数直接来自 CHtmlEditCtrlBase
类。完整描述请参见 MSDN 页面(点击此处)
BOOL SetDesignMode(BOOL bMode); HRESULT ExecCommand(const GUID *pGuid, long cmdID, long cmdExecOpt, VARIANT* pInVar=NULL, VARIANT* pOutVar=NULL); HRESULT ExecCommand(long cmdID, long cmdExecOpt, VARIANT* pInVar=NULL, VARIANT* pOutVar=NULL); long QueryStatus(long cmdID); HRESULT GetEvent(IHTMLEventObj **ppEventObj); HRESULT GetEventSrcElement(IHTMLElement **ppSrcElement); HRESULT GetDocument(IHTMLDocument2** ppDoc); HRESULT NewDocument(); HRESULT GetDocumentHTML(CString& szHTML, BOOL a_bClearDirtyFlag = FALSE); HRESULT SetDocumentHTML(LPCTSTR szHTML); HRESULT GetIsDirty(); HRESULT GetDocumentTitle(CString& szTitle); HRESULT GetBlockFormatNames(CStringArray &sa); HRESULT SetForeColor(LPCTSTR szColor); HRESULT SetForeColor(int nColor); HRESULT GetForeColor(int &nColor); HRESULT GetBackColor(int& nColor); HRESULT SetBackColor(LPCTSTR szColor); HRESULT SetBackColor(int nColor); HRESULT SetDefaultComposeSettings(LPCSTR szFontName=NULL, unsigned short nFontSize=3, COLORREF crFontColor=0xFF000000, COLORREF crFontBgColor=0xFF000000, bool bBold = false, bool bItalic = false, bool bUnderline = false); HRESULT GetBlockFormat(CString& strFormat); HRESULT SetBlockFormat(LPCTSTR szFormat); HRESULT GetFontFace(CString& strFace); HRESULT SetFontFace(LPCTSTR szFace); HRESULT IE50Paste(LPCTSTR szData); HRESULT GetBookMark(CString& strAnchor); HRESULT SetBookMark(LPCTSTR szAnchorName); HRESULT SetOverwriteMode(bool bMode); HRESULT Is1DElement(bool& bValue); HRESULT Is2DElement(bool& bValue); HRESULT GetFontSize(short& nSize); HRESULT SetFontSize(unsigned short size); HRESULT GetFrameZone(short& nZone); HRESULT SetCSSEditingLevel(short nLevel); HRESULT HyperLink(LPCTSTR szUrl = NULL); HRESULT Image(LPCTSTR szUrl = NULL); HRESULT OrderList(LPCTSTR szId = NULL); HRESULT UnorderList(LPCTSTR szId = NULL); HRESULT AddToGlyphTable(LPCTSTR szTag, LPCTSTR szImgUrl, unsigned short nTagType, unsigned short nAlignment, unsigned short nPosInfo, unsigned short nDirection, unsigned int nImgWidth, unsigned int nImgHeight); HRESULT EmptyGlyphTable(); HRESULT Button(LPCTSTR szId = NULL); HRESULT CheckBox(LPCTSTR szId = NULL); HRESULT DropDownBox(LPCTSTR szId = NULL); HRESULT HorizontalLine(LPCTSTR szId = NULL); HRESULT Iframe(LPCTSTR szId = NULL); HRESULT InsFieldSet(LPCTSTR szId = NULL); HRESULT InsInputButton(LPCTSTR szId = NULL); HRESULT InsInputHidden(LPCTSTR szId = NULL); HRESULT InsInputImage(LPCTSTR szId = NULL); HRESULT InsInputPassword(LPCTSTR szId = NULL); HRESULT InsInputReset(LPCTSTR szId = NULL); HRESULT InsInputSubmit(LPCTSTR szId = NULL); HRESULT InsInputUpload(LPCTSTR szId = NULL); HRESULT ListBox(LPCTSTR szId = NULL); HRESULT Marquee(LPCTSTR szId = NULL); HRESULT Paragraph(LPCTSTR szId = NULL); HRESULT RadioButton(LPCTSTR szId = NULL); HRESULT SaveAs(LPCTSTR szPath = NULL); HRESULT TextArea(LPCTSTR szId = NULL); HRESULT TextBox(LPCTSTR szId = NULL); HRESULT GetAbsolutePosition(bool &bCurValue); HRESULT SetAbsolutePosition(bool bNewValue); HRESULT Set2DPosition(bool bNewValue); HRESULT SetAtomicSelection(bool bNewValue); HRESULT SetAutoURLDetectMode(bool bNewValue); HRESULT SetDisableEditFocusUI(bool bNewValue); HRESULT SetIE5PasteMode(bool bNewValue); HRESULT SetLiveResize(bool bNewValue); HRESULT SetMultiSelect(bool bNewValue); HRESULT SetOverrideCursor(bool bNewValue); HRESULT SetRespectVisInDesign(bool bNewValue); HRESULT GetShowAlignedSiteTags(bool &bCurValue); HRESULT SetShowAlignedSiteTags(bool bNewValue); HRESULT GetShowAllTags(bool &bCurValue); HRESULT SetShowAllTags(bool bNewValue); HRESULT GetShowAreaTags(bool &bCurValue); HRESULT SetShowAreaTags(bool bNewValue); HRESULT GetShowCommentTags(bool &bCurValue); HRESULT SetShowCommentTags(bool bNewValue); HRESULT GetShowMiscTags(bool &bCurValue); HRESULT SetShowMiscTags(bool bNewValue); HRESULT GetShowScriptTags(bool &bCurValue); HRESULT SetShowScriptTags(bool bNewValue); HRESULT GetShowStyleTags(bool &bCurValue); HRESULT SetShowStyleTags(bool bNewValue); HRESULT GetShowUnknownTags(bool &bCurValue); HRESULT SetShowUnknownTags(bool bNewValue); HRESULT GetShowBRTags(bool &bCurValue); HRESULT SetShowBRTags(bool bNewValue); HRESULT PrintDocument(); HRESULT PrintDocument(LPCTSTR szPrintTemplate); HRESULT PrintDocument(bool bShowPrintDialog); HRESULT PrintPreview(); HRESULT PrintPreview(LPCTSTR szPrintTemplate); HRESULT Bold(); HRESULT Copy(); HRESULT Cut(); HRESULT Delete(); HRESULT Indent(); HRESULT Italic(); HRESULT JustifyCenter(); HRESULT JustifyLeft(); HRESULT JustifyRight(); HRESULT Outdent(); HRESULT Paste(); HRESULT RemoveFormat(); HRESULT SelectAll(); HRESULT Underline(); HRESULT Unlink(); HRESULT ClearSelection(); HRESULT Font(); HRESULT RefreshDocument(); HRESULT UnBookmark();
这些成员函数是由本文作者(Ireneusz Zieliński)添加的,旨在使此类更易于使用,并且不是原始 ChtmlEditCtrlBase
类的一部分
BOOL IsBold();
检查当前选中文本是否具有“粗体”属性。
BOOL IsUnderline();
检查当前选中文本是否具有“下划线”属性。
BOOL IsStrikeOut();
检查当前选中文本是否具有“删除线”属性。
BOOL IsItalic();
检查当前选中文本是否具有“斜体”属性。
BOOL CanPaste();
检查当前 HTML 编辑器是否可用粘贴操作。
HRESULT LineBreakNormal();
在当前编辑位置插入一个单换行符(HTML
<BR>
标签)。BOOL IsDesignMode();
检查编辑器是否处于“设计”模式(换句话说,
TRUE
表示可以编辑内容)。HRESULT GetURLsOfAllImages(CStringArray& a_arrImages);
返回当前加载的 HTML 文档中所有图像的 URL 集合。
HRESULT ReplaceImageURL(const CString& a_sUrlToReplace, const CString& a_sUrlToReplaceWith);
用一个图像替换另一个图像。
HRESULT GetDocumentBody(CString& a_sBody, BOOL a_bTextInsteadHTML);
获取消息的正文。正文是 HTML 文档中由
<BODY>
和</BODY>
HTML 标签界定的部分。您可以将第二个参数设置为TRUE
以获取文档内容的纯文本表示。HRESULT Undo();
在编辑器上执行撤销操作。
HRESULT Redo();
在编辑器上执行重做操作。
HRESULT Find();
显示“查找文本”对话框。
HRESULT StrikeOut();
对当前选中文本设置“删除线”属性。
HRESULT SubScriptSelectedText();
对当前选中文本设置“下标”属性。
HRESULT SuperScriptSelectedText();
对当前选中文本设置“上标”属性。
HRESULT SetDocumentCharset(const CString& a_sCharsetEncoding);
为当前加载的 HTML 文档设置新的字符集编码。
HRESULT GetDocumentCharset(CString& a_sCharsetEncoding);
返回一个表示文档当前字符编码的字符串。
HRESULT ShowSource();
使用记事本打开文档的 HTML 源代码。
HRESULT ShowIEOptionsDialog();
显示一个包含 Internet Explorer 选项的对话框。
HRESULT GetBodyBackgroundImage(CString& a_sImage);
获取文档背景图像的 URL。
HRESULT SetBodyBackgroundImage(const CString& a_sImage);
为文档设置新的背景图像。
HRESULT GetBodyProperties(CString& a_sTag);
获取
<BODY>
标签的属性。HRESULT GetBodyBackgroundColor(CString& a_sColor);
获取文档正文的背景颜色。
HRESULT GetBodyTextColor(CString& a_sColor);
获取文档正文的文本颜色。
HRESULT PasteHTMLAtCurrentSelection(const CString& a_sHTMLText, BOOL a_bSetCursorAtBeginingOfInsertedText);
在当前光标位置粘贴 HTML 代码。如果需要,会在插入后将光标移回。
所有这些函数的作用和用法都很容易猜测/理解。其中大多数函数只是 COM 调用的简单封装——因此,如果遇到任何问题——请查看正在调用哪个 COM 函数,并在 MSDN 中查阅相关信息。最终的 MSDN 资源是 CHtmlEditCtrlBase 类的描述。由于我的类只是 CHtmlEditCtrlBase
的 80% 移植版,因此我建议(如有疑问)先阅读此页面。
以下是一些可能为您节省时间的小贴士:
- 在将文档加载到控件中后,调用
SetDesignerMode(TRUE)
函数。在调用Navigate(url...)
之后立即执行此操作可能为时过早(如果机器上安装的 Internet Explorer 版本低于 6.0,该函数将失败)。 - 如果您创建一个空的 HTML 文档并开始编辑,您会很快发现按下 Enter 键会插入一个段落,而不是换行符。这种默认行为很令人烦恼,可以通过两种方式解决:第一,您可以按下 SHIFT + ENTER 组合键;或者,将以下 HTML 文档加载到 HTML 控件中
<HTML> <BODY> <DIV> </DIV> </BODY> </HTML>
- 如果出现编译错误,请确保您的机器上安装了最新的 Platform SDK(最重要的 SDK 是核心和 Internet 开发 SDK)。
在本文的这个时候,我希望您在创建杀手级应用程序的道路上一帆风顺 ;-D。很抱歉我的英语不是我的母语。
关注点
- MSDN 关于 CHtmlEditCtrlBase 类的页面.
- MSDN 关于 IHTMLDocument2 接口的页面.
- MSDN - 编程和重用浏览器 - 概述和教程.
- Microsoft Platform SDK 更新站点.
变更历史
- 2004 年 12 月 27 日:现在,该控件应该可以与 UNICODE 完美配合。添加了故障安全
CopyEx
方法(完整描述在代码(CPP 文件)中)。 - 2004 年 6 月 8 日:更新了演示应用程序。