The first step is to create a new project.
Projects
tab, select MFC
ActiveX ControlWizard
.Project name
enter
SQHMTree.The MFC ActiveX Control Wizard
starts.
Page 1 of 2
dialog, make the following choices: Number of
controls
: 1Runtime license:
NoSource file comments:
YesHelp files:
Nodynamic linked
library (DLL)
.We made SQHMTree an automation client of HoTMetaL PRO so that it can efficiently manipulate HoTMetaL PRO objects (such as Document, DOMNode, etc.). SQHMTree needs to have the information about the server (HoTMetaL PRO) objects' properties and methods. We made this information available to SQHMTree by creating dispatch classes from HoTMetaL PRO's type library and adding them to SQHMTree project:
Class
Wizard...
from the View menu.
Class Info
tab. Confirm Classes
dialog, select all the classes (you can use
Shift-Click to do this).
MFC Class Wizard
dialog.
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 PRO to move the insertion point of the current document to the beginning of the node represented by the tree item that was clicked on.
Class View
tab and choose
New Class...
from the pop-up menu.
Base
class
list.Class View
tab, right-click on CMyTreeCtrl
and choose Add Member Variable...
from the pop-up menu.
Variable type
Variable name
CMyTreeCtrl::CMyTreeCtrl() { m_menu.CreatePopupMenu(); m_menu.AppendMenu( MF_STRING, ID_REFRESH_TREE,__T("Refresh") ); }
Class View
tab, right-click on CMyTreeCtrl
and choose Add Windows message Handler... from the pop-up menu.
Add Handler
.
Refresh
(created inside the
constructor of CMyTreeCtrl): the handler is named as
OnRefreshTree() and should be created in in the file
MyTreeCtrl.cpp. The code is written as follows:void CMyTreeCtrl::OnRefreshTree() { DeleteAllItems(); CWaitCursor dummy; LoadXMLDocElements(); }
Class View
tab, right-click on CMyTreeCtrl and
choose Add Member Function... from the pop-up menu. Function Declaration
.
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; }
CSQHMTreeCtrl is the ActiveX control generated by the wizard. We need to do some modifications:
Class View
tab, right-click on CMyTreeCtrl and
choose Add Member Variable...
from the pop-up menu. Variable type
Variable name
Class View
tab, open
SQHMTree classes
Class View
tab, expand SQHMTree classes folder, expand
CSATreeCtrl, then double-click on OnCreate( LPCREATESTRUCT
lpCreatStruct). This will put the insertion point in the editor window at the beginning
of the function body of OnCreate( ).
int CSQHMTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here CRect rect; GetClientRect( rect ); m_tree.Create(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS,rect,this,1); CImageList *imgList; CBitmap bmp, bmpMsk; imgList = new CImageList; int nRet = imgList->Create( 16, 16, ILC_COLOR4, 4, 4 ); bmp.LoadBitmap( IDB_ITEM_ROOT ); bmpMsk.LoadBitmap( IDB_ITEM_DOCUMENT ); nRet = imgList->Add( &bmp, (COLORREF)0x000000 ); imgList->Add( &bmpMsk, (COLORREF)0x000000 ); bmp.DeleteObject( ); bmpMsk.DeleteObject( ); bmp.LoadBitmap( IDB_ITEM_COMMENT ); bmpMsk.LoadBitmap( IDB_ITEM_TEXT ); nRet = imgList->Add( &bmp, (COLORREF)0x000000 ); imgList->Add( &bmpMsk, (COLORREF)0x000000 ); bmp.DeleteObject( ); bmpMsk.DeleteObject( ); bmp.LoadBitmap( IDB_ITEM_ATTRIBUTE ); imgList->Add( &bmp, (COLORREF)0x000000 ); bmp.DeleteObject( ); bmp.LoadBitmap( IDB_ITEM_ELEMENT ); imgList->Add( &bmp, (COLORREF)0x000000 ); bmp.DeleteObject( ); m_tree.SetImageList( imgList, TVSIL_NORMAL ); m_tree.LoadXMLDocElements( ); m_tree.ShowWindow( SW_SHOW ); m_view->ShowWindow( SW_SHOW ); return 0;}
void CSQHMTreeCtrl::OnSize(UINT nType, int cx, int cy) { COleControl::OnSize(nType, cx, cy); m_tree.MoveWindow( 0, 0, cx, cy ); }
After successfully compiling the project, we now embed this control in HoTMetaL PRO, and use it as a tool to navigate the structure of the active HoTMetaL PRO document:
<HTML> <HEAD> <TITLE>Structure View</TITLE> <LINK REL="STYLESHEET" HREF="fxindex.css"> </HEAD> <BODY> <OBJECT CLASSID="clsid:B3ECC6F2-F678-11D2-BAE6-006097043CC8" ID="TreeView" WIDTH="100%" HEIGHT="100%" BORDER="3D" ALIGN="left" HSPACE="0%" VSPACE="0%"> </OBJECT> </BODY> </HTML>
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.
Copyright © SoftQuad Software Inc. 1999