HTMLayout Embedding Principles
HTMLayout is a "plain" Windows DLL means it does not require any component technology to be embedded in your application. External interface and HTMLayout embedding principles are similar to Windows Common Controls practice of use.
To create an instance of HTMLayout you will call ::CreateWindow[Ex] Windows API function. To load HTML in it you may use either ::HTMLayoutLoadHtml to load markup from memory or ::HTMLayoutLoadFile to load it from local file system or from the Internet. To get a Windows class name of HTMLayout window use HTMLayoutClassName() function.
HTMLayout uses standard WM_NOTIFY message mechanism to call back host application.
Groups of callback events generated by HTMLayout:
- Control creation: HLN_CREATE_CONTROL, HLN_CONTROL_CREATED and HLN_DESTROY_CONTROL.
Host application can handle this events to create its own child controls for standard input elements: <INPUT>, <TEXTAREA>, <SELECT>, <IFRAME> or <OBJECT>.
- Resource loading: HLN_LOAD_DATA, HLN_DATA_LOADED and HLN_DOCUMENT_COMPLETE.
Host application will handle this to provide HTMLayout resources referred by loading HTML. For example application may store images and style sheets in its resource section and load them into HTMLayout from there.
- Behavior creation: HLN_ATTACH_BEHAVIOR.
Host application can subclass and override standard behaviors of HTML elements by creating special behavior handlers. HTML author can assign such behaviors by using behavior CSS attribute. E.g. <div style="behavior:menu">
HTMLayout SDK contains set of ready to use behavior implementations: hyperlink, command, collapsible, etc.
Host application can dynamicly change current document layout by manipulating DOM elements: hide/show and insert/remove portions of DOM tree.
1. Attaching HTMLayout functionality to existing window.
Along with standard way of HTMLayout creation using CreateWindow API call, HTMLayout also supports "functional mixin" style of integration - it can be attached to any already existing window class.
Motivation: some component sytems, e.g. ActiveX or .NET containers do many things "under the hood" managing container/children relationship. In this environments you may choose to assign HTMLayout functionality to existing class rather than redesigning the whole infrastructure.
To use this mode it is enough to call HTMLayoutProcND function from window procedure of your window class. This function declared as standard Microsoft Windows window procedure with one additional parameter to report "handled" status of message processing:
LRESULT HTMLayoutProcND(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL* pbHandled);
If HTMLayoutProcND reports that given message has been processed you don't need to call default window procedure of your container.
Typical example of HTMLayout mixin (MFC):
class MyClass: CWnd //or any other CWnd derived class
typedef CWnd super; // our superclass we derived from
virtual LRESULT WindowProc(UINT message,WPARAM wParam,LPARAM lParam );
BOOL handled = FALSE;
LRESULT lr = HTMLayoutProcND( m_hWnd, message, wParam, lParam, &handled );
if( handled ) return lr; // HTMLayout processed the message
return super::WindowProc(message,wParam,lParam ); // call superclass window proc
2. Embedding custom controls into HTML
HTMLayout allows to define HTML and manage layout of any type of custom HWND based control.
To define control of your choice you may use <INPUT type="mycontroltype"> or <WIDGET type="mycontroltype">...</WIDGET> markup.
After parsing document HTMLayout will generate HLN_CREATE_CONTROL notification informing host application about control creation. Application can handle such notification and create window (HWND) using value of type attribute as a class designator. Host application may not create new control but return HWND of existing control instead. It is up to your design.
2.1. <INPUT> and <WIDGET>
In standard HTML all controls are inline blocks - <input>, <select> and <textarea> are all inline elements.
To be able to handle wider variety of input widgets and their postioning HTMLayout introduces new element - <widget>. <widget> is a block HTML element and tag which means:
- <widget> must be always closed by using either <widget ... /> form or by tail </widget> markup.
- In layout <widget> behaves as a block element similar to <div>.
- <widget> can be used for defining intrinsic controls too. For example to define block level textarea element use: <widget type=textarea>... text ... </widget>.
There are some types of UI controls which are definitely block elements. For example TreeView and ListView common controls are not designed to be used inline.
Being block element, <widget> allows to handle more naturaly heights given in % and %% units. Remember that following markup:
while being parsed will be transformed into:
This is a requirement of HTML specification. As you may see calculation of heights given in % or %% units for inline input elements is ambiguous in this case - it is not clear which element should be used as a parent for % calculation.
<widget> element solves this problem as it does not require text container.
2.3. Custom controls. Dimensions, fonts and colors.
After generation of HLN_CREATE_CONTROL notifications and if NMHL_CREATE_CONTROL.outControlHwnd field was set by application to valid window handle (application specific custom control) HTMLayout does following:
- Sends WM_SETFONT message with the font handle determining by style attributes.
- By using ::GetWindowRect API call it inspects its dimensions. These dimensions become "minimum intrinsic control dimension". HTMLayout uses these values for setting default width and height of the element.
- In runtime HTMLayout uses this "minimum intrinsic control dimension" and standard CSS attributes: width, min-width, max-width, height, min-height and max-height for calculating actual control dimension.
If it is needed your control may use standard WM_CTLCOLORSTATIC or WM_CTLCOLOREDIT messages before rendering to get background brush and text colors.