IFileDialog und SetFolder



  • Hallo,

    ist vieleicht nicht richtig MFC, aber ich will es in MFC nutzen.

    Also: Ich möchte ein FolderBrowser haben. SHBrowseForFolder nutze ich bis win XP und ab Vista wird ja IFileDialog empfohlen (msdn). Nun hab ich das soweit mit dem IFileDialog und möchte noch ein Startverzeichniss anhängen (z.B. mit IFileDialog::SetFolder())
    Wie man das macht wird auch in der msdn beschrieben (http://msdn.microsoft.com/en-us/library/bb776913(VS.85).aspx#start_folder)
    Das Problem is nur: SHCreateItemFromFolderID() schein nur auf dieser Seite erwähnt worden zu sein (siehe google suche) Keine Doku oder ähnliches.
    Kennt / nutzt jemand die Funktion? Abgesehen davon kann man denn damit auch ein IShellItem auf ein Unterverzeichnis erhalten?

    Also die konkrete Frage lautet: Wie gebe ich einem IFileDialog ein Inital Verzeichnis bzw. Wie kann ich ein IShellItem auf ein Verzeichniss erstellen?

    Gruß und dank
    Micha


  • Mod

    Das ist eine Pseudo-Funktion... die gibt es so nicht.

    Nutze eine der entsprechenden Funktionen, die Dir passen
    SHCreateShellItem
    SHCreateItemFromIDList
    SHCreateItemFromParsingName
    SHCreateItemWithParent
    SHCreateItemFromRelativeName
    SHCreateItemInKnownFolder
    SHGetItemFromObject



  • Danke für den Hinweis.

    ich habs jetzt so gemacht:

    //IFileOpenDialog pDlg...
    IShellItem *psi;
    CString initPath = _T("c:\");
    SHCreateItemFromParsingName(initPath, NULL, IID_PPV_ARGS(&psi));        
    pDlg->SetFolder(psi);
    

    Unter Windows 7 läuft das auch, nur wenn ich das Programm unter XP starten will kommt die Meldung "Der Prozedureinstiegspunkt "SHCreateItemFromPhrasingName" wurde in der DLL "Shell32.dll" nicht gefunden". Ja wieso auch: ist ja erst ab Vista mit dabei. Die Funktion wird aber garnicht unter XP aufgerufen, beim Programmstart erst recht nicht.
    Was muss ich denn machen, das das Programm trotzdem unter XP lauffähig ist?

    Micha


  • Mod

    Du darfst diese Funktion nicht implizit aufrufen.
    - Delay Load verwenden für Shell32.dll
    - Oder LoadLibrary mit GetProcAddr



  • Ich hab das mal mit LoadLibrary versucht: kommt die gleiche Fehlermeldung wie vorher:

    typedef HRESULT(CALLBACK* MySHCreateItemFromParsingName)(PCWSTR path, IBindCtx* pbc, REFIID riid, __deref_out void **ppv);
    
    IShellItem *psi;
    HINSTANCE hDll = LoadLibrary(_T("Shell32.dll"));
    if(hDll)
    {
    	MySHCreateItemFromParsingName pMySHCreateItemFromParsingName;
    	pMySHCreateItemFromParsingName = (MySHCreateItemFromParsingName)GetProcAddress(hDll,
    	"SHCreateItemFromParsingName");
    	if(pMySHCreateItemFromParsingName)
    	{
    		if(pMySHCreateItemFromParsingName(help, NULL, IID_PPV_ARGS(&psi)))
    			pDlg->SetFolder(psi);
    	}
    	FreeLibrary(hDll);
    }
    

    Das mit Delayload werde ich nicht nutzen. Ich hab da so ein ungutes Gefühl sowas für eine so recht unwichtige Funktion zu machen. Haben die Leute ab Vista eben etwas mehraufwand...

    edit: Ein vollständiges Neuerstellen hat die Fehlermeldung verschwinden lassen. Es scheint auf Win 7 aber nicht zu funktionieren. Kann mir jemand sagen, ob es eine Möglichkeit gibt, wenn ich unter XP entwickle, das ich unter win 7 debuggen kann? Ständig den Rechner hoch- und runterfahren nervt langsam.

    Micha


  • Mod

    Warum nimmst Du nicht Remote Debugging?

    1. Sag mal: Hast Du mal den Rückgabewert angesehen?
    SHCreateItemFromParsingName liefert einen HRESULT!
    S_OK ist 0! Du machst das ganze nur im Fehlerfall was natürlich nicht gehen kann!
    2. Ich würde Dir bei solch einem Code dringend raten psi zu initialiseren. Der Code müsste Dir IMHO um die Ohren fliegen.


Anmelden zum Antworten