|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis code demonstrates the use of Windows shell interfaces. Shell Interfaces and Functions UsedThe interfaces are:
The shell functions are:
The idea behind itI've never worked with the Windows shell API before and this is my first try at it. I wanted to implement a common way of retrieving shell namespaces, using provided and documented shell interfaces. This sample is a substitute for The source code is separated into a shell extension DLL BFF{D}.DLL and a sample app App{D}.exe. The DLL contains everything that you need. The sample app shows how to use the DLL's functionality. How to useWhen you need to call the "browse for folder" dialog put in the source code that will look like this: CBrowseForFolderDlg::BFFINFO info; memset(&info, 0, sizeof(info)); info.m_pParent = this; strcpy(info.m_szTitle, "Browse For Folder"); strcpy(info.m_szMsg, "Select the Voice Mail Folder"); info.m_pidlRoot = m_pidlMainPath; /* Line 1 */ info.m_pidlSelected = m_pidlSelected; info.m_nFlags |= BFF_IDL_ROOT | BFF_IDL_SELECTED; /* Line 2 */ info.m_nFlags |= (m_bIncFiles) ? BFF_INCLUDE_FILES : info.m_nFlags; info.m_nFlags |= (m_bSysOnly) ? BFF_SYSTEM_ONLY : info.m_nFlags; CBrowseForFolderDlg dlg(&info); if (dlg.DoModal() == IDCANCEL) return; // release memory for the previous default SHFree(m_pidlSelected); // allocate and copy newly selected m_pidlSelected = dlg.GetTreeSelectedFullIdl(); The above code assumes that you have preallocated and assigned the strcpy(info.m_szRoot, "c:\\windows\\system"); info.m_nFlags |= BFF_CHAR_ROOT; Note, that you can specify network paths as well. strcpy(info.m_szRoot, "\\\\ABERRESFORD\\views"); info.m_nFlags |= BFF_CHAR_ROOT; Or CSIDL values. info.m_pidlRoot = CSIDL_DESKTOP; info.m_nFlags |= BFF_CSIDL_ROOT; Exactly the same rules apply to the I've added a button on the dialog, "Set as Root", and made it invisible for the debugging purposes. You can make it visible and set the roots dynamically in the demo application. You also have to add the BFF{D}.LIB library to your link list. The letter "D" signifies that you're linking with debug version of DLL. That's all. You should be able to run your app and use Data and Visual separationI've applied the "Visitor" design patter to this example. I've introduced an abstract
The Data retrievalI only extract immediate children for a selected node if any. You can specify the depth of the search by usingITreeNode::SetFindDepth() method. the depth of <1> means just get
immediate children.
Displaying TreeIn order to achieve high display speed of the tree I used a widely known display technique. The core idea behind it, is that you only provide information that is visible at a given moment in time.CTreeCtrl will be sending a message for each visible node when it needs text and an icon for it -
CTreeCtrl::OnGetdispinfo. The TVITEM::lParam member points at an instance of ITreeNode.
Only then I provide the tree control with the text and the icon id in the
image list.
According to the data retrieval approach I described above, whenever a user expands a node
I will request this ITreeNode to go and fetch its immediate children. Then I will request
CUITreeVisitor to go and visit (display) found nodes in the tree control. This is done
through a method CTreeCtrl calls every time a node with children gets expanded
CTreeCtrl::OnItemexpanding(). Therefore, whether a user expands just
one level or the "*" button on the numpad was clicked the same algorithm does the job.
SortingThe shell objects are displayed in a sorted descending order. The system folders take precedence over the files. This is done using standard Microsoft's approach. There is a callback function that you need to set up, which will be called when Microsoft algorithm needs to compare two items from the list being sorted. This is the staticCFileTreeCtrl::CompFunc() method in our case.
UpdatesI have updated the source code and the picture. Enjoy! If you find bugs or have any suggestions for improvements, let me know.Updates again... (01/30/2001)I've fixed a couple of bugs. One of them was pretty nasty. The list control didn't work on WinNT because of that. All fixed now. Now you can specify any node in the shell namespace as a base root for your shell browser. TheCBrowseForFolderDlg::BFFINFO structure has been extended to support an arbitrary root.
You can specify the base root in the form of an ITEMIDLIST, CSIDL or
char*. The same goes to the default selection. You can type in a network path
and the synchronize button should be working.
|
||||||||||||||||||||||