MobileFinding Special Folder Paths on the HPC and HPC Pro

Finding Special Folder Paths on the HPC and HPC Pro

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Finding Special Folder Paths on the HPC and HPC Pro

Getting the paths for the special folders involves a couple of extra steps on the HPC and HPC Pro. These devices fully implement the “pidl”. On the desktop, and on larger CE platforms, pidl is a pointer to a buffer that is allocated by the shell. In order to free this buffer, you need to get and use the shell’s IMalloc COM interface. This buffer must be released when you are done using it, and in order to do so you must obtain a pointer to the shell’s IMalloc COM interface. This isn’t necessary on the palmtop CE devices, because the value returned in pidl is a defined constant that you can pass to SHGetPathFromIDList() to retrieve a pathname.

Modifying the FindDIrs example from our last installment just a bit, we can accommodate the larger CE devices, using the COM interface to locate special folders. Here’s how the WM_INITDIALOG case looks using the IMalloc interface pointer:

LPMALLOC  lpMallocInterface;

case WM_INITDIALOG:
  hWndList = GetDlgItem(hWnd,IDC_SPECIAL_DIRS );
  _stprintf( szBuff, TEXT("%s"),TEXT("Special Folders"));
  ListBox_InsertString(hWndList, -1, &szBuff);

  //Init the IMalloc interface pointer
  lpMallocInterface = NULL;

  //Get the Shell's IMalloc Interface
  rc = SHGetMalloc( & lpMallocInterface );
  if( rc != NOERROR )
  { return TRUE; }

    for ( i = 0; i < dim ( iaSpecialDirs ); i ++ )
    {
      rc = SHGetSpecialFolderLocation(hWnd,
                   iaSpecialDirs[i].csidl, &pidl );

      if( rc == NOERROR )
      {
         _stprintf( szBuff, TEXT("   %s "),
                    iaSpecialDirs[i].pszCSIDL);
         ListBox_InsertString(hWndList, -1, &szBuff);

         SHGetPathFromIDList( pidl, &szBuff[0] );
         ListBox_InsertString(hWndList, -1, &szBuff);

         //Use the interface pointer to free the buffer
         //allocation
         lpMallocInterface->Free( pidl );

      }// end if()

    }//end for()

//Now remove our reference to the shell's IMalloc Interface
lpMallocInterface->Release();
   break;

Let’s have a recap of differences between the two implementations. First, we initialize the variable that holds the pointer to the shell’s IMalloc interface:

//Init the IMalloc interface pointer
lpMallocInterface = NULL;

Next, we call SHGetMalloc(), passing the address of this pointer, as the only parameter. We check the return to make sure we got the interface pointer, and if not we exit the function:

//Get the Shell's IMalloc Interface
rc = SHGetMalloc( & lpMallocInterface );
if( rc != NOERROR )
  { return TRUE; }

Now, when we call SHGetSpecialFolderLocation(), the address of a buffer allocated by the shell is returned in the variable pidl:

rc = SHGetSpecialFolderLocation(hWnd,
                 iaSpecialDirs[i].csidl, &pidl );

We use this returned address to look up the actual pathname when we call SHGetPathFromIDList():

SHGetPathFromIDList( pidl, &szBuff[0] );

We free the shell’s buffer at the bottom of the loop body:

//Use the interface pointer to free the buffer allocation
lpMallocInterface->Free( pidl );

After we’ve looped the entire array of special folder constants, we release the IMalloc interface:

//Now remove our reference to the shell's IMalloc Interface
lpMallocInterface->Release();

Here’s one last caveat. Note the declaration of szBuff, which came from a portion of the FindDirs example code not shown in this installment. (You can find the full source on the developer.com site):

TCHAR szBuff[MAX_PATH];

Don’t be tempted to save stack space by reducing the size of this buffer. In some cases, the SHGetPathFromIDList() function fills the buffer with null padding, using the entire MAX_PATH space, even though the actual contents are only a few characters in length.

Looking Ahead:

In the next installment, we’ll begin exploring the CE shell’s user interface elements.

About the Author

Nancy Nicolaisen is a software engineer who has designed and implemented highly modular Windows CE products that include features such as full remote diagnostics, CE-side data compression, dynamically constructed user interface, automatic screen size detection, entry time data validation.

In addition to writing for Developer.com, she has written several books including Making Win 32 Applications Mobile.

# # #

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories