SQHMTree
An ActiveX control for browsing the HTML structure of a page open in
HoTMetaL
Introduction
SQHMTree is an ActiveX control for viewing and browsing the structure of
an open HoTMetaL document. These notes describe how to create SQHMTree, and how
to embed it in the HoTMetaL Resource Manager.
We used Microsoft Visual C++ 5.0 to create SQHMTree, but the steps are
the same for Visual C++ 6.0. We assume readers have a basic understanding of
how to use Visual C++ and HoTMetaL.
Create a new project
- In Visual C++, choose New from the File menu.
- A tabbed dialog is displayed; click on the Projects tab.
- In the Projects tab:
- Select MFC ActiveX ControlWizard.
- Enter SQHMTree as the Project name.
- Click on OK.
- The MFC ActiveX Control Wizard is displayed. In the Page 1
of 2 dialog, make the following choices:
- Number of controls: 1
- Runtime license: No
- Source file comments: Yes
- Help files: No
- Click on Next>.
- In the Page 2 of 2 dialog, make the following choices:
- Control to browse: SQHMTree
- Activate when visible: Yes
- Invisible at runtime: No
- Available in Insert Object Dialog: No
- Has About Box: Yes
- Acts as simple frame control: No
- Subclass: none
- Advanced: No
- Click on Finished.
Add the HoTMetaL interfaces to the SQHMTree project
We made SQHMTree an automation client of HoTMetaL so that it can
efficiently manipulate HoTMetaL objects (such as Document, DOMNode, etc.).
SQHMTree needs to have the information about the server (HoTMetaL) objects'
properties and methods. We made this information available to SQHMTree by
creating dispatch classes from HoTMetaL's type library and adding them to
SQHMTree project:
- Choose Class Wizard... from the View menu.
- Click on the Class Info tab.
- Click on the Add Class button and choose From a type
library... from the pop-up menu.
- Browse to the HoTMetaL installation directory and open the file
hmpro6.tlb (or hmpro6.exe).
- In the Confirm Classes dialog, select all the classes (you can
use Shift-Click to do this).
- Click on OK.
- Click on OK in the MFC Class Wizard dialog.
Design CMyTreeCtrl
CMyTreeCtrl is derived from a standard MFC class:
CTreeCtrl. It contains the hierarchical structure of an .html document.
A left mouse click on a tree item will cause HoTMetaL to move the insertion
point of the current document to the beginning of the node represented by the
tree item that was clicked on.
- Right-click on SQHMTree classes in the Class View tab
and choose New Class... from the pop-up menu.
- Add a class named CMyTreeCtrl into SQHMTree project, and
specify it is derived from CTreeCtrl:
- Enter CMyTreeCtrl as the class name.
- Choose CTreeCtrl from the Base class list.
- Add a context menu m_menu to CMyTreeCtrl. m_menu
contains the menu item to refresh the tree.
- In the Class View tab, right-click on CMyTreeCtrl
and choose Add Member Variable... from the pop-up menu.
- Enter CMenu as the Variable type
- Enter m_menu as the Variable name
- Append the menu item to it inside the constructor of
CMyTreeCtrl (located in the file MyTreeCtrl.cpp). The code is
written as follows:
CMyTreeCtrl::CMyTreeCtrl() {
m_menu.CreatePopupMenu();
m_menu.AppendMenu( MF_STRING, ID_REFRESH_TREE,__T("Refresh") );
}
- Add three message handlers: OnLButtonDown(),
OnRButtonDown(), and OnRefreshTree() to CMyTreeCtrl:
OnLButtonDown() informs HoTMetaL when it should move its insertion
point; OnRButtonDown() displays the context (pop-up) menu;
OnRefreshTree() forces the control to refresh its contents, based the
active HoTMetaL document.
- In the Class View tab, right-click on CMyTreeCtrl
and choose Add Windows message Handler... from the pop-up menu.
- Choose WM_LBUTTONDOWN from the list on the left and click
on Add Handler.
- Do the same for WM_RBUTTONDOWN.
- Create the resource symbol ID_REFRESH_TREE for the menu item
Refresh and add the message handler for it (created inside the
constructor of CMyTreeCtrl): the handler is named OnRefreshTree( ) and
should be created in the file MyTreeCtrl.cpp. The code is written as
follows:
void CMyTreeCtrl::OnRefreshTree()
{
DeleteAllItems();
CWaitCursor dummy;
LoadXMLDocElements();
}
- Add method LoadXMLDocElements(),which loads the elements of
the active HoTMetaL document.
- In the Class View tab, right-click on CMyTreeCtrl
and choose Add Member Function... from the pop-up menu.
- Enter LoadXMLDocElements() for the Function
Declaration
- Enter BOOL for the function type.
- The function code is written as follows (in the file
MyTreeCtrl.cpp):
BOOL CMyTreeCtrl::LoadXMLDocElements() {
// Connect to HoTMetaL
COleException e;
_Application xmetalApp;
if (!xmetalApp.CreateDispatch(XMETALAPP_GUID, &e)) {
::AfxMessageBox(IDS_ERR_DISPATCH);
return S_FALSE;
}
_Document xmetalDoc = xmetalApp.GetActiveDocument( );
// If not document open, display stub
if (!xmetalDoc ) {
// Insert a empty root item when no active document is open
SetNoDocument();
return S_FALSE;
} DOMNode domEle = xmetalDoc.GetDocumentElement( );
// If no document element available, display stub
if (!domEle ) {
// Insert a empty root item when no active document is open
TV_INSERTSTRUCT tvstruct;
tvstruct.hParent = NULL;
tvstruct.hInsertAfter = TVI_SORT;
tvstruct.item.iImage = 0;
tvstruct.item.iSelectedImage = 0;
tvstruct.item.pszText = __T("(empty)");
tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE
| TVIF_TEXT | TVIF_PARAM;
InsertItem( &tvstruct );
return S_FALSE;
}
// Insert the element names into the tree, starting with the root
int index = 0;
InsertElement( NULL, domEle, index );
// Enable "Refresh" context menu
m_menu.EnableMenuItem( ITEM_REFRESH_TREE, TRUE );
// Expand the tree to the first level
Expand(GetRootItem(), TVE_EXPAND);
return TRUE;
}
Design the ActiveX control CSQHMTreeCtrl
CSQHMTreeCtrl is the ActiveX control generated by the wizard. We
need to do some modifications:
- Add a member variable m_tree, which is an object of class
CMyTreeCtrl.
- In the Class View tab, right-click on CMyTreeCtrl
and choose Add Member Variable... from the pop-up menu.
- Enter CMyTreeCtrl as the Variable type
- Enter m_tree as the Variable name
- Override the OnCreate() method; inside this method we create
m_tree and initialize it.
- In the Class View tab, open SQHMTree classes
- Right-click on CSQHMTreeCtrl
- Choose Windows Message Handler from the pop-up menu
- Find WM_CREATE in the list on the left, and double-click
on it.
- See the supplied source code for the body of OnCreate().
- Override the OnSize( ) method; inside this method,
we resize m_tree to the full size of CSQHMTreeCtrl whenever
CSQHMTreeCtrl's size changes. The steps for doing this are basically the
same as for creating OnCreate(): when you create the Windows Message
Handler, choose WM_SIZE. The code for the method is as follows:
void CSQHMTreeCtrl::OnSize(UINT nType, int cx, int cy)
{
COleControl::OnSize(nType, cx, cy);
m_tree.MoveWindow( 0, 0, cx, cy );
}
- Refer to the supplied Visual C++ project for the remaining
code and resources required for the project.
Embed the SQHMTree control in HoTMetaL
After successfully compiling the project, we now embed this control in
HoTMetaL, and use it as a tool to navigate the structure of the active HoTMetaL
document:
- Create a folder (for example, treeView ) under the
Assets folder in the HoTMetaL installation folder.
- Create a HTML file named fxindex.htm under treeView .
By default, when an asset folder is selected, HoTMetaL looks for a file
named fxindex.htm under this folder, and opens it in the Resource
Manager browser window. To enable SQHMTree to be correctly opened in the
browser, the content of fxindex.htm might look like:
<HTML>
<HEAD>
<TITLE>Document Tree View</TITLE>
<LINK REL="STYLESHEET" HREF="fxindex.css">
</HEAD>
<BODY>
<OBJECT CLASSID="clsid:94402467-597A-11D3-BB28-006097043CC8"
ID="TreeView" WIDTH="100%" HEIGHT="100%" BORDER="3D"
ALIGN="left" HSPACE="0%" VSPACE="0%">
</OBJECT>
</BODY>
</HTML>
- Create a style sheet file named fxindex.css in the
treeView folder:
BODY {
margin-top: 0pt;
margin-left: 0pt;
margin-right: 0pt;
margin-bottom: 0pt;
}
Since the SQHMTree control has its own scroll bar, you may want to
disable the Resource Manager scroll bar. To do so, you only need to create an
empty file named noscrollbar.txt in the treeView folder.