Frequently we wish to display a list of directories as a control inside a dialog. The standard 'File' dialog is not of much use here since it cannot be used as a control inside another dialog. Also the standard 'File' dialog permits selection of only files and not of directories. To meet this requirement we have developed here an ActiveX directory control. Steps Involved:
We have used the 'MFC ActiveX Control Wizard' to develop the directory control. The steps involved are enumerated below:
Select 'MFC ActiveX Control Wizard' as new project type with project name as 'Dir'. Click on 'OK'.
In Step 1 of 2 select '1' for 'How many controls would you like your project to have?'. Click on 'Next'.
In Step 2 of 2 select 'SysTreeView32' for 'Which window class, if any, should this control subclass?'. Click on 'Finish' to let the wizard generate the code.
Click on the 'Class View' tab and in the PreCreateWindow( ) virtual function you can see the line
cs.lpszClass = _T ( "SysTreeView32" ) ;
This line indicates that SystreeView32 window class has been made as a subclass of the directory control. Hence the messages would be received by the control class before reaching the SystreeView32 window class. To change the style of the tree window we have added:
cs.style |= TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | WS_BORDER ;
Next we have added an OnCreate( ) handler to the CDirCtrl class. From the OnCreate( ) handler adddrives( ) function has been called that adds drives to the CString variable. This function in turn calls adddriveitems( ) to add to the tree control drives and a '+' against each drive. The adddriveitems( ) function uses a pointer to CTreeView object to add items to the tree control. This pointer has been defined as a pubic member variable of CDirCtrl class and has been intialised with the handle on the tree control. When we click on '+' sign or double click on the drive name in the tree control, the control tries to send a notification message to the parent that the item is being expanded. Since there is no parent in this control and we want that the control should get the notification we have added the following entry in the message map of CDirCtrl class.
ON_NOTIFY_REFLECT ( TVN_ITEMEXPANDING, onexpanding )
This results into the onexpanding( ) function getting called whenever a notification arrives. This function first deletes the empty enter which was added to get the '+' sign. Secondly, it calls adddir( ) function to add subdirectories of the selected drive. The sub-directories having more directories inside them would get '+' sign before them. On double clicking such sub-directories the control will receive the reflected notification message. Again the control would be transferred to the onexpanding( ) function which will now list the sub-sub-directories of the selected directory. On double clicking the item or single clicking the '-' of the expanded directory, the control gets the reflected message. This time we delete all the entries under this item by calling the deleteallchild( ) function. As we select item in the tree control the control fires an event to the container with the full path of the selected directory. To accomplish this an event with the name sendpath( ) has been added to the CDirCtrl class. The sendpath( ) event has been fired from the handler onSelChange( ) that gets called on selection of any item. If we run this program the control will register itself with the Windows registry on that machine. A dialog box would be displayed asking for the exe file to be used as a container for this control. We can 'Microsoft's ActiveX Test Container' to display the control. Here we have to insert our control from the 'Insert control' box. The container contains of a splitter window. The upper window displays the control and the lower window displays the events generated by the control.