CFileDialog::GetFileName() liefert falsche Ergebnisse

sun-fire

Grünschnabel
Hi Leute,

ich bin heute auf etwas interessantes gestoßen:
Die Funktionen CFileDialog::GetFileName() und GetFileTitle() liefern falsche Ergebnisse, wenn der eingegebene Dateiname länger ist als der interne Buffer m_pOFN.nMaxFileTitle (64 Zeichen). Dass der Name zu lang ist, ist ja auch okay, nur wird der Name kommentarlos abgeschnitten, d.h., es kommt keine Fehlermeldung, Warnung o.ä.. Wenn man nun intern mit dem Namen weiterarbeitet, kann ganz schöner Müll daraus werden! :)
CFileDialog::GetPathName() liefert dagegen das vollständige Ergebnis.

Sicher ist von Euch auch schon einmal jemand auf dieses Phänomen gestoßen. Wie geht Ihr damit um?

Viele Grüße
Sunfire
 
Moin sun-fire,

ich kenne diese Phänomen nicht!!

Wie ich damit umgehen würde?
Ich denke mal, ich würde die Funktion nehmen, die das richtige Ergebnis liefert :suspekt:

Oder verstehe ich Deine Frage falsch ? ? ?

Gruß
Klaus
 
Hi Klaus,

ja, ein wenig hast Du den Kern missverstanden:

GetFileName soll den Dateinamen mit Endung liefern.
GetFileTitle soll den Dateinamen ohne Endung liefern.
GetPathName liefert den vollständigen Pfad mit Dateinamen und Endung. Diesen muss man dann quasi selbst "zerhacken", wenn man die anderen Teile separat braucht. Würden die ersten beiden Funktionen auch bei "zu langen" Dateinamen korrekt arbeiten, könnte man sich diese Handarbeit sparen...

Viele Grüße
Sunfire
 
Hallo,

ok, aber dass kannst Du doch dann über eine Hilfsfunktion lösen, in der Du dann "GetPathName" aufrufst, entsprechend zerlegst und dann jedesmal passend verwendest!

Wenn die anderen beiden Funktion von der Länge beschränkt sind, ist das halt so .... ist denn bei "GetPathName" die Länge nicht auch irgendwann beschränkt? Oder bekommst Du da einen String?

Gruß
Klaus
 
Hallo Klaus,

das ist mir schon klar, aber eben diese Handarbeit könnte man sich sparen, wenn die Funktionen korrekt arbeiten würden!

Leider steht auch nirgends etwas davon, dass sie in der Länge beschränkt sind. Sie schneiden einfach ab und man bekommt keinen Hinweis. Erst wenn man mit den Werten weiterarbeitet, merkt man irgendwann, dass hier was schiefläuft. => schlechter Programmierstil von Seiten MS. Irgendeine Ausnahme oder sowas würde man doch wenigstens erwarten, wenn ein intern gesetzter Buffer überschritten wird, oder?

Die Beschränkung von GetPathName() liegt wohl bei 260 (MAX_PATH). Dies habe ich jetzt nicht zu Ende getestet, weil mir die Zählerei zu blöd war. Das Eingabefeld im FileDialog lässt irgendwann keine weiteren Zeichen mehr zu und dann kommt auch die Fehlermeldung, der Name sei ungültig. Meinem Gefühl nach ist dies bei 256 Zeichen der Fall. Wenn ich schon eine Namensbegrenzung bei 64 resp. 60 Zeichen (ohne Endung) habe, wäre es schön , wenn auch das Eingabefeld an dieser Stelle begrenzt wäre, findest Du nicht? ;-)

Und: ja, ich bekomme einen String, aber auch bei den anderen Funktionen (was sonst?). :)

Viele Grüße
Tanja
 
Hallo Tanja,

stimmt, habe eben mal in meiner Hilfe geschaut (VC++ 6.0) und da steht auch nix von einer Beschränkung ....
Ich benutze diese Funktion jedoch nur ein einziges Mal bei kurzen Dateinamen (8.3), da ist es noch nie aufgefallen ;-)

Da wirst Du dann vermutlich nicht um eine eigene Funktion herumkommen!

Gruß
Klaus
 
Ergänzung: CFileDialog::GetFileName() liefert falsche Ergebnisse

Aaalso, jetzt hab ichs doch noch durchgetestet: auch GetPathName() schneidet gnadenlos ab, wenn der Pfad über 256 Zeichen hinausgeht. Ist schon witzig... (so lange Namen/Pfade sind zwar eh doof, aber interessant find' ich's trotzdem) ;-)
 
Hi.

Schau mal hier (http://msdn.microsoft.com/en-us/library/dk77e5e7(VS.80).aspx)
Additionally, you must set m_ofn.nMaxFile with the number of characters in the buffer pointed to by m_ofn.lpstrFile. If you set the maximum number of files to be selected to n, the necessary buffer size is n*(_MAX_PATH + 1) + 1. For example:
C++:
CFileDialog dlgFile(...);
...
CString fileName;
dlgFile.GetOFN().lpstrFile = fileName.GetBuffer(<very large number>);
dlgFile.GetOFN().nMaxFile = <very large number>;

INT_PTR nResult = dlgFile.DoModal();
fileName.ReleaseBuffer();
Standardmäßig wird der Wert von MAX_PATH (260) für die Größe verwendet.

Gruß
 
Zurück