2010-06-09 6 views
17

Dans mon application, je peux programme ouvrez l'explorateur et sélectionnez un fichier en utilisant le code suivant:sélection de fichier Programmatically dans l'explorateur

void BrowseToFile(LPCTSTR filename) 
{ 
    CString strArgs; 
    strArgs = _T("/select,\""); 
    strArgs += filename; 
    strArgs += _T("\""); 

    ShellExecute(0, _T("open"), _T("explorer.exe"), strArgs, 0, SW_NORMAL); 
} 

Mon problème est que si j'appelle cette fonction une deuxième fois avec un autre fichier, mais dans le même dossier, la sélection dans l'explorateur ne change pas dans le nouveau fichier, mais reste sur le fichier précédent.

Par exemple, si j'appelle ma fonction avec C:\path\to\file1.txt, une nouvelle fenêtre de l'explorateur s'ouvrira et file1.txt sera sélectionnée. Si j'appelle ma fonction une deuxième fois avec C:\path\to\file2.txt, la fenêtre de l'explorateur existant sera activée, mais la sélection sera toujours sur file1.txt.

Existe-t-il un moyen de forcer l'explorateur à mettre à jour la sélection ou une meilleure façon d'y parvenir?

EDIT:

Le comportement mentionné ci-dessus était sous Windows XP. Il semble que le comportement sur Vista/Win7 est différent. Chaque appel ouvrira une nouvelle instance d'explorateur et sélectionnera le fichier.

Mon objectif principal est de répliquer l'option Visual Studio à Open Containing Folder d'un document. Cette fonctionnalité dans Visual Studio se comporte de la même manière sur XP, Vista et Win7. Il ne créera pas une nouvelle instance si une autre instance avec le même dossier est déjà ouverte, mais elle mettra à jour la sélection vers le nouveau fichier.

Si quelqu'un sait comment Visual Studio accomplit cela, j'aimerais le savoir.

+0

Je ne vois pas ce comportement sur Windows 7 x64. Deux fenêtres s'ouvrent correctement, chacune avec le bon fichier sélectionné. –

+0

Vous avez raison, le comportement sur Vista et Win 7 est différent. J'ai mis à jour ma question pour le mentionner. – flashk

+0

http://stackoverflow.com/questions/4831101/how-to-re-use-existing-already-opened-windows-explorer-window-to-launch-explorer et http://stackoverflow.com/questions/8182494/how-i-set-an-existing-explorer-exe-instance-to-select-a-file semble lié ... – rogerdpack

Répondre

25

J'ai trouvé la réponse à ma question. Je dois utiliser la fonction shell SHOpenFolderAndSelectItems. Voici le code de la fonction si quelqu'un est intéressé:

void BrowseToFile(LPCTSTR filename) 
{ 
    ITEMIDLIST *pidl = ILCreateFromPath(filename); 
    if(pidl) { 
     SHOpenFolderAndSelectItems(pidl,0,0,0); 
     ILFree(pidl); 
    } 
} 
+0

apparaît chrome utilise cela, aussi, voir http://src.chromium.org /svn/trunk/src/chrome/browser/platform_util_win.cc – rogerdpack

+0

Voici une version binaire compilée que les gens peuvent appeler (pour ceux qui ne veulent pas de COM): https: //gist.github.com/rdp/9748303 – rogerdpack

+0

N'oubliez pas d'appeler 'CoInitializeEx (...)' avant d'appeler 'SHOpenFolderAndSelectItems (...)', et assurez-vous de remplacer tous les antislash de votre chemin par des antislashs. L'échec de l'une ou l'autre de ces deux choses entraînera un échec. –

0

Dans le cas où vous l'avez indiqué, la fenêtre de fichier ne sélectionne le fichier que lorsqu'il est initialisé au lieu d'être activé.

Bien que cela ressemble à un kludge, vous pouvez détecter XP et seulement pour ce système d'exploitation fermer la boîte de dialogue en utilisant son handle et en ouvrir un nouveau pour cibler un autre fichier avec.

2

Essayez l'option '/ n'. Cela ouvrira cependant un nouveau dossier - peut-être déjà ouvert. Mais, au moins, le fichier que vous spécifiez est sélectionné.

/n,/select,<path_and_filename> 

SHOpenFolderAndSelectItems échoue toujours dans mon cas et je ne peux pas comprendre pourquoi. Btw, vous devez appeler CoInitialize/CoInitializeEx avant d'appeler celui-ci.

+0

SHOpenFolderAndSelectItems échoue sauf si j'utilise un chemin complet parfaitement formaté, comme c: \ dev – rogerdpack

Questions connexes