Click here to Skip to main content
Click here to Skip to main content
Go to top

HTML editor for VC++ 6.0

, 27 Dec 2004
Rate this:
Please Sign up or sign in to vote.
HTML editing control for VC++ 6.0 equivalent to MFC7 CHtmlEditCtrlBase class.

Sample Image - HtmlEdit.gif

Introduction

Today, applications often need a rich user interface. One of them is the ability to compose or edit HTML documents in a easy, effective and reliable way. This article and source code attached gives you a nice control to perform this task. And now, the best part: this control works fine with Microsoft VC++ 6.0!

Background

I'm the author of Tray Helper application. For a long time, I wanted to add a feature to send a colorful HTML mail. After some research, I found that Microsoft did a nice thing implementing IHTMLDocument2 interface (and a few others related to it) - but working with raw COM interfaces is not very easy, effective or programmer-friendly. I think someone from Microsoft also realized that, and in MFC 7.0, there is a very nice wrapper for COM: CHtmlEditCtrlBase class. After examining the code of this class, I decided to port it to MFC 4.0 and VC++ 6.0.

Using the code

The CHtmlEditCtrl2 class I want to introduce there is not only ported from CHtmlEditCtrlBase - I did some other improvements and changes to the original code - so it not only compiles under VC++ 6.0 but also has some new features and is even easier to use in existing projects. The main change was that CHtmlEditCtrl2 class derives from CWebBrowser2. It means that if your projects already use a standard web browser control to display HTML documents - adding editing capabilities would be trivial (read below for a full instruction).

Adding HTML editor to your projects:

Step 1: Adding an ordinary web browser control to your project.

If you already use a web browser control in your project - skip this paragraph and start reading from "Step 2".

Let's assume that you want to add a HTML edit control to your dialog based application. First, you need to add a web browser control that will contain your HTML documents.

  • In order to do it, go to dialog template editor of Visual Studio and click on "Project / Add to project / Components and controls". From pop-up dialog, select "Registered ActiveX controls", and finally select "Web Browser control" (the name of the control depends on the language of your PC - for example, on my Polish version of Windows, it is "Przegladarka Przeglądarka sieci Web firmy Microsoft"). To be sure that you're selecting the right control, check the description below the file list - it should be "WebBrowser control".
  • After selecting a control, a dialog box with CWebBrowser2 class to be created should appear. Click on "OK" without any modifications.
  • Note that new position should be added to tool-bar with list of controls available to insert into dialog. So, select it and just add a web browser!
  • Finally, use a class wizard (Ctrl+W) to add a member variable of type CWebBrowser2 to just add item.
  • Next, you can add a OnInitdialog method to your dialog and request a browser to load a HTML document using Navigate method of CWebBrowser2 class.

Step 2: Adding edit capabilities to web browser.

It's very easy. Just follow these few steps:

  • Copy HtmlEditCtrl2.H and HtmlEditCtrl2.cpp directory with your source files and add them to your project.
  • Modify header file where you have a member variable of CWebBrowser2 declared and change it to CHtmlEditCtrl2.
  • Change #include "WebBrowser2.H" to #include "HtmlEditCtrl2.H".
  • After loading a HTML document (using, for example, Navigate method), call SetDesignMode(TRUE) method to enable edit mode.
  • If after edit is complete, you want to get a source of HTML document, call GetDocumentHTML function.

Highlight of the most important methods of the control (most likely you will need to use them):

  • void Navigate(LPCTSTR URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers)

    Use this function to load a HTML document. Pass as URL, a string with a path to the file to open. It could be a remote site or a local file. Rest of the parameters could be null.

    Examples:

    Navigate("<A href="http://www.codeproject.com/">http://www.codeproject.com/</A>", NULL, NULL, NULL, NULL);
    Navigate("C:\\my_file.html", NULL, NULL, NULL, NULL);
  • BOOL SetDesignMode(BOOL bMode);

    Enables or disables edit mode. In versions of Internet Explorer prior to 6.0, document must be loaded in the first place to enter a design mode.

  • HRESULT GetDocumentHTML(CString& szHTML, BOOL a_bClearDirtyFlag = FALSE);

    Gets the content of HTML document.

  • HRESULT SetDocumentHTML(LPCTSTR szHTML);

    Sets new content for HTML document. Please note that you can't call this function on an empty control. You need to load a document first (for example, by calling the Navigate method).

Complete list of public member functions of CHtmlEditCtrl2 class:

These member functions are taken directly from CHtmlEditCtrlBase class. Full description at MSDN pages (click here):

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();

These member functions were added by the author of this article (Ireneusz Zieliński) just to make the usage of this class easier, and are not a part of the original ChtmlEditCtrlBase class:

  • BOOL IsBold();

    Checks if currently selected text has “bold” attribute.

  • BOOL IsUnderline();

    Checks if currently selected text has “underline” attribute.

  • BOOL IsStrikeOut();

    Checks if currently selected text has “strike-out” attribute.

  • BOOL IsItalic();

    Checks if currently selected text has “italic” attribute.

  • BOOL CanPaste();

    Checks if paste operation is available on HTML editor right now.

  • HRESULT LineBreakNormal();

    Inserts a single line break (HTML <BR> tag) at current editing position.

  • BOOL IsDesignMode();

    Checks if editor is in “designer” mode (in other words, TRUE means that you can edit content).

  • HRESULT GetURLsOfAllImages(CStringArray& a_arrImages);

    Returns a collection of all images present in currently loaded HTML document.

  • HRESULT ReplaceImageURL(const CString& a_sUrlToReplace, const CString& a_sUrlToReplaceWith);

    Replaces an image with a different one.

  • HRESULT GetDocumentBody(CString& a_sBody, BOOL a_bTextInsteadHTML);

    Gets the body of the message. Body is a part of HTML document that is limited by <BODY> and </BODY> HTML tags. You can pass TRUE as a second parameter to get a plain text representation of the content of the document.

  • HRESULT Undo();

    Performs an undo operation on editor.

  • HRESULT Redo();

    Performs a redo operation on editor.

  • HRESULT Find();

    Displays a Find Text dialog.

  • HRESULT StrikeOut();

    Sets a “strike-out” attribute on currently selected text.

  • HRESULT SubScriptSelectedText();

    Sets a “sub-script” attribute on currently selected text.

  • HRESULT SuperScriptSelectedText();

    Sets a “super-script” attribute on currently selected text.

  • HRESULT SetDocumentCharset(const CString& a_sCharsetEncoding);

    Sets a new charset encoding for currently loaded HTML document.

  • HRESULT GetDocumentCharset(CString& a_sCharsetEncoding);

    Returns a string representing the current character encoding of the document.

  • HRESULT ShowSource();

    Opens Notepad with the HTML source of the document.

  • HRESULT ShowIEOptionsDialog();

    Displays a dialog with Internet Explorer options.

  • HRESULT GetBodyBackgroundImage(CString& a_sImage);

    Gets a URL to the background image of the document.

  • HRESULT SetBodyBackgroundImage(const CString& a_sImage);

    Sets a new background image for the document.

  • HRESULT GetBodyProperties(CString& a_sTag);

    Gets proprieties of <BODY> tag.

  • HRESULT GetBodyBackgroundColor(CString& a_sColor);

    Gets background color of document’s body.

  • HRESULT GetBodyTextColor(CString& a_sColor);

    Gets text color of document’s body.

  • HRESULT PasteHTMLAtCurrentSelection(const CString& a_sHTMLText, BOOL a_bSetCursorAtBeginingOfInsertedText);

    Pastes HTML code at the current cursor location. Moves back cursor after inserting, if required.

The meaning and usage of all of these functions are very easy to guess / understand. Most of these functions are simple wrappers over COM calls - so, in case of any problems - check what COM function is being called and read about it in MSDN. The ultimate MSDN resource is a description of CHtmlEditCtrlBase class. Since my class is only an 80% port of CHtmlEditCtrlBase, I recommend to read this page first (in case of any questions).

Here are some tips that could save you some time:

  1. Call SetDesignerMode(TRUE) function when document is loaded into control. Doing it just after calling Navigate(url...) could be too early (function will fail if Internet Explorer prior to version 6.0 is installed on the machine).
  2. If you create an empty HTML document and start editing it - you quickly realize that pressing an Enter key inserts a paragraph, not a line break. This default behavior is pretty irritating and could be solved in two ways: first, you could press SHIFT + ENTER instead, or load into HTML control such an HTML document:
    <HTML>
    <BODY>
    <DIV> </DIV>
    </BODY>
    </HTML>
  3. In case of compilation errors, make sure that you have on your machine the latest Platform SDK installed (the most important are Core and Internet Development SDKs).

At this point of the article, I would like to wish you good luck creating killer applications ;-D. Sorry for my English - it's not my native language.

Points of Interest

History of changes

  • 27th of December 2004: Now, control should work perfect with UNICODE defined. Added fail-safe CopyEx method (full description in code (CPP file)).
  • 8th of June 2004: Updated demo application.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Irek Zielinski
Web Developer
United Kingdom United Kingdom
Irek works as a C++ senior software developer.
He runs also his own small shareware bussines (He is author of few quite popular applications like: Tray Helper or Time Adjuster).
 
Occasionaly he posts articles to Codeguru or Codeproject. Besides C++ he likes motorcycles and paragliding.
Check out his software at: http://www.ireksoftware.com

Comments and Discussions

 
QuestionThe best example of using WindowsWebBrowser control, not the one of !!! Pinmembermargaritaville27-Oct-13 19:51 
Questioni have get the information of the html,how to show the html information to dialog? Pinmemberuukko25-Oct-11 23:52 
GeneralMy vote of 4 Pinmemberjyl_hrb17-Apr-11 21:38 
GeneralBug in GetHTMLDocument using Ansi Pinmemberschmurgulum28-Jan-11 5:31 
hi everybody.
 
on my computer it returns the data in utf-16 which has 2 bytes for each character
 
WideCharToMultiByte(...) the 4th parameter is the number of characters in the string and not the bytelength!
 
it s in:
HRESULT __stdcall CHtmlEditCtrl2::CStreamOnCString::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
 
                int charcount = cb / 2;  // utf-16

		// compiling ANSI and got a UNICODE buffer
		UINT nCharsToSkip = flags & IS_TEXT_UNICODE_SIGNATURE ? 1 : 0;
		unsigned int nChars = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)pw, charcount,
			NULL, 0, NULL, NULL);
 
		char *pBuff = new char[nChars];
		if (pBuff)
		{
			WideCharToMultiByte(CP_ACP, 0, (wchar_t*)pw, charcount, pBuff, nChars, NULL , NULL);
			//IZ replaced: m_strStream.Append(pBuff+nCharsToSkip, nChars-nCharsToSkip);
			AppendToCString(m_strStream, pBuff+nCharsToSkip, nChars-nCharsToSkip);
						
			if (pcbWritten)
			*pcbWritten = cb;
		}
 
insert charcount and fix 2 x WideCharToMultiByte
 

greetings
Schmurgulum
GeneralAdding a "Find and Replace" dialog PinmemberMember 288400822-Sep-10 8:28 
GeneralTool Tips PinmemberAggMeena6-Dec-09 23:51 
GeneralHTML TEXT BOX EDITING CONTROL VC++ 6.0 (NOT WEB BROWSER CONTROL) Pinmembershrikanth 20093-Jun-09 4:50 
GeneralRe: HTML TEXT BOX EDITING CONTROL VC++ 6.0 (NOT WEB BROWSER CONTROL) PinmemberIrek Zielinski7-Dec-09 0:05 
GeneralSetAutoURLDetectMode not work Pinmemberbunpkin20-May-09 0:23 
GeneralRe: SetAutoURLDetectMode not work Pinmemberbunpkin20-May-09 16:19 
QuestionHow to format <h1>,<h2>,<h3>...?</h3></h2></h1> Pinmembery_yy200824-Jan-09 2:10 
QuestionGetHTMLDocument PinmemberNatacha268-Oct-08 4:39 
Answeri found it and correct it as follows: Pinmembery_yy200824-Jan-09 2:01 
AnswerRe: i found it and correct it as follows: PinmemberIrek Zielinski26-Jan-09 1:23 
GeneralThanks, your modificatoin is a bug free! Pinmembery_yy200826-Jan-09 17:27 
QuestionCan we make a DLL of a program which are using ActiveX control Pinmembernitin_pro27-Feb-08 19:38 
Questioncall this application from IE Button PinmemberJD8120-Nov-07 0:22 
Questionerror unresolved external symbol _WinMain@16 PinmemberJD8118-Nov-07 13:39 
AnswerRe: error unresolved external symbol _WinMain@16 PinmemberJD8118-Nov-07 13:57 
Questionhow to find whether the focus is on the browser Pinmemberrupesh_gangi6-Nov-07 1:20 
Questioncuhow to send focus to the browser? Pinmemberrupesh_gangi5-Nov-07 22:20 
GeneralID value erros solution Pinmemberrupesh_gangi5-Nov-07 3:21 
General20 'error C2065' Errors Pinmemberkunal.tawde24-Oct-07 1:33 
GeneralRe: 20 'error C2065' Errors Pinmemberyaron shani30-Oct-07 9:13 
GeneralRe: 20 'error C2065' Errors Pinmembershjw73041-Sep-08 22:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 28 Dec 2004
Article Copyright 2004 by Irek Zielinski
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid