Si j'ai un Je peux voir comment énumérer ses enfants, et je peux voir comment l'utiliser pour comparer deux enfants. Mais comment puis-je obtenir son propre PIDL? P>
Je demande parce que j'aimerais savoir: p>
est-ce ishellfolder == un autre iShellfolder p>
blockQuote>
Je peux utiliser ishellfolder code> Pointeur d'interface. Comment puis-je obtenir son PIDL? p>
ishellfolder :: comp réserve () code>, mais je dois avoir les identifiants des deux dossiers. P>
5 Réponses :
J'ai constaté que vous pouvez interroger un Ishellfolder pour son iPersistColder2, qui a GetCurfolder (), qui renvoie son PIDL absolu. Je pourrais alors simplement utiliser l'IShellfolder pour le bureau pour les comparerids () pour déterminer s'ils sont égaux. J'ai trouvé les contours de ceci en regardant shgetidlistfromObject . Je ne pouvais pas simplement utiliser cette fonction, parce que sa Vista, et j'ai besoin de la compatibilité XP.
Voici un croquis de la façon dont il fonctionne (en supposant que vous avez un ifolder_desktop, et ifolder_other, qui sont des pointeurs IShellfolder. PIDL est un simple assistant qui Assure que les idologistes sont traitées correctement): p> au cas où n'importe qui est intéressé par ma classe PIDL simple: P> class Pidl
{
public:
// create empty
Pidl() : m_pidl(NULL) { }
// create one of specified size
explicit Pidl(size_t size) : m_pidl(Pidl_Create(size)) {}
// create a copy of a given PIDL
explicit Pidl(const ITEMIDLIST * pidl) : m_pidl(Pidl_Copy(pidl)) {}
// create an absolute PIDL from a parent + child
Pidl(const ITEMIDLIST_ABSOLUTE * pParent, const ITEMIDLIST_RELATIVE * pChild) : m_pidl(Pidl_Concatenate(pParent, pChild)) { }
// return our PIDL for general use (but retain ownership of it)
operator const ITEMIDLIST * () { return m_pidl; }
// return a pointer to our pointer, for use in functions that assign to a PIDL
operator ITEMIDLIST ** ()
{
free();
return &m_pidl;
}
// release ownership of our PIDL
ITEMIDLIST * release()
{
ITEMIDLIST * pidl = m_pidl;
m_pidl = NULL;
return pidl;
}
void free()
{
if (m_pidl)
//Pidl_Free(m_pidl);
ILFree(m_pidl);
}
// automatically free our pidl (if we have one)
~Pidl()
{
free();
}
private:
ITEMIDLIST * m_pidl;
};
La réponse de Mordachai pourrait être correcte, mais pour moi, cette requête n'a aucun sens sur deux fronts: P>
Je ne crois pas qu'il existe un document publié indiquant qu'un IShellfolder ne peut avoir qu'un seul parent. Il pourrait y avoir plusieurs façons de tout dossier shell. Le panneau de commande est accessible via mon ordinateur, via le menu Démarrer et n'importe où dans le système de fichiers que vous créez un
Junction le point. Il semble que l'intention orgénale des équipes de shell était, étant donné une instance Ishellfolder, il ne devrait pas importer d'utilisateurs externes ce que em> son emplacement arbitraire est arrivé. P> li>
plus, toute application qui instancie un ishellfolder sûrement em> a fait de sorte d'avoir une connaissance d'une PIDL. Si votre application se souciait de la voie à un iShellfolder, cela avait déjà cette information. Comment l'avez-vous perdu? (Et pourquoi l'équipe Shell devrait-elle ajouter une méthode pour aider les applications à garder une trace de leurs propres données?) P> li>
ol>
1. Vrai, mais le système de fichiers est la vérité sous-jacente pour la plupart des objets de l'espace Shell. Et bien qu'il soit possible d'avoir plusieurs liens, jonctions, etc. à un dossier donné, il ne peut y avoir qu'un seul dossier parent. C'est vrai par définition du système de fichiers. Cela a toujours été ainsi, et il y a SHBindtoparent de corroborer cette vérité. 2. Pas ça. On peut instancer un Ishellfolder directement de Shgetdesktopfolder. En tout cas, il s'agit souvent de systèmes conçus qui ne peuvent aller que d'une manière qui échoue finalement. La capacité de convertir de l'un à l'autre est plus flexible et robuste.
1. Donc, si certains systèmes de fichiers ont des limites.L'apace de noms de shell a été conçu pour exprimer l'affaire plus générale. 2. Merci d'avoir souligné le cas spécial. Très intelligent.
Qu'est-ce que Chris ou Mordechai écrit sur le n ° 1 est de toute façon pas au point. La question ne concerne pas les objets de l'espace de noms shell, mais sur des objets ayant une interface code> ishellfolder code>. Possession d'un Le meilleur que vous puissiez faire, je pense, est que Mordechai suggère: p>
Le but de cette interface est de corriger l'objet dans l'espace de noms de shell, ce qui fait tourner le dossier persistable. Plutôt que d'en déduire de toute absence de documentation publiée, examinez ce que Microsoft dit en réalité le Vous devez implémenter cette interface pour que l'élément d'objet de l'objet de dossier Shell puisse être récupéré. P>
blockQuote>
sur # 2, j'ai peur que Chris n'est certainement pas correct. Un Il y a une poignée d'autres dossiers coquillés créateurs implémentés dans Shell32 et toute DLL peut configurer un nombre de personnes. p> IShellfolder CODE> L'interface ne signifie pas elle-même une présence dans l'espace de noms de shell. La question initiale est mal formée, dans la mesure où elle suppose qu'un objet avec une interface code> iShellfolder code> doit avoir "sa propre PIDL" em>. p>
IPERSISTFolder2 code> interface li>
ul>
iPersistFolder code> et
IPERSISTFolder2 CODE> interfaces et la
ishellfolder code> peut certainement être obtenu sans PIDL. Le panneau de commande, que Chris introduit pour le n ° 1, fournit un contre-exemple prêt au n ° 2. Il suffit de nourrir
clsid_controlpanel code> et
iid_ishellfolder code> à coCreateInstance strong>. Vous obtenez une instanciation parfaitement utilisable du panneau de commande sans jamais "avoir la connaissance d'un PIDL" em>. p>
J'ai oublié de mentionner la fonction Il n'est disponible que dans Windows Vista et supérieur. Il a l'avantage d'être documenté, même si Vous obtenez plus de détails, bien sûr, de Ma propre documentation < / a>. Cela montre que Microsoft connaît deux autres moyens d'obtenir une PIDL pour un pointeur d'interface arbitraire à un objet de l'espace de noms de shell. p> shgetidlistfromObject code>. p>
Merci pour le lien et les détails. Je ne me souviens pas si je suis tombé sur cette fonction, mais je suis limité à la maintenance de la compatibilité XP (bien que cela sonne comme si je pouvais utiliser un lien dynamique vers shell32.dll).
Comme indiqué avant qu'il puisse y avoir beaucoup de problèmes avec des dossiers spéciaux tels que Panneau de contrôle (je ne comprends toujours pas complètement) mais voici une solution simple pour les dossiers "normaux":
HRESULT get_pidl(IShellFolder * sf, LPITEMIDLIST * pidl) { if (!sf || !pidl) return E_FAIL; wchar_t FolderName[MAX_PATH] = {0}; STRRET strDispName; sf->GetDisplayNameOf(NULL, SHGDN_FORPARSING, &strDispName); StrRetToBuf(&strDispName, NULL, FolderName, (UINT)MAX_PATH); IShellFolder * desktop = nullptr; SHGetDesktopFolder(&desktop); ULONG cbEaten, atrib = 0; HRESULT hr = desktop->ParseDisplayName(NULL, nullptr, FolderName, &cbEaten, pidl, &atrib); desktop->Release(); return hr; }