User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

    Using the Shell Namespace To Get Network Computers, Printers and Recycle Bin Items



    Sample Image

    Environment: VC6

    This article explains how to make use of the COM interfaces implemented by Shell Extensions to get the required information on a local machine or network. In this example I have demonstrated it to get the list of all user machines logged onto the network, printers attached to network and items in the recycle bin of local machine. The CShellExt wrapper class can be extended to include the functionality to extract all kind of information. Although there are a lot of wrapper shell functions present to get the same information, but use of COM interfaces gives an insight into what foes on behind the scene in windows explorer and how we can extend the shell's namespace.

    Before we ask for any information from Shell, there are couple of environment variables, which needs to be initialized. First we need to allocate memory in Shell's address space. Asking for IMalloc interface pointer, which we will release before we exit our application, can do this. The Desktop folder is the root of Shell's name space, therefore we will need the interface pointer to that. These steps have been implemented in InitializeEnvironment function of CShellExt class.

    
    HRESULT  hr = SHGetMalloc (&m_pMalloc);
    HRESULT  hr = SHGetDesktopFolder (&m_pDesktopFolder);
    

    Network Neighborhood, Printers, RecycleBin, etc. fall under the category of Special Folders a.k.a Virtual Folders. Windows API provides bunch of functions to work with them. We use SHGetSpecialFolderPath function to obtain the path to required folder. E.g. to obtain path to printers folder

    
    HRESULT  hr = SHGetSpecialFolderLocation (NULL, CSIDL_PRINTERS, &netItemIdLst);
    

    To get more information about second argument to this function call, look in the on-line help. This argument specifies the special folder for which IShellFolder interface is needed. The link between special folders and their paths is stored in the registry as:

    HKEY_CURRENT_USER
     \Software
      \Microsoft
       \Windows
         \CurrentVersion
           \Explorer
            \Shell Folders
    

    After we have IShellFolder interface pointer to special folder, we can ask for contents of folder by creating an item enumeration object (a set of item identifiers) that can be retrieved using the IEnumIDList interface. E.g. for printer folder

    HRESULT hr = pPrinterFolder->EnumObjects (NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnumIds);
    

    After we have ID list enumeration, the display name for each item can be obtained by using GetDisplayNameOf method of IShellFolder interface.

    while ((hr = pEnumIds->Next (1, &pidlItems, &celtFetched)) != S_FALSE && celtFetched == 1) 
    {
       hr = pPrinterFolder->GetDisplayNameOf (pidlItems, SHGDN_INFOLDER, &strDispName);
       if (FAILED (hr))
       {
          goto FreeInterfaces;
       }
       .
       .
    }
    

    After we have obtained the display name of the folder, we need to extract icons. Every shell object which has icon(s) associated with it, implements IExtractIcon interface. This can be obtained by using GetUIObjectOf method of IShellFolder interface. After getting the IExtractIcon interface pointer, use its two methods to get handles to small and large icons. This has been implemented in GetIconsForFolderNode function of CShellExt class.

    IExtractIcon *pExtractIcon = NULL;
    
    hr = pFolderNode->GetUIObjectOf (NULL, 1, const_cast<LPCITEMIDLIST *>(&pidlItems),
    IID_IExtractIcon, NULL, reinterpret_cast<LPVOID *>(&pExtractIcon));
    	
    if (SUCCEEDED (hr)) {
    	TCHAR str[MAX_PATH] = {0};
    	int index;
    	UINT flags;
    
    	// Get the file location where the icons are stored.
    
    	hr = pExtractIcon->GetIconLocation (0, str, MAX_PATH, &index, &flags);
    	if (SUCCEEDED (hr)) {
    		HICON hiconLarge = NULL;
    		HICON hiconSmall = NULL;
    		UINT nIconSize = MAKELONG (32, 16);
    		LPCSTR pszFile = (LPCSTR)str;
    
    		// Extract the icon handles from the location.
    
    		hr = pExtractIcon->Extract (str, index, &hIconLg, &hIconSm, nIconSize);
    		pExtractIcon->Release ();
    	}
    }
    

    To show the use of this extension class, I have created a dialog-based application, which has a tool bar with 3 buttons for NetWork compuetrs, Printers, RecycleBin items. Click on one of them to see the results. The sample application also shows the usage of CTreeCtrl and how to implement CToolBar in dialog based applications.

    Downloads

    Download demo project - 28.3 Kb

    History


    IT Offers


    Top Authors