Ein Problem bei einem Kunden hat mich ins ungläubige Staunen getrieben.
Wir haben in einem Einstellungsdialog ein Edit Control für einen Dateinamen. Dazu einen simplen Schalter mit dem man einen CFileDialog öffnet und die Datei so auswählen kann. Bei einem Kunden wollte aber der Dialog in einigen Fällen nicht öffnen, der Klick auf den Schalter blieb ohne Wirkung. Da der entsprechende Code so simpel war, kam ein Programmfehler kaum in Frage.
Nachdem ich mir einen Screenshot habe senden lassen, staunte ich nicht schlecht, denn ich konnte den Fehler mit gleichen Eingaben zuerst nicht nachvollziehen, denn ich nutzte Vista und der Kunde hatte XP SP2. Sobald ich aber unter XP die selben Vorgaben machte, trat der Fehler auch bei mir auf.
Es scheint ein Bug in den Common Dialogs zu sein. Ist der Dateiname, den man im zweiten Parameter von CFileDialog angibt (vorschlägt) in bestimmter Weise „ungültig“, dann öffnet der Dialog nicht. Der Rückgabewert ist IDCANCEL (2) und CommDlgExtendedError liefert FNERR_INVALIDFILENAME. Ungültig ist aber fast zu viel gesagt, denn der Pfad enthielt an einer Stelle nur einfach 2 Backslashes statt einen, wie üblich.
Einfach nachzuvollziehen mit dem folgenden Snippet:
// Preset filename with a double backslash in the path:
// C:\TEMP\\Schrott.txt
CFileDialog dlg(TRUE,_T("txt"),_T("C:\\TEMP\\\\Schrott.txt"),
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("Text files|*.txt|All files|*.*||"));
INT_PTR iResult = dlg.DoModal();
DWORD dwLastError = GetLastError();
DWORD dwCommLastError = CommDlgExtendedError();
CString strResult;
strResult.Format(_T("Returncode %d, Lasterror 0x%08X, CommLastError 0x%08X"),
iResult,dwLastError,dwCommLastError);
AfxMessageBox(strResult);
Eigentlich nur verwunderlich, denn der Name selbst mit doppelten Backslashes wird vom Dateisystem sonst überall akzeptiert. Man kann eine Datei mit dem Namen öffnen, lesen und schreiben. Nur CFileDialog mag ihn nicht. Oder besser der Standard-Common-File-Dialog mag ihn nicht.
Bleibt die Frage warum ich unter Vista den Fehler nicht bekam?
Nutzt man VS-2008 und lässt das Programm unter Vista laufen, dann ist auch alles wieder gut. Denn unter Vista benutzt Der CFileDialog ein neues Interface (Common Item Dialog) und nicht mehr den normalen Common-File-Dialog. Die neuen in die MFC gewrappten Dateidialoge von Vista können mit dieser Vorgabe umgehen.
Lässt man das gleiche Programm wieder unter XP SP2 laufen, bekommt man den entsprechenden Fehler wieder, da in diesem Fall wieder die Standard-Common-Dialoge verwendet werden.