XHTMLCtrl
There are many places in an application where nice text formatting will give your software a polished look - like in about boxes, splash screens, and even registration dialogs. How to accomplish this while avoiding the complexity of the rich edit control and the bloat of the web browser control is the big challenge.
XHTMLCtrl (formerly called XHTMLStatic) was created to offer a light-weight alternative: a simple API, and support for basic HTML tags, images, and hyperlinks. XHTMLCtrl can be used in MFC and non-MFC applications, and comes with full source code, like all Hans Dietrich Software Components.
XHTMLCtrl Demo
The demo project provides a sample app that shows what the XHTMLCtrl control looks like:
The Headings dialog shows the default headings:
The Image Gallery dialog shows some additional ways to display images:
Press the "View HTML" button and the HTML is shown:
XHTMLCtrl Features
The following HTML tags are supported by XHTMLCtrl:
| Tag | Syntax | Attributes |
|---|---|---|
| A - Anchor | <A>...</A> | TITLE="title string" HREF="http://www.hdsoft.org" HREF="mailto:jon@company.com" HREF="app:MY_COMMAND_MESSAGE" ‡ |
| BIG - Big Text | <BIG>...</BIG> | |
| B - Bold Text | <B>...</B> | |
| BR - Line Break | <BR> | |
| CENTER - Center Text | <CENTER>...</CENTER> | |
| CODE - Software Code Text | <CODE>...</CODE> | |
| FONT - Font Change | <FONT>...</FONT> | COLOR="Color string" BGCOLOR="Color string" ‡ SIZE="Size adjustment" FACE="Font face name" |
| Hn - Header n (H1 thru H6) | <Hn>...</Hn> | |
| HR - Horizontal Rule | <HR> | SIZE=Line thickness |
| I - Italic Text | <I>...</I> | |
| IMG - Image | <IMG...> | SRC="source url" TITLE="title string" ID="resource id number" TYPE="resource type string" ‡ WIDTH="width in pixels" HEIGHT="height in pixels" ALIGN="alignment" |
| P - Paragraph | <P> | |
| SMALL - Small Text | <SMALL>...</SMALL> | |
| STRIKE - Strike-through Text | <STRIKE>...</STRIKE> | |
| SUB - Subscript Text | <SUB>...</SUB> | |
| SUP - Superscript Text | <SUP>...</SUP> | |
| U - Underlined Text | <U>...</U> |
Using the APP: Hyperlink
To see the APP: hyperlink in action, click on the "Moby Dick" title, and you will see how the parent dialog catches the APP: message:
Using an APP: hyperlink in a XHTMLCtrl control involves three steps:
- Define the APP: struct - here is an example from XHTMLCtrlTestDlg.cpp:
XHTMLCTRL_APP_COMMAND AppCommands[] = { { m_hWnd, WM_APP_COMMAND_1, 1, _T("WM_APP_COMMAND1") }, { m_hWnd, WM_APP_COMMAND_2, 2, _T("WM_APP_COMMAND2") } };You can add as many entries as you need. Each entry has four elements: the first is theHWNDof the window that is to receive the message; the second is the numeric message number that will be sent to the window viaSendMessage(); the third is user-defined data that is returned in the wParam member; and the fourth is a string that ties the table entry to the HTML code. When the user clicks on the link, XHTMLCtrl will scan the table trying to find a match for the string that follows the "app:". Then, it will extract the message number from the table and send the message. - Pass the table address to the XHTMLCtrl control:
m_Html1.SetAppCommands(m_AppCommands, 1);
This function passes the table address and the number of entries in the table. The XHTMLCtrl control makes its own copy of the table, so the parent need not ensure its persistence. - Insert the hyperlink in the HTML - in XHTMLCtrlTestDlg.cpp, the HTML for the APP: hyperlink (shown here without the font tags) is written as:
_T("<a href=\"app:WM_APP_COMMAND1\">Moby Dick</a>")The string "WM_APP_COMMAND" that follows the app: is what ties the hyperlink to the app command table of Step 1. Note that this string may be anything you wish; to improve readability, you can use the "string form" of the actual message command constant.
Using the FONT Tag
The FONT COLOR and BGCOLOR attributes both take a color string value, which is a string in one of three forms:
- "color-name" - Example: "red".
- "hex-value" - Example: "#FF0000".
- "rgb-value" - Example: "255,0,0".
The SIZE attribute for FONT currently takes only relative size adjustments - plus or minus. For example, SIZE="+4" or SIZE="-2".
Using the IMG Tag
An image may be displayed from an embedded resource or an external file (local, usingfile:///, or remote, using http://):
- Embedded resource:
_T("<img type=\"999\" id=\"144\" title=\"whale\" align=\"right\" width=\"48\" height=\"48\">")The type and id attributes specify the resource type and resource id of the embedded image. The image was embedded as a resource using this resource command:IDR_IMAGE4 999 DISCARDABLE "res\\whale.jpg"
whereIDR_IMAGE4= 144. The resource type was arbitrarily picked to be 999; it can be anything not already used by the resource compiler – see winuser.h for a complete list ofRT_xxxxresource types. - Local file:
_T("<img src=\"file:///C:/temp/whale.jpg\" title=\"whale\" align=\"right\" width=\"48\" height=\"48\">")The attribute src is used to specify the file: protocol for the local file C:/temp/whale.jpg. - Remote file:
_T("<img src=\"http://www.hdsoft.org/images/whale.jpg\" title=\"whale\" align=\"right\" width=\"48\" height=\"48\">")The attribute src is used to specify the http: protocol for the remote file www.hdsoft.org/images/whale.jpg.
- left - Position image at the left edge of the control; subsequent text will flow around image.
- right - Position image at the right edge of the control; subsequent text will flow around image.
- bottom (default) - Position image at baseline of current text.
Setting Colors and Fonts
In addition to using the FONT tag to set colors and font, you can also use the XHTMLCtrl APIs. These APIs allow you to set colors and font for any or all of the six headers, plus the current text color and font:
| Function | Description |
|---|---|
| COLORREF GetBkColor(int index = -1) | Retrieves the background color for the heading (0 - 5) or current text (-1) |
| LOGFONT& GetLogFont(int index = -1) | Retrieves the logfont struct for the heading (0 - 5) or current text (-1) |
| COLORREF GetTextColor(int index = -1) | Retrieves the text color for the heading (0 - 5) or current text (-1) |
| void SetAllBkColor(COLORREF rgb) | Sets the background color of all headings and current text to RGB value |
| void SetAllBkColor(LPCTSTR lpszColor) | Sets the background color of all headings and current text to named color |
| void SetAllTextColor(COLORREF rgb) | Sets the text color of all headings and current text to RGB value |
| void SetAllTextColor(LPCTSTR lpszColor) | Sets the text color of all headings and current text to named color |
| COLORREF SetBkColor(COLORREF rgb, int index = -1) | Sets the background color for the heading (0 - 5) or current text (-1) to RGB value |
| COLORREF SetBkColor(LPCTSTR lpszColor, int index = -1) | Sets the background color for the heading (0 - 5) or current text (-1) to named color |
| void SetLogFont(const LOGFONT& lf, int index = -1) | Sets the font for the heading (0 - 5) or current text (-1) |
| COLORREF SetTextColor(COLORREF rgb, int index = -1) | Sets the text color for the heading (0 - 5) or current text (-1) to RGB value |
| COLORREF SetTextColor(LPCTSTR lpszColor, int index = -1) | Sets the text color for the heading (0 - 5) or current text (-1) to named color |
XHTMLCtrl ToolTips
Tooltips are available for anchor <A> tags and image <IMG> tags. For anchor tags, the url string is the default tooltip, unless the TITLE attribute is specified. However, the APP: hyperlink string is never used as a tooltip.For image tags, a tooltip may be specified with the TITLE attribute; there is no default tooltip for image tags.
Using Character Entities
Support for character entities was one of the features most requested for the last version. I wanted to support all the commonly used ones, but I did not want a huge table with characters that most people would never use. The compromise: a table-driven entity lookup, with a table that can be easily added to.
Here's how it works:
- The entity table is defined in XHTMLCtrl.h as
static XHTMLCtrl_CHAR_ENTITIES m_aCharEntities[];
Each of the table entries is defined as:struct XHTMLCtrl_CHAR_ENTITIES { TCHAR * pszName; // string entered in HTML - e.g., " " TCHAR cCode; // code generated by XHTMLCtrl TCHAR cSymbol; // character symbol displayed }; - The table is specified in XHTMLCtrl.cpp:
XHTMLCtrl_CHAR_ENTITIES CXHTMLCtrl::m_aCharEntities[] = { { _T("&"), 0, _T('&') }, // ampersand { _T("•"), 0, _T('\x95') }, // bullet NOT IN MS SANS SERIF { _T("¢"), 0, _T('\xA2') }, // cent sign { _T("©"), 0, _T('\xA9') }, // copyright { _T("°"), 0, _T('\xB0') }, // degree sign { _T("€"), 0, _T('\x80') }, // euro sign { _T("½"), 0, _T('\xBD') }, // fraction one half { _T("¼"), 0, _T('\xBC') }, // fraction one quarter { _T(">"), 0, _T('>') }, // greater than { _T("¿"), 0, _T('\xBF') }, // inverted question mark { _T("<"), 0, _T('<') }, // less than { _T("µ"), 0, _T('\xB5') }, // micro sign { _T("·"), 0, _T('\xB7') }, // middle dot = Georgian comma { _T(" "), 0, _T(' ') }, // nonbreaking space { _T("¶"), 0, _T('\xB6') }, // pilcrow sign = paragraph sign { _T("±"), 0, _T('\xB1') }, // plus-minus sign { _T("£"), 0, _T('\xA3') }, // pound sign { _T("""), 0, _T('"') }, // quotation mark { _T("®"), 0, _T('\xAE') }, // registered trademark { _T("§"), 0, _T('\xA7') }, // section sign { _T("¹"), 0, _T('\xB9') }, // superscript one { _T("²"), 0, _T('\xB2') }, // superscript two { _T("³"), 0, _T('\xB3') }, // superscript three { _T("×"), 0, _T('\xD7') }, // multiplication sign { _T("™"), 0, _T('\x99') }, // trademark NOT IN MS SANS SERIF { NULL, 0, 0 } // MUST BE LASTTo add an entry, just follow the same format as for the other entries. You can the Microsoft Character Map utility, charmap.exe, to obtain the hex display code. - That's it! The XHTMLCtrl control will now substitute the display code whenever it sees the entity name.
The following table shows how the character entities will be displayed:
| Entity | Display Symbol | Description |
|---|---|---|
| & | & | ampersand |
| • | • | bullet (not in MS SANS SERIF) |
| ¢ | ¢ | cent sign |
| © | © | copyright |
| ° | ° | degree sign |
| € | € | euro sign |
| ½ | ½ | fraction one half |
| ¼ | ¼ | fraction one quarter |
| > | > | greater than |
| ¿ | ¿ | inverted question mark |
| < | < | less than |
| µ | µ | micro sign |
| · | · | middle dot = Georgian comma |
| | nonbreaking space | |
| ¶ | ¶ | pilcrow sign = paragraph sign |
| ± | ± | plus-minus sign |
| £ | £ | pound sign |
| " | " | quotation mark = double quote |
| ® | ® | registered trademark |
| § | § | section sign |
| ¹ | ¹ | superscript one |
| ² | ² | superscript two |
| ³ | ³ | superscript three |
| × | × | multiplication sign |
| ™ | ™ | trademark (not in MS SANS SERIF) |
Current Limitations
- The supported HTML tags are limited to those listed above.
- There are some simplifying assumptions made when parsing the HTML - for example, it is assumed there are no spaces between the < and the beginning of the tag.
How To Use
Step 1: Integrate Files in MFC App
[If you are compiling a non-MFC app, go to Step 2.]
To integrate XHTMLCtrl into an MFC app, add the following files to your project:
- XHTMLCtrl.cpp
- XHTMLCtrl.h
- XDisplayImage.cpp
- XDisplayImage.h
- XNamedColors.cpp [Note: does not use precompiled headers]
- XNamedColors.h
- XArray.h
- XStack.h
XHTMLCTRL_USE_MFC is defined in XHTMLCtrl.h, and that stdafx.h is included in XHTMLCtrl.cpp.
Step 2: Integrate Files in non-MFC App
[If you are compiling an MFC app, go to Step 3.]
To integrate XHTMLCtrl into a non-MFC app, add the following files to your project:
- XHTMLCtrl.cpp
- XHTMLCtrl.h
- XDisplayImage.cpp
- XDisplayImage.h
- XNamedColors.cpp [Note: does not use precompiled headers]
- XNamedColors.h
- XArray.h
- XStack.h
- CXDC.h
- CXPoint.h
- CXRect.h
- CXToolTipCtrl.h
- CXWaitCursor.h
- wtlstring.h
XHTMLCTRL_USE_MFC is not defined in XHTMLCtrl.h, and that stdafx.h is not included in XHTMLCtrl.cpp.
Step 3: Create the Control
Create a static control on your dialog, where you want to put the new XHTMLCtrl control. Also assign a variable name to this static (e.g., IDC_FRAME1) using ClassWizard. Using a static control as a frame is a convenient way to obtain a rect for the XHTMLCtrl control.
Next, include the header file XHTMLCtrl.h in dialog's header file, and insert a variable for the CXHTMLCtrl. This shows header file XHTMLCtrlTestDlg.h from demo:
CXHTMLCtrl m_Html1;
CXHTMLCtrl m_Html2;
Now you can create the XHTMLCtrl:
CRect rectFrame;
GetDlgItem(IDC_FRAME1)->GetWindowRect(&rectFrame);
ScreenToClient(&rectFrame);
GetDlgItem(IDC_FRAME1)->ShowWindow(SW_HIDE);
VERIFY(m_Html1.Create(AfxGetInstanceHandle(), WS_CHILD | WS_VISIBLE | WS_TABSTOP,
rectFrame, m_hWnd, 9001));
Step 4: Add Text to the Control
Final step is to put some text into XHTMLCtrl control:
m_Html1.SetWindowText(_T("<b><font size=\"+8\">Moby Dick</font></b>"));
For more details on how to use CXHTMLCtrl, see XHTMLCtrlTestDlg.cpp.
Revision History
Version 2.4
- Fixed problem with left margin
- Fixed problem with <center>
- Implemented <HTML>, <TITLE>, and <BODY>
- Implemented GetTitleText()
Version 2.0
- Implemented <IMG> tag.
- Implemented <P> tag.
- Implemented <H1>...<H6> tags.
- Added TITLE attribute to <A> tag
- Control can now be resized (
WM_SIZE). - Removed MFC dependency; control can now be used in MFC or non-MFC app.
Version 1.4
- Fixed bug where text could be written outside of control's client rect, reported (with fix) by David Pritchard.
- Expanded table of character entities.
- Added VS2005 project.
- Implemented memory DC to improve performance, suggested by conan.ks.
- Switched from WM_TIMER to WM_MOUSEMOVE for display of hand cursor, suggested by rm2 and RichardC. This prevents hand cursor from appearing on overlapping windows.
Version 1.3
- Added transparency support, suggested by Anna.
- Added support for
WM_PRINT, suggested by beaus07. - Added support for <center>, requested by several readers.
- Added support for tooltips for hyperlinks.
- Load hand cursor from
IDC_HAND, suggested by kamnas. - Fixed font object leak, reported by furbo.
- Fixed problem with
SetWindowText()reported by Andro67; the background and text colors are no longer reset whenSetWindowText()is called. - Fixed bug when control is hidden, reported by RichardC.
Version 1.2
- Changed APP: hyperlink to use HWND instead of
GetParent. - Added wParam to
XHTMLSTATIC_APP_COMMANDstruct. - Added function
SetTextColor(LPCTSTR lpszColor). - Added function
SetLogFont(const LOGFONT * pLogFont). - Added function
SetWindowText()to call Init andRedrawWindow. - Fixed bug with
XNamedColorsin handling of "255,0,0" style. - in
SetColorFromString(). - Fixed bug with descenders of large serif fonts.
Version 1.1
- Implemented SUB tag.
- Implemented SUP tag.
- Implemented BIG tag.
- Implemented SMALL tag.
- Implemented CODE tag.
- Implemented HR tag.
- Implemented APP: hyperlink.
- Implemented common character entities.
- Improved parsing performance.
- Bug fixes.
Version 1.0
- Initial release.
Buy latest version
| Buy XHTMLCtrl 2.4 license – $35.00 per developer |