File Open Dialog nur für Ordner

anmae

Erfahrenes Mitglied
Hallo,
ich habe einen Speichern unter Dialog. Diesen möchte ich nun so anpassen das ich nur den Ordner auswählen kann und nicht den Dateinamen.
Wie geht das?


Also ich möchte einfach nur den Speicherort für eine Datei auswählen. Wenn das nicht mit dem Dialog geht, gibt es vielleicht eine Alternative?


Danke
 
Zuletzt bearbeitet:
Danke erstmal.

ich hab hier im Forum das gefunden:

Code:
	BROWSEINFO bi;	
	bi.hwndOwner      = GetSafeHwnd();					
  	bi.pidlRoot       = NULL; 
  	bi.pszDisplayName = "Speichern unter";  
  	bi.lpszTitle      = NULL; 
  	bi.ulFlags        = BIF_RETURNONLYFSDIRS;
  	bi.lpfn           = NULL;           
  	bi.lParam         = 0;    
  	bi.iImage         = 0;    

	LPITEMIDLIST pidl;	
	pidl = SHBrowseForFolder(&bi);
leider gibt das bei mir einen Absturz nach dem Schließen des Dialogs :( !?
 
Selbst mit der Funktion PidlBrowse(...) aus der MSDN bekomme ich einen Absturz nach dem Dialog.
Ich hab es auch schon mit m_hWnd anstatt mit GetSafeWnd() versucht - das selbe.

Hat jemand eine Idee?
 
Die Funktion SHGetFolderLocation() kennt er nicht.

kann es sein, das ich irgendwas nicht included habe und mit einer Überladenen Funktion arbeite welche mir dann den Absturz beschert?
 
ich habs so gelöst:

Code:
#include <shlobj.h>

...

static BROWSEINFO	 bi;
TCHAR				 szPath[MAX_PATH];
ITEMIDLIST			 * browser;
LPMALLOC			 lpMalloc;

// Browsinfo initialisieren
bi.hwndOwner = hDlg;
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = TEXT ("Bitte wählen Sie das gewünschte Verzeichnis aus!");
bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;

// Dialog zum Verzeichnis wählen einblenden
browser = SHBrowseForFolder (&bi);

// und gewähltes Verzeichnis auswerten
if (browser)
{
	if(SHGetPathFromIDList (browser, szPath)) 
	{
		SetWindowText (hEditDevice, szPath);
	}
}
			    
SHGetMalloc (&lpMalloc);

lpMalloc->lpVtbl->Free (lpMalloc, browser);

Wobei "lpMalloc->lpVtbl->Free (lpMalloc, browser);" in C++ so aussehen sollte: "lpMalloc->Free (browser);"

Und je nach dem Welche Parameter du bei bi.ulFlags verwendest kannst du weitere Funktionen zu dem Ordner wählen Dialog hinzufügen. Schau dazu einfach mal beim MSDN nach, dort sind die einzelnen Flags gut erklärt. Hoffe das bringt dich weiter!
 
Ich habe mal eine Variante gebaut, mit der man auch einen Pfad voreistellen und festlegen kann, ab welchen Laufwerk bzw. Ordner gebrowst wird:
Code:
// Deklaration (in .h)
/////////////////////////////////////////////////////////////////////////////////

CString BrowseFolder(LPCTSTR lpszTitle, LPCTSTR lpszDefault, LPCTSTR lpszRoot);
static int CALLBACK BrowseCallBackProc(HWND  hwnd, UINT uMsg, LPARAM lp, LPARAM pData);


// Implementierung (in .cpp)
/////////////////////////////////////////////////////////////////////////////////

#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE	0x0040
#endif

//-------------------------------------------------------------------
//  Beschreibung:   Pfadauswahldialog
//-------------------------------------------------------------------
//  Parameter:      lpszDefault ... voreingestellter Pfad
//                  lpszTitle   ... Dialogtitel
//                  lpszRoot    ... Pfad, ab dem Struktur angezeigt
//                                  wird
//  RETURN          Gewählter Ordner oder leer bei Abbruch
//-------------------------------------------------------------------
CString CMyDialog::BrowseFolder( LPCTSTR lpszTitle,
                                 LPCTSTR lpszDefault,
                                 LPCTSTR lpszRoot)
{
    BROWSEINFO      brInf;
    LPITEMIDLIST    pidl;
    LPSHELLFOLDER   pshf;   
    ULONG           pchEaten;
    OLECHAR         olePath[_MAX_PATH];
    TCHAR           lpBuffer[_MAX_PATH];

    if( SUCCEEDED(SHGetDesktopFolder(&pshf)) )
    {
        if( lpszRoot )
        {
            MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)lpszRoot, -1, olePath, _MAX_PATH);
            pshf->ParseDisplayName(GetSafeHwnd(), NULL, olePath, &pchEaten, &pidl, NULL);
            brInf.pidlRoot = pidl;
        }
        else
        {
            brInf.pidlRoot = NULL;
        }

        brInf.hwndOwner         = GetSafeHwnd();
        brInf.pszDisplayName    = lpBuffer;
        brInf.lpszTitle         = lpszTitle;
        brInf.ulFlags           = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
        brInf.lpfn              = BrowseCallBackProc;
        brInf.lParam            = (LPARAM)lpszDefault;
        brInf.iImage            = 0;
    
        pidl = SHBrowseForFolder(&brInf);
    
        if( pidl )
        {
            SHGetPathFromIDList(pidl, lpBuffer);
            return CString(lpBuffer);
        }
    }

    return CString(_T(""));
}

//-------------------------------------------------------------------
//  Callback-Funktion für SHBrowseForFolder
//-------------------------------------------------------------------
int CALLBACK CMyDialog::BrowseCallBackProc( HWND   hwnd,
                                            UINT   uMsg,
                                            LPARAM lp,
                                            LPARAM pData )
{
    switch( uMsg )
    {
        case BFFM_INITIALIZED:
            if( pData )
            {
                ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, pData);
            }
            break;
    }

    return 0;
}

Gruß
MCoder
 
Habe noch eine Frage dazu.

Es klappt alles. Das einzige Problem, dass ich habe:

Das Fenster öffnet sich modal hinter meinem Dialog. Komme dort nur mit, Alt-Tab oder alles minimieren und Dialog dann wieder maximieren, dran.

Was kann ich da machen?

Danke Robert.
 
Zurück