# MFC: Pfad festlegen (Auswahlbutton)



## Dragosani (8. Februar 2007)

Also, ich versuche mich das erste Mal so richtig an einem MFC Programm (bin GUI Programmierung nicht gewöhnt).

Folgendes soll das kleine Programm machen: Ich möchte den Pfad zu einem Ordner in einem Edit-Feld anzeigen lassen. Klingt einfach, aber ich bekomme es nicht hin.

Erstmal der Code, wenn ich auf den "Wählen" Button klicke:


```
void CTest3Dlg::OnBnClickedPathopen()
{
	//Benachrichtigung
	CFileDialog ldFile(TRUE);
	//Dialogfeld Path Open zeigen und Ergebnis auffangen
	if (ldFile.DoModal() == IDOK)
	{
		//Gewähltes Verzeichnis ermitteln
		m_strResults1 = ldFile.GetFolderPath();
		// Dialogfeld aktualisieren
		UpdateData(FALSE);
	}
}
```

Ich habe da aus den CFileDialog Members die Funktion *GetFolderPath()* genommen, aber wenn ich das Programm so ausführe und auf den Button klicke, dann öffnet sich zwar ein Auswahlfenster, aber ich muss dennoch eine Datei auswählen und mit "öffnen" bestätigen. Aber nichtmal das hat den gewünschten Erfolg, da ich sofort einen Fehler bekomme.

Nutze ich anstatt GetFolderPath() GetPathName, dann erhalte ich ja leider den Pfad zu einer Datei (leider inkl. Dateiname), was mir so nicht reicht.

Wie kann ich es hinbekommen, daß ich zum einen nur einen Ordner wählen muss und keine Datei und er mir keinen Absturzt provoziert.

Zum Compiler: ich nutze Visual C++ Professional.


----------



## jokey2 (8. Februar 2007)

Mit dem CFileDialog kann man nur Dateien auswählen. Die Auswahl von Ordnern ist da nicht vorgesehen. SHGetFolder wäre da die richtige Wahl. Da die Anwendung aber etwas kompliziert ist, gibt es eine Wrapper-Klasse dafür bei CodeGuru.
Abgesehen davon sollte es mit CFileDialog funktionieren, wenn Du eine Datei auswählst. Welcher Fehler tritt denn wo auf?


----------



## Dragosani (8. Februar 2007)

Wenn ich ein die Funktion GetFolderPath() nutze (wie oben im Code) und dann den Button nutze, dann eine Datei wähle und auf "öffnen" gehe, bricht das Programm sofort ab.

Mit einer anderen Funktion (beispielsweise GetPathName()) geht es ohne Probleme.

Hm, Wrapper Klassen - ich weiß nichtmal was das ist  Geschweige denn, wie man das einbeut


----------



## jokey2 (8. Februar 2007)

Auszug aus dem MSDN zu GetFolderPath: 


> The dialog box must have been created with the *OFN_EXPLORER* style;  otherwise, the function will fail with an assertion.


Eine Wrapper-Klasse ist eine Klasse, die eine Funktionalität enthält, welche von mehreren API-Funktionen erbracht wird. Sie ist zur Vereinfachung der Anwendung. Die Verwendung von SHGetFolderPath ist ziemlich komplex. Daher hat jemand eine Klasse geschrieben, die diese Funktion verwendet, aber den Aufruf vereinfacht.
Du mußt Dir nur die Dateien von CodeGuru runterladen und sie in Dein Projekt einfügen. Dann erstellst Du eine Instanz der Klasse analog zur Verwendung von CFileDialog, rufst DoModal auf und holst Dir danach den Pfad mit der Memberfunktion GetPath.


----------



## Dragosani (8. Februar 2007)

Hm, okay ich werde es mal versuchen, sobald ich zu Hause bin. Herrje, schwere Geburt fürs zweite Programm ...


----------



## MCoder (8. Februar 2007)

jokey2 hat gesagt.:


> SHGetFolder wäre da die richtige Wahl.


Die Funktion zum Auswählen von Ordnern heißt SHBrowseForFolder() und ist eigentlich nicht besonders schwierig anzuwenden.

```
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE  0x0040
#endif

CString strFolder = _T("");

BROWSEINFO      brInf;
LPITEMIDLIST    pidl;
TCHAR           lpBuffer[MAX_PATH];

brInf.hwndOwner      = GetSafeHwnd();
brInf.pidlRoot       = NULL;
brInf.pszDisplayName = lpBuffer;
brInf.lpszTitle      = _T("Ordner wählen");
brInf.ulFlags        = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
brInf.lpfn           = NULL;
brInf.lParam         = 0;
brInf.iImage         = 0;

pidl = SHBrowseForFolder(&brInf);

if( pidl )
{
    SHGetPathFromIDList(pidl, lpBuffer);
    strFolder = lpBuffer;
}
```
Gruß
MCoder


----------



## Dragosani (9. Februar 2007)

Oh, Deinen Beitrag habe ich jetzt erst gesehen. Wo baue ich denn den Code ein? In die Header Datei?

Und dann kann ich dies einfach durch ein SHBrowseForFolder() aufrufen?


----------



## MCoder (9. Februar 2007)

Den Code kannst du in deiner Methode "OnBnClickedPathopen()" einbauen. Den "#ifdef ..." - Block brauchst du wahrscheinlich nur, wenn du noch das "Visual Studio 6" verwendest. Die Variable "strFolder" enthält dann den Ordner. Hier könntest du auch gleich "m_strResults1" verwenden.

Gruß
MCoder


----------



## Dragosani (9. Februar 2007)

Juhu, das werde ich direkt morgen früh testen. Klingt ja sogar so leicht, daß sogar ich es packe 

Vielen Dank. Ich melde mich wieder.

Edit:

Jau, das klappt sogar  Tausend Dank.

Nun muss ich nur noch irgendwie mein DOS Programm in die GUI bekommen *seufzt*


----------

