
Introduction
There is an undocumented DLL component used in the Installer of VS.NET that allows you to render HTML for your application, and all from a simple window class.
The control would allow you to render, say, a richly formatted report in your application and display it to the user.
The library is located at \Program Files\Microsoft Visual Studio .NET 2003\Setup\Visual Studio .NET Enterprise Architect 2003 - English with the filename: htmllite.dll (136 Kb).
You must copy the DLL from here and place it with the other source and executable files extracted from the ZIP archive. The DLL has not been included in the ZIP for redistribution reasons.
How to use HTMLLITE
The library is very simple to use. You need to first call a sub aliased:
RegisterHtmlLiteClass
... and this will make ready the window class for use in your application (similar to calling InitCommonControls).
The control can then be created with CreateWindowEx like any other window:
CreateWindowEx(WS_EX_CONTROLPARENT, "HTMLLITE",
"TODO: HTML goes here...", WS_CHILD | WS_VISIBLE,
10, 10, 500, 500, hWnd, 0, 0, 0);
The control is then ready and visible on your parent window.
Under the hood
A few weeks ago when I first started tinkering with HTMLLITE, I spent a few hours on that ancient utility called Spy++ to see what messages HTMLLITE was using...
I found that HTMLLITE works very similar to the standard Windows Common Controls, such as ListViews. It makes use of WM_NOTIFY, to send notifications to your application about mouse clicks, moves, and others.
The lParam of the WM_NOTIFY contains a pointer to a NMHDR structure, and like any other control, the members are no different... hwndFrom, idFrom and code.
'Code' was the important one, so I set about learning what each code meant and came up with the following:
#define HTMLLITE_CODE_LEFTCLICK 1000
#define HTMLLITE_CODE_TABCYCLE 1001
#define HTMLLITE_CODE_RIGHTCLICK 1003
#define HTMLLITE_CODE_MOUSEOVER 1004
#define HTMLLITE_CODE_MOUSEHOVER 1005
#define HTMLLITE_CODE_MOUSEEXIT 1006
Simple.
The control also uses its window text/caption as the source for the HTML. So if you want to change the HTML content after it has been created, simply send a WM_SETTEXT message containing the new HTML.
Next step was to find a way to determine which hyperlink had been clicked in any given HTMLLITE control instance. As pot luck had it, a couple of days ago I stumbled upon the MSDN pages about the SYSLINK control (new with Common Controls v6). The SYSLINK control is similar to HTMLLITE except it can only render simple <a href> style markup. I tried out the notification structure of the SYSLINK control to see if HTMLLITE used anything similar.. and.. hut-damn, it did:
typedef struct tagNMLINK { NMHDR hdr;
LITEM item;
} NMLINK, *PNMLINK;
After about half an hour I had reversed the entire HTMLLITE NM structure...
The most important member is linkid. This member contains the value of the parameter linkid used in a <a href="..."> style markup. So if you have more than one link in a HTMLLITE control, simply add linkid parameters to your <a>'s and they will be filled into the following structure's similarly named member.
typedef struct NMHTMLLITE {
//The Window Handle (hWnd) of the HTMLLITE control
//... sending you this message.
DWORD hwndFrom;
//If your HTMLLITE control is on a dialog, this member
//... contains its Dialog ID.
DWORD idFrom;
//As defined below. As an example, this member will
//... equal HTMLLITE_CODE_LEFTCLICK when a Link has
//... been Left-clicked.
DWORD code;
//When you create a Link with <a href="..." linkid=xxx>
//... the linkid parameter is filled in this member.
//.. allowing you to know which link has been clicked
//... in your HTMLLITE control and then perform a specific action.
DWORD linkid;
//This is a RECT structure which contains the coord //... dimensions of the Link concerned.
RECT linkrc;
} NMHTMLLITE, *LPNMHTMLLITE;
Easy peasy.
Extent of HTML implementation?
Well to be honest, I am unsure. I know it seems to use CSS-alike HTML, but it is not really W3C quality :)
Here are a few pieces of markup that MS .NET apps use, so you'll know how much I know:
<p highlight=#003399 padding-left=20 padding-top=14 padding-bottom=14>
<font face="arial" size=12pt color="white"><b>Microsoft®</b></font>
<br><font face="arial" size=22pt color="white">Visual Studio® .NET Setup
</font></p>
<p align="right"><a color=#3F4F7F HOVER-COLOR=#C3120C linkid=211>
<b>Text goes here</b></a></p>
Earlier today I checked if Tables would work - they didn't.
Please post comments in the section below, so we can fill the holes in this particular area.
I am the lead developer of numerous .NET-based networking and communication server systems for Windows, for a company based in Cambridge. Including SMS/SMPP, VOIP and VoiceXML technologies.