Ordner auswählen mit CFileDialog



  • Hi,
    dass man mit CFileDialog Dateien auswählen kann, weiß ich.
    Ich würde aber gerne Ordner auswählen. Hat da einer einen Tip?
    Alternativ ginge es auch, wenn mir jemand sagte, wie ich, analog zum Explorer, dazu komme, auch die Netzwerkumgebung zu durchsuchen. GetLogicalDrives liefert nur die Laufwerke auf dem Rechner, nicht aber die im Netzwerk. Wenn es so eine Funktion gäbe, könnte ich mit die Dialogbox selber basteln.

    Danke
    Jens 🕶


  • Administrator

    Um Ordner auszuwählen, bzw. nach ihnen zu suchen in einem Dialog, dafür gibt es SHBrowseForFolder. Hier zwei Links:
    FAQ-Eintrag
    MSDN-Eintrag

    Um dir die Netzwerkharddisks aufzulisten, solltest du wohl folgende Funktion benutzen:
    WNetOpenEnum

    Grüssli



  • Bei dem OpenEnum bin ich auch schon gelandet:

    LPTSTR lpLocalName=NULL; 
        LPTSTR lpRemoteName=NULL; 
        LPTSTR lpComment=NULL; 
        LPTSTR lpProvider=NULL;
    	NETRESOURCE ntr;
    	 ntr.dwScope=RESOURCE_GLOBALNET;
    	 ntr.dwType=RESOURCETYPE_DISK;
    	 ntr.dwDisplayType=RESOURCEDISPLAYTYPE_SHARE;
    	 ntr.dwUsage=RESOURCEUSAGE_CONTAINER;
    	 ntr.lpLocalName=lpLocalName;
    	 ntr.lpRemoteName=lpRemoteName; 
    	 ntr.lpComment=lpComment;
    	 ntr.lpProvider=lpProvider;
    	 LPHANDLE lphEnum=NULL;
    	int z=WNetOpenEnum(
    			RESOURCE_GLOBALNET,     // scope of enumeration
    			RESOURCETYPE_DISK,      // resource types to list
    			RESOURCEUSAGE_CONTAINER,     // resource usage to list
    			&ntr,
                lphEnum         // pointer to resource structure
    			   // pointer to enumeration handle buffer
    );
    

    Leider liefert OpenEnum 487 zurück, ERROR_INVALID_ADDRESS.
    was kann man da denn machen?
    Gruß Jens


  • Administrator

    Lies den Fehler und schau dir deinen Code an. Ich habe noch nie damit gearbeitet, aber ich nehme schwer an, dass wenn du NETRESOURCE angibst, du nicht die Strings auf NULL setzen darfst. Zumindest genau so kommt mir der Fehler rüber. Ich habe nun auch ein wenig getestet und dabei noch ein Beispiel gefunden:
    http://msdn2.microsoft.com/en-us/library/aa385341.aspx

    Hier noch mein Code, den ich kurz zusammen geschnipselt habe:

    /////////////////////////////////////////////////////////////////////////////////
    // main.cpp : Implementation file
    
    #include <iostream>
    #include <conio.h>
    
    #include "windows.h"
    #include "Winnetwk.h"   // Lib nicht vergessen ;)
    
    int main()
    {
    	HANDLE hEnumeration;
    
    	DWORD dwReturn = ::WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, NULL, &hEnumeration);
    
    	if(dwReturn != NO_ERROR)
    	{
    		std::cout << "Error" << std::endl;
    		return dwReturn;
    	}
    
    	DWORD dwCount = -1;
    	DWORD dwBufferSize = 16384;
    	BYTE* pbBuffer = new BYTE[dwBufferSize];
    	NETRESOURCE* pNetresource = NULL;
    
    	do
    	{
    		dwReturn = ::WNetEnumResource(hEnumeration, &dwCount, pbBuffer, &dwBufferSize);
    
    		pNetresource = reinterpret_cast<NETRESOURCE*>(pbBuffer);
    
    		for(DWORD n = 0; n < dwCount; ++n)
    		{
                // Wenn du diese if-Anweisung weg nimmst, listet der irgendwie alles auf.
                // Hab die Auflistung selber wohl auch noch nicht ganz durchblickt.
                // wcout hier, weil ich mit Widebyte compiliert habe.
    			if(pNetresource[n].dwType == RESOURCETYPE_DISK)
    			{ std::wcout << pNetresource[n].lpRemoteName << std::endl; }
    		}
    	}
    	while(dwReturn == ERROR_MORE_DATA);
    
    	delete[] pbBuffer;
    
    	_getch();
    
        return 0;
    }
    

    Ich hoffe das hilft dir weiter. Ich selber will mich jetzt damit nicht weiter beschäftigen, da ich es ja schliesslich nicht brauche *g* 😉

    Grüssli



  • Vielen Dank Dravere! 🙂



  • Kleine Korrektur:

    delete pucBuffer;
    

    muss natürlich

    delete [] pbBuffer;
    

    heissen.


  • Administrator

    jencas schrieb:

    Kleine Korrektur:

    delete pucBuffer;
    

    muss natürlich

    delete [] pbBuffer;
    

    heissen.

    Ups, hab noch nach dem Copy&Paste etwas nachkorrigiert, never touch a running system. 😃
    Korrigiere es gleich noch oben im Code, sonst hat es halt ein schönes Speicherleck 😉

    Grüssli


Anmelden zum Antworten