Further Extensions
NOTE >> We’ve only exported one method. We have not exported any of the Objective Toolkit Tree control’s bitmap functionality. This and other extensions are left to the developer.
You can get a good idea of how to go about extending this by examining the code for the method implementation we’ve provided, InsertItem():
STDMETHODIMP Cmytreecontrol::InsertItem(VARIANTARG nIndexParent,
//!AFX_MANAGE_STATE is necessary whenever functions callable from
//other modules are provided!
TV_ITEM tvi;
tvi.mask = TVIF_TEXT;
_bstr_t bstrBuffer(text);
tvi.pszText = bstrBuffer;
memmove(&(tvis.item), &tvi, sizeof(TV_ITEM));
//!If the value of the parent node passed in was zero, insert at
//the root level. Otherwise, insert the new node as the child of
//the specified parent.
if (nIndexParent.lVal != 0)
tvis.hParent = (HTREEITEM)(nIndexParent.lVal);
tvis.hParent = TVI_ROOT;
tvis.hInsertAfter = TVI_LAST;
HTREEITEM htiAX = m_wndClassImpl.InsertItem( &tvis );
//!Return an identifier (in this case, actually, a pointer) of
//the just-created node as a variant in the [out,retval] parameter
//to the caller. This implementation is provided as an example
//only. Production code might implement some type of 'key' scheme
//for the nodes and should also include error checking. This code
//can also be modified and extended to enable use of the bitmap/
//imagelist functionality of which the SECTreeCtrl is capable.
pNode->lVal = (DWORD)(htiAX);
pNode->vt = VT_I4;
return S_OK;
As explained in the comments in this routine, a production version would need a great deal more error checking. Nonetheless, it does illustrate two important points.
*Note the call to AFX_MANAGE_STATE(). As is explained below, this is necessary in any routine that is callable externally.
*Note the invocation of the Objective Toolkit Tree control method InsertItem()—called on the member variable m_wndClassImpl. This is the actual instance of the class SECTreeCtrl provided by wrapper classes in header file sectxmacs.h. See this file for implementation details. In general, this member variable may be used to access any SECTreeCtrl class provided functionality.
This method can be modified (for example, to access the bitmap/imagelist functionality as described) and other methods may be defined on the Imytreecontrol interface to make functionality in the base Tree control accessible through the ActiveX control you are developing.
The Objective Toolkit libraries require initialization before they can be used. During this process, resources are allocated and made available to the module that uses them. It is important that any such resources be available only to the module and not to the application. If such resources were to live in the application, several conflicts could arise.
Consider a case where two ATL-based DLLs link in Objective Toolkit. Assume that the first performs control registration. The second is then loaded. Both work fine. Then let us assume that the first control gets terminated, while the rest of the application continues to run. Like any good control, the first control cleans up after itself, un-registering the class. When the second control tries to create a control of this class, it fails.
Objective Toolkit is completely aware of these issues and can be used freely inside different ATL modules. Remember to call AFX_MANAGE_STATE(AfxGetStaticModuleState()) when you export functions that will be called from other modules. Non-module state-aware MFC controls will fail under these situations.
In this chapter, we have provided guidelines and working code, as well as code generation helpers, for better ATL compatibility with Objective Toolkit. Please contact us if you encounter problems with this support or if there are other features that you would like to see implemented.