Changing name of Start-Programs-oldFolder

Changing name of Start-Programs-oldFolder

Post by chris.. » Thu, 27 Jul 2000 04:00:00



I need to programatically change the name of a folder that appears on
users' Start-Programs menu.  For example, it's called oldFolder, and I
want to change it to newFolder.

Our users run Win95, Win98, and WinNT.

I'm using VC++ 6.0.  I figured that I could use IShellFolder to
navigate thru the CSIDL_PROGRAMS folder, find oldFolder, and then
rename it to newFolder.  Apparently this is easier said than done.
Folder names don't seem to be returned the way I expected them to.

Here's a code snippet:

// rename.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    LPMALLOC pMalloc = NULL;
    IShellFolder *psfDesktop = NULL;
    IShellFolder *psfStartMenu = NULL;
    LPENUMIDLIST ppenum = NULL;
    LPITEMIDLIST pidlStartMenu = NULL;
    HRESULT hr;
    LPITEMIDLIST pidlItems = NULL;
    ULONG celtFetched;
    STRRET strDispName;
    TCHAR pszDisplayName[MAX_PATH];

    hr = SHGetMalloc(&pMalloc);

    //Step 1: Find the CSIDL_PROGRAMS item
    hr = SHGetDesktopFolder(&psfDesktop);
    hr = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS,
                                    &pidlStartMenu);
    hr = psfDesktop->BindToObject(pidlStartMenu, NULL,
                     IID_IShellFolder, (LPVOID *) &psfStartMenu);
    psfDesktop->Release();

    //Step 2: Create an enumidlist
    hr = psfStartMenu->EnumObjects(NULL, SHCONTF_FOLDERS, &ppenum);

    //Step 3: Cycle thru the items, fetching the display name of each
    while (hr = ppenum->Next(1, &pidlItems, &celtFetched) == S_OK
                && (celtFetched) == 1) {
        hr = psfStartMenu->GetDisplayNameOf(pidlItems, SHGDN_NORMAL,
                                            &strDispName);
        //hr = StrRetToBuf(&strDispName, pidlItems, pszDisplayName,
                           MAX_PATH);
        //cout << pszDisplayName << '\n';

        pMalloc->Free(pidlItems);
    }

    ppenum->Release();
    pMalloc->Free(pidlStartMenu);
    psfStartMenu->Release();
    pMalloc->Release();

    return 0;

Quote:}

I can't use StrRetToBuf because it requires IE5 or greater which my
customers may not have.  In fact the version of SHLWAPI.H that came
with VisualStudio doesn't even have it defined.  Anyway, in debug mode
when I look at strDispName after the call to GetDisplayName,
strDispName.uType = 1, strDispName.uOffset = 14, and strDispName.cStr
= "\14\0".

Any idea what I'm doing wrong?  I used the code at
http://msdn.microsoft.com/library/psdk/shellcc/Shell/Shell_basics/Naviga
te.htm as the basis for this code.

Or perhaps there's an easier way to do this?

Sent via Deja.com http://www.deja.com/
Before you buy.

 
 
 

Changing name of Start-Programs-oldFolder

Post by Strohm Armstron » Thu, 27 Jul 2000 04:00:00


These are nothing but directories, so just treat them like directories.

1. Call SHGetSpecialFolderLocation with CSIDL_PROGRAMS.
2. Call SHGetPathFromIDList to get the path of the Programs folder.
3. Call MoveFile to "change" the folder's name to the new name.


> I need to programatically change the name of a folder that appears on
> users' Start-Programs menu.  For example, it's called oldFolder, and I
> want to change it to newFolder.

> Our users run Win95, Win98, and WinNT.

> I'm using VC++ 6.0.  I figured that I could use IShellFolder to
> navigate thru the CSIDL_PROGRAMS folder, find oldFolder, and then
> rename it to newFolder.  Apparently this is easier said than done.
> Folder names don't seem to be returned the way I expected them to.

> Here's a code snippet:

> // rename.cpp : Defines the entry point for the application.
> //

> #include "stdafx.h"
> #include <shlobj.h>
> #include <shlwapi.h>
> #include <iostream.h>

> int APIENTRY WinMain(HINSTANCE hInstance,
>                      HINSTANCE hPrevInstance,
>                      LPSTR     lpCmdLine,
>                      int       nCmdShow)
> {
>     LPMALLOC pMalloc = NULL;
>     IShellFolder *psfDesktop = NULL;
>     IShellFolder *psfStartMenu = NULL;
>     LPENUMIDLIST ppenum = NULL;
>     LPITEMIDLIST pidlStartMenu = NULL;
>     HRESULT hr;
>     LPITEMIDLIST pidlItems = NULL;
>     ULONG celtFetched;
>     STRRET strDispName;
>     TCHAR pszDisplayName[MAX_PATH];

>     hr = SHGetMalloc(&pMalloc);

>     //Step 1: Find the CSIDL_PROGRAMS item
>     hr = SHGetDesktopFolder(&psfDesktop);
>     hr = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS,
>                                     &pidlStartMenu);
>     hr = psfDesktop->BindToObject(pidlStartMenu, NULL,
>                      IID_IShellFolder, (LPVOID *) &psfStartMenu);
>     psfDesktop->Release();

>     //Step 2: Create an enumidlist
>     hr = psfStartMenu->EnumObjects(NULL, SHCONTF_FOLDERS, &ppenum);

>     //Step 3: Cycle thru the items, fetching the display name of each
>     while (hr = ppenum->Next(1, &pidlItems, &celtFetched) == S_OK
>                 && (celtFetched) == 1) {
> hr = psfStartMenu->GetDisplayNameOf(pidlItems, SHGDN_NORMAL,
>                                             &strDispName);
> //hr = StrRetToBuf(&strDispName, pidlItems, pszDisplayName,
>                            MAX_PATH);
> //cout << pszDisplayName << '\n';

> pMalloc->Free(pidlItems);
>     }

>     ppenum->Release();
>     pMalloc->Free(pidlStartMenu);
>     psfStartMenu->Release();
>     pMalloc->Release();

>     return 0;
> }

> I can't use StrRetToBuf because it requires IE5 or greater which my
> customers may not have.  In fact the version of SHLWAPI.H that came
> with VisualStudio doesn't even have it defined.  Anyway, in debug mode
> when I look at strDispName after the call to GetDisplayName,
> strDispName.uType = 1, strDispName.uOffset = 14, and strDispName.cStr
> = "\14\0".

> Any idea what I'm doing wrong?  I used the code at
> http://msdn.microsoft.com/library/psdk/shellcc/Shell/Shell_basics/Naviga
> te.htm as the basis for this code.

> Or perhaps there's an easier way to do this?

> Sent via Deja.com http://www.deja.com/
> Before you buy.


 
 
 

Changing name of Start-Programs-oldFolder

Post by chris.. » Thu, 27 Jul 2000 04:00:00


Thanks Strohm, but using that method doesn't work either (at least not
on my box which is running NT4.0).

The paths returned by SHGetPathFromIDList are not valid (and so
MoveFile fails).  It keeps returning paths in the format:

C:\WINNT\Profiles\codd\Desktop\oldFolder

But there is no such folder... that folder really exists in:

C:\WINNT\Profiles\codd\StartMenu\Programs\oldFolder

????????



> These are nothing but directories, so just treat them like
directories.

> 1. Call SHGetSpecialFolderLocation with CSIDL_PROGRAMS.
> 2. Call SHGetPathFromIDList to get the path of the Programs folder.
> 3. Call MoveFile to "change" the folder's name to the new name.




Quote:> > I need to programatically change the name of a folder that appears
on
> > users' Start-Programs menu.  For example, it's called oldFolder,
and I
> > want to change it to newFolder.

> > Our users run Win95, Win98, and WinNT.

> > I'm using VC++ 6.0.  I figured that I could use IShellFolder to
> > navigate thru the CSIDL_PROGRAMS folder, find oldFolder, and then
> > rename it to newFolder.  Apparently this is easier said than done.
> > Folder names don't seem to be returned the way I expected them to.

> > Here's a code snippet:

> > // rename.cpp : Defines the entry point for the application.
> > //

> > #include "stdafx.h"
> > #include <shlobj.h>
> > #include <shlwapi.h>
> > #include <iostream.h>

> > int APIENTRY WinMain(HINSTANCE hInstance,
> >                      HINSTANCE hPrevInstance,
> >                      LPSTR     lpCmdLine,
> >                      int       nCmdShow)
> > {
> >     LPMALLOC pMalloc = NULL;
> >     IShellFolder *psfDesktop = NULL;
> >     IShellFolder *psfStartMenu = NULL;
> >     LPENUMIDLIST ppenum = NULL;
> >     LPITEMIDLIST pidlStartMenu = NULL;
> >     HRESULT hr;
> >     LPITEMIDLIST pidlItems = NULL;
> >     ULONG celtFetched;
> >     STRRET strDispName;
> >     TCHAR pszDisplayName[MAX_PATH];

> >     hr = SHGetMalloc(&pMalloc);

> >     //Step 1: Find the CSIDL_PROGRAMS item
> >     hr = SHGetDesktopFolder(&psfDesktop);
> >     hr = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS,
> >                                     &pidlStartMenu);
> >     hr = psfDesktop->BindToObject(pidlStartMenu, NULL,
> >                      IID_IShellFolder, (LPVOID *) &psfStartMenu);
> >     psfDesktop->Release();

> >     //Step 2: Create an enumidlist
> >     hr = psfStartMenu->EnumObjects(NULL, SHCONTF_FOLDERS, &ppenum);

> >     //Step 3: Cycle thru the items, fetching the display name of
each
> >     while (hr = ppenum->Next(1, &pidlItems, &celtFetched) == S_OK
> >                 && (celtFetched) == 1) {
> > hr = psfStartMenu->GetDisplayNameOf(pidlItems, SHGDN_NORMAL,
> >                                             &strDispName);
> > //hr = StrRetToBuf(&strDispName, pidlItems, pszDisplayName,
> >                            MAX_PATH);
> > //cout << pszDisplayName << '\n';

> > pMalloc->Free(pidlItems);
> >     }

> >     ppenum->Release();
> >     pMalloc->Free(pidlStartMenu);
> >     psfStartMenu->Release();
> >     pMalloc->Release();

> >     return 0;
> > }

> > I can't use StrRetToBuf because it requires IE5 or greater which my
> > customers may not have.  In fact the version of SHLWAPI.H that came
> > with VisualStudio doesn't even have it defined.  Anyway, in debug
mode
> > when I look at strDispName after the call to GetDisplayName,
> > strDispName.uType = 1, strDispName.uOffset = 14, and
strDispName.cStr
> > = "\14\0".

> > Any idea what I'm doing wrong?  I used the code at

http://msdn.microsoft.com/library/psdk/shellcc/Shell/Shell_basics/Naviga

Quote:> > te.htm as the basis for this code.

> > Or perhaps there's an easier way to do this?

> > Sent via Deja.com http://www.deja.com/
> > Before you buy.

Sent via Deja.com http://www.deja.com/
Before you buy.
 
 
 

Changing name of Start-Programs-oldFolder

Post by Strohm Armstron » Fri, 28 Jul 2000 04:00:00


That's odd. The following works fine for me and many others on all
platforms> Judging from your other post in this newsgroup that was answered
by Jim Barry, I would say you are not creating the PIDL correctly.

LPMALLOC pMalloc;

// Get the Shell's default allocator
if(SHGetMalloc(&pMalloc) == NOERROR)
   {
   LPITEMIDLIST pidl = NULL;
   SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidl);

   if(pidl)
      {
      TCHAR szPath[MAX_PATH];

      SHGetPathFromIDList(pidl, szPath);

      MessageBox(NULL, szPath, TEXT("Path of the Desktop Folder"), MB_OK);

      pMalloc->Free(pidl);
      }

   pMalloc->Release();
   }

 
 
 

Changing name of Start-Programs-oldFolder

Post by chris.. » Fri, 28 Jul 2000 04:00:00


Thanks Strohm.... Jim was right, the PIDL that I was using was returned
from IFolder::EnumObjects, and was a relative PIDL. SHGetPathFromIDList
requires a fully qualified PIDL.  I appended this relative PIDL to the
PIDL returned by SHGetSpecialFolderLocation (which is a fully qualified
PIDL), and voila, if I call SHGetPathFromIDList on the "built" PIDL
everything works fine...

I just didn't understand how PIDL's worked.... now that I've PIDL'd
around with them so much I think I get it!   :)

thx again for your help.



Quote:

> That's odd. The following works fine for me and many others on all
> platforms> Judging from your other post in this newsgroup that was
answered
> by Jim Barry, I would say you are not creating the PIDL correctly.

> LPMALLOC pMalloc;

> // Get the Shell's default allocator
> if(SHGetMalloc(&pMalloc) == NOERROR)
>    {
>    LPITEMIDLIST pidl = NULL;
>    SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidl);

>    if(pidl)
>       {
>       TCHAR szPath[MAX_PATH];

>       SHGetPathFromIDList(pidl, szPath);

>       MessageBox(NULL, szPath, TEXT("Path of the Desktop Folder"),
MB_OK);

>       pMalloc->Free(pidl);
>       }

>    pMalloc->Release();
>    }

Sent via Deja.com http://www.deja.com/
Before you buy.