We help IT Professionals succeed at work.

How to get "My Network Places" folder display name?

yuxiliu
yuxiliu asked
on
Medium Priority
348 Views
Last Modified: 2013-12-03
Following is my code to get the display name of "My Network Places": but something must be wrong, the result I get is "Documents and Settings" but not the "My Network Places"
Do appreciate if you can help!

TCHAR szBuffer[MAX_PATH];
memset(szBuffer, 0, sizeof(szBuffer));

IMallocPtr spMalloc;
SHGetMalloc(&spMalloc);
     
IShellFolderPtr pDesktop=NULL;
SHGetDesktopFolder(&pDesktop);

LPITEMIDLIST pDeskIDL = NULL;
SHGetSpecialFolderLocation(m_hWnd, CSIDL_DESKTOP,&pDeskIDL);
if(pDesktop)
{
     LPITEMIDLIST pidl=NULL;
     LPITEMIDLIST pThisIDL = NULL;
       
        //My Net place
     SHGetSpecialFolderLocation(m_hWnd, CSIDL_NETHOOD, &pidl);
     pThisIDL = ConcatPidls(pDeskIDL, pidl);
     GetName(pDesktop, pThisIDL, SHGDN_NORMAL, Buffer);
     CString strMyNetPlace(szBuffer); //Here I got "Documents and Settings"
     spMalloc->Free(pidl);
     spMalloc->Free(pThisIDL);
Comment
Watch Question

Author

Commented:
continue...
2 functions I was using are following...., Great thanks in advance!

BOOL GetName(LPSHELLFOLDER lpsf,
             LPITEMIDLIST  lpi,
                DWORD         dwFlags,
             LPSTR         lpFriendlyName)
{
   BOOL   bSuccess=TRUE;
   STRRET str;

   if (NOERROR==lpsf->GetDisplayNameOf(lpi,dwFlags, &str))
   {
      switch (str.uType)
      {
         case STRRET_WSTR:

            WideCharToMultiByte(CP_ACP,                 // CodePage
                                0,                         // dwFlags
                                str.pOleStr,            // lpWideCharStr
                                -1,                     // cchWideChar
                                lpFriendlyName,         // lpMultiByteStr
                                        MAX_PATH,
                                //sizeof(lpFriendlyName), // cchMultiByte, wrong. sizeof on a pointer, psk, psk
                                NULL,                   // lpDefaultChar,
                                NULL);                  // lpUsedDefaultChar

             break;

         case STRRET_OFFSET:

             lstrcpy(lpFriendlyName, (LPSTR)lpi+str.uOffset);
             break;

         case STRRET_CSTR:
             
             lstrcpy(lpFriendlyName, (LPSTR)str.cStr);
             break;

         default:
             bSuccess = FALSE;
             break;
      }
   }
   else
      bSuccess = FALSE;

   return bSuccess;
}

ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
    LPITEMIDLIST pidlNew;
    UINT cb1;
    UINT cb2;

    if (pidl1)  //May be NULL
       cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb);
    else
       cb1 = 0;

    cb2 = GetSize(pidl2);

    pidlNew = CreatePidl(cb1 + cb2);
    if (pidlNew)
    {
        if (pidl1)
           memcpy(pidlNew, pidl1, cb1);
        memcpy(((LPSTR)pidlNew) + cb1, pidl2, cb2);
    }
    return pidlNew;
}

Commented:
The desktops PIDL is empty, so you don't need that concat stuff, simply use the pidl you get from CSIDL_NETHOOD.
If that doesn't solve your problem, try calling pDesktop->BindToObject(pidl, ...) and give in "NULL" as the pidl into the GetName function. Does that work now?

Regards, Madshi.

Commented:
If that still doesn't work, you probably need to split off the last item from the pidl, then call BindToObject with the first x-1 items of the pidl and give in the last item into the GetName function. That at least will work.

Author

Commented:
I've tried your 1st and 2nd method but doesn't work.
Could you please show me some code about last method?

Acctually, I've also interested in "My Picture" folder.
MSDN say it can also be get by SHGetSpecialFolderLocation(...CLSID_PICTURES...), and MSDN also say this function will return pidls that related to "Desktop" but all call failed, just return "Documents and Settings".

by the way, Do you think Microsoft make a ugly, stupid, hard to use thing: "Shell", it convert some readable things to un-readable things, then convert them back....
I hate programming by this way, Microsoft should fire the project manager of "Shell" project!

Commented:
Yeah, this kind of namespace programming is really ugly...   :-(   I'm sorry, I can't give you any C/C++ code for that, cause I'm working in Delphi.

Basically you need to understand the PIDL structure. A shell ItemID list (PIDL) consists of x elements. You can think of it like being a path like "firstElement\secondElement\thirdElement\forthElement". But a PIDL element is not string, it's pure binary data. Each element begins with a word (2 bytes) specifying the size of the PIDL data (not including the size word). Directly after the PIDL data of the first PIDL element there comes the size word of the second PIDL element. After the last PIDL element there comes a 0 word, that marks the end of the PIDL. What you probably need to do to make this all work is to split the PIDL into two pieces like: "firstElement\secondElement\thirdElement" and "forthElement". The first piece of the PIDL must be bound to the desktop shell object. The second piece (which must be just the last PIDL element) must be given into GetName.

Regards, Madshi.
Commented:
PAQed, with points refunded (100)

modulo
Community Support Moderator

Explore More ContentExplore courses, solutions, and other research materials related to this topic.