2009-11-20 8 views
2

Evidemment c'est trivial à faire avec win32 api - CreateDirectory(). Mais j'essaie d'héberger un IShellView, et j'aimerais le faire de la manière la plus shell-orientée. J'aurais pensé qu'il y aurait un createobject ou un createfolder ou un tel dans un IShellFolder. Mais ni IShellView ni IShellFolder, ni même IFolderView ne semblent avoir quelque chose comme ça.Quel est le moyen de "Shell Namespace" pour créer un nouveau dossier?

Existe-t-il un moyen de programmation Shell pour créer un nouveau dossier? Ou ai-je besoin de créer un dossier en utilisant un chemin, à l'ancienne?

Si je dois le faire via CreateDirectory(), alors ma question suivante pourrait être: des idées sur la façon d'obtenir l'IShellView/IFolderView pour voir réellement ce nouvel objet et l'afficher à l'utilisateur? Motivation: Création de mon propre remplacement de boîte de dialogue de fichier et je souhaite fournir la fonctionnalité d'icône de la barre d'outils «nouveau dossier» de la boîte de dialogue de fichier XP standard.

EDIT: Je suis allé de l'avant et créé quelque chose qui fonctionne essentiellement, en utilisant CreateDirectory. Cependant, j'espère encore qu'il ya une meilleure façon de le faire, mais pour que vous puissiez voir comment cela fonctionne, et d'offrir de meilleures idées pour résoudre ce problème mieux:

PidlUtils::Pidl pidl(m_folder); 
    CFilename folderName(GetDisplayNameOf(pidl), "New Folder"); 
    for (int i = 2; folderName.Exists(); ++i) 
     folderName.SetFullName(FString("New Folder (%d)", i)); 
    if (!CPathname::Create(folderName, false)) 
     throw CContextException("Unable to create a new folder here: "); 

    // get the PIDL for the newly created folder 
    PidlUtils::Pidl pidlNew; 
#ifdef UNICODE 
    const wchar_t * wszName = folderName.c_str(); 
#else 
    wchar_t wszName[MAX_PATH]; 
    MultiByteToWideChar(CP_ACP, 0, folderName.GetFullName(), -1, wszName, MAX_PATH); 
#endif 
    m_hresult = m_folder->ParseDisplayName(NULL, NULL, wszName, NULL, pidlNew, NULL); 
    if (FAILED(m_hresult)) 
     throw CLabeledException(FString("Unable to get the PIDL for the new folder: 0x%X", m_hresult)); 

    // upgrade our interface so we can select & rename it 
    CComQIPtr<IShellView2> sv2(m_shell_view); 
    if (!sv2) 
     throw CLabeledException("Unable to obtain the IShellView2 we need to rename the newly created folder."); 

    // force it to see thew new folder 
    sv2->Refresh(); 

    // select the new folder, and begin the rename process 
    m_hresult = sv2->SelectAndPositionItem(pidlNew, SVSI_EDIT|SVSI_DESELECTOTHERS|SVSI_ENSUREVISIBLE|SVSI_POSITIONITEM, NULL); 
    if (FAILED(m_hresult)) 
     throw CLabeledException(FString("Unable to select and position the new folder item: 0x%X", m_hresult)); 

Répondre

0

Les dossiers shell implémentent généralement l'interface IStorage, ce qui est assez simple. Par exemple, ce qui suit crée un dossier nommé « ABCD » sur le bureau:

 CComPtr<IShellFolder> pDesktop; 
    HRESULT hr = SHGetDesktopFolder(&pDesktop); 
    if (FAILED(hr)) return; 
    CComQIPtr<IStorage> pStorage(pDesktop); 
    if (!pStorage) return; 
    CComPtr<IStorage> dummy; 
    hr = pStorage->CreateStorage(L"abcd", STGM_FAILIFTHERE, 0, 0, &dummy); 
+0

Merci! Devoir mélanger COM et Win32 pour accomplir cela semblait bizarre. Bien sûr, cette façon d'utiliser COM Shell peut très bien se terminer par un appel à "CreateDirectory()"! lol;) – Mordachai

4

Oui, vous pouvez get IContextMenu et recherchez des sous-menus, mais pourquoi s'embêter, il suffit d'appeler SHChangeNotify après avoir appelé CreateDirectory

+0

Obtenir une IContextMenu sonne comme il pourrait être très utile pour obtenir la liste des options d'affichage dans une vue shell donné (détails, de petites icônes, etc.). Êtes-vous en train de dire que je pourrais essayer de déterrer la commande pour créer un nouveau dossier à partir d'un menu contextuel et l'invoquer? Ouais, si c'est ce que tu veux dire, ça a l'air d'une mauvaise idée! J'espérais plus comme IFolderView :: CreateObject() ou une autre. – Mordachai

+0

Oui .. Appelez SHChangeNotify car c'est la bonne façon de le faire. Piquer dans IContextMenu est un bon moyen de s'assurer que votre programme se brise sur la prochaine version de Windows. –

1

La fonction API Win32 CreateDirectory semble être la "méthode correcte". Au moins, je ne trouve rien de mieux - et les réponses ici ne font pas vraiment la lumière sur une meilleure façon de le faire.