65.9K
CodeProject 正在变化。 阅读更多。
Home

VC++ 6.0 的 HTML 编辑器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (34投票s)

2004年5月25日

7分钟阅读

viewsIcon

368082

downloadIcon

8975

VC++ 6.0 的 HTML 编辑控件,功能相当于 MFC7 的 CHtmlEditCtrlBase 类。

Sample Image - HtmlEdit.gif

引言

如今,应用程序常常需要丰富的用户界面。其中一项功能就是能够以简单、有效且可靠的方式撰写或编辑 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.HHtmlEditCtrl2.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% 移植版,因此我建议(如有疑问)先阅读此页面

以下是一些可能为您节省时间的小贴士:

  1. 在将文档加载到控件中后,调用 SetDesignerMode(TRUE) 函数。在调用 Navigate(url...) 之后立即执行此操作可能为时过早(如果机器上安装的 Internet Explorer 版本低于 6.0,该函数将失败)。
  2. 如果您创建一个空的 HTML 文档并开始编辑,您会很快发现按下 Enter 键会插入一个段落,而不是换行符。这种默认行为很令人烦恼,可以通过两种方式解决:第一,您可以按下 SHIFT + ENTER 组合键;或者,将以下 HTML 文档加载到 HTML 控件中
    <HTML>
    <BODY>
    <DIV> </DIV>
    </BODY>
    </HTML>
  3. 如果出现编译错误,请确保您的机器上安装了最新的 Platform SDK(最重要的 SDK 是核心和 Internet 开发 SDK)。

在本文的这个时候,我希望您在创建杀手级应用程序的道路上一帆风顺 ;-D。很抱歉我的英语不是我的母语。

关注点

变更历史

  • 2004 年 12 月 27 日:现在,该控件应该可以与 UNICODE 完美配合。添加了故障安全 CopyEx 方法(完整描述在代码(CPP 文件)中)。
  • 2004 年 6 月 8 日:更新了演示应用程序。
© . All rights reserved.