PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : VC++: Save File Dialog erzeugen?


Vedek Bareil
2005-08-09, 13:20:17
Hi Leute,

ich habe folgendes Problem (Visual C++ 6):
ich will einen Save File Dialog erzeugen. Nun gibt es ja diese CFileDialog-Klasse, die eigentlich zu diesem Zweck recht gut geeignet wäre. Allerdings trägt bei ihr der Button, mit dem die Dateiauswahl bestätigt wird (also wodurch DoModal IDOK zurückgibt), die Aufschrift "Open". Und die kann auch offenbar nicht zu "Save As" umgeändert werden.

Alternativ gibt es da noch die Funktion GetSaveFileName, die auch darauf ausgelegt ist, einen Save Dialog anzuzeigen. Das Problem ist: die hat als Parameter einen Pointer zu einer OPENFILENAME-Struktur, die so ungefähr x-tausend Einträge hat, die alle in mühseliger Handarbeit aufgefüllt werden müßten.

Die CFileDialog-Klasse verwendet zwar auch eine OPENFILENAME-Struktur (m_ofn), die aber automatisch befüllt wird. Mir kam bereits die Idee, einfach eine Struktur vom CFileDialog-Konstruktor befüllen zu lassen und dann an GetSaveFileName zu übergeben:

CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT, NULL);
GetSaveFileName(&dlg.m_ofn);

Aber da spielt Windows (XP) nicht mit und läßt es nur so Assertion Failed-Fehlermeldungen hageln.

Gibt es keine komfortable Möglichkeiten zum Erzeugen eines Datei speichern Dialoges?

Demirug
2005-08-09, 13:24:42
Einfach aus dem ersten TRUE ein FALSE machen.

Vedek Bareil
2005-08-09, 13:34:57
Thx

Coda
2005-08-09, 13:42:56
Nur so ne Anmerkung am Rande: Statt "VC++:" wäre "MFC:" angebrachter gewesen.

ShadowXX
2005-08-09, 13:51:54
Und als zweite kleiner Anmerkung:

Einfach mal in die MSDN gucken...da steht sowas auch drinne (die gibts auch Online und ist für jeden zugänglich).

Vedek Bareil
2005-08-09, 14:37:03
Und als zweite kleiner Anmerkung:

Einfach mal in die MSDN gucken...da steht sowas auch drinne jedenfalls wenn man lange genug sucht. In der Doku zur CFileDialog-Klasse steht endlos viel Text, auch zum Thema Open und Save File Dialog. Aber wie man aus einem CFileDialog denn nun einen Save Dialog macht, dazu hab ich erst in der Passage für den Konstruktor was gefunden.

GloomY
2005-08-09, 16:43:59
Ich hab' mich vor kurzem auch mit dem Problem des Save-Dialog-Erzeugens rumgeschlagen. Falls es noch interessiert, hier mal meine Lösung in reinem C:

FILE *datei_oeffnen(void) {

char filename[1024];
strcpy(filename,"yipiieh.csv");

OPENFILENAME ofn;
memset (&ofn, 0, sizeof(OPENFILENAME));

// hell on earth
ofn.lStructSize = sizeof(OPENFILENAME); // wird benötigt
ofn.hwndOwner = NULL; // kein Fenster Owner
ofn.lpstrFilter = "csv-Dateien\0*.csv\0"; // *csv als Auswahlfilter
ofn.lpstrCustomFilter = NULL; // kein eigener Filter
ofn.lpstrFile = filename; // unser Buffer
ofn.nMaxFile = 1024; // Größe unseres Buffers
ofn.lpstrFileTitle = NULL; // Dateiname ohne Pfad ist unnütz
ofn.lpstrInitialDir = NULL; // kein spezielles Verzeichnis am Anfang
ofn.lpstrTitle = "Datei zum Öffnen auswählen..."; // Titelleiste
ofn.Flags = /* Eigenschaften der Dialogbox */
OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_READONLY;
/* Alle weiteren Member der OPENFILENAME struct, die
* nicht benötigt werden, habe ich schon weggelassen und werden mit 0
* initialisiert.
*/

if (GetOpenFileName(&ofn)) {
printf("Öffne Datei \"%s\"\n", filename);
return fopen(filename, "r");
} else {
printf("Fehler!\n\n");
int error = CommDlgExtendedError(); // gib mir den Fehlercode
switch (error) {
case 0:
printf("Abbruch durch Benutzer.\n\n");
sleep(1000);
exit(0);
case FNERR_BUFFERTOOSMALL:
printf("Der interne Buffer ist zu klein.");
break;
case FNERR_INVALIDFILENAME:
printf("Der Dateiname ist ungültig.");
break;
case FNERR_SUBCLASSFAILURE:
printf("Nicht genügend Speicher vorhanden!");
break;
case CDERR_DIALOGFAILURE:
case CDERR_FINDRESFAILURE:
case CDERR_INITIALIZATION:
case CDERR_LOADRESFAILURE:
case CDERR_LOADSTRFAILURE:
case CDERR_LOCKRESFAILURE:
case CDERR_MEMALLOCFAILURE:
case CDERR_MEMLOCKFAILURE:
printf("Die Dialogbox konnte nicht erstellt werden. ");
default:
printf("Vielleicht hilft ein Reboot oder installieren Sie Windows ");
printf("neu.\nOder nerven Sie ihren Systemadministrator!");
}
printf("\n\nProgrammabbruch! Fehlercode: %i\n", error);
system("PAUSE");
exit(1);
}

Coda
2005-08-09, 16:50:55
Noch mehr OT: Ich würde sowieso einen großen Bogen um MFC und Win32 machen.

Es gibt so schöne Toolkits wie Qt oder wxWidgets :(

Trap
2005-08-09, 19:36:23
Auch Windows Forms (aus .NET) ist besser.

MFC würd ich nur unter Bedrohung meines Lebens benutzen, Geld reicht nicht mich dazu zu bringen ;)

grakaman
2005-08-09, 21:18:14
Noch mehr OT: Ich würde sowieso einen großen Bogen um MFC und Win32 machen.


Wenn man aber etwas mehr als das Standardzeugs macht, kommt man imo um direkte Win32 Aufrufe im Moment oft nicht herum, egal ob von VB6, .NET etc. Deswegen ist es nicht schlecht, wenn man sich damit zum Teil schon auskennt. Zumindest bis es eine vollständige Ersetzung gibt.

Coda
2005-08-09, 21:20:08
Also mir hat bisher mit wxWidgets und Boost nix gefehlt wozu ich proprietäre APIs gebraucht hätte (Ok, um eine shared lib zu laden mal, aber das ist mit paar #ifdefs auch auf Unix lauffähig)

grakaman
2005-08-09, 21:27:27
Also mir hat bisher mit wxWidgets und Boost nix gefehlt wozu ich proprietäre APIs gebraucht hätte (Ok, um eine shared lib zu laden mal, aber das ist mit paar #ifdefs auch auf Unix lauffähig)

Es gibt da aber wirklich noch sehr viel. Als Bsp., was mir in unmittelbarer Vergangenheit untergekommen ist, ist z.B. die RichTextBox. Da kannst du sowohl bei .NET oder VB6 schön kräftig Win32 Aufrufe verwenden, um brauchbare Funktionalität zu erlangen (z.B. erweiterte Typographieoptionen, Links/Zentrierte/Rechtsbündige/Dezimal Tabs, Indent etc. etc.). Da schätzungsweise andere Bibliotheken ebenfalls das RichEdit Control von Windows verwenden, wird es dort nicht anders sein oder man hat dort wirklich alles implementiert und gewrapped. Es gibt aber noch ne ganze Reihe anderer Fälle, wo man zumindest bei VB6, .NET noch Win32 Aufrufe machen muss.

Coda
2005-08-09, 21:55:45
Wer redet denn von .NET und VB6? Qt und wx wrappen wirklich so gut wie alles.

Vor allem Qt sollte das auch tun, weil ganz KDE darauf aufbaut ;)

grakaman
2005-08-09, 22:19:23
Wer redet denn von .NET und VB6?


Ich, zwei Postings weiter oben, weil du von Win32 generell abrätst, was imo in der Praxis nicht gänzlich möglich ist. Mein Bsp. war ja auch nur wirklich ein kleines unter vielen und komischerweise scheinen die selben Probleme auch unter Delphi zu existieren. Wie das unter QT aussieht, weiß ich nicht. Allerdings beweifle ich wirklich, dass dort alles gewrapped wird, was nativ unter Win32 alles möglich wäre. Nichts desto trotz, wer in Delphi, .NET, VB etc. programmiert, verwendet kein QT ;)

Coda
2005-08-09, 22:38:48
Davon war hier ja auch nie die Rede. :|
Es ging mir um C/C++. Und mit Qt ist man wirklich auf der sehr sicheren Seite, ich denke mal die Rich Text API ist dort sogar mächtiger als die von Windows.

P.S.: Man schreibt es Qt, nicht QT und spricht es "cute" nicht "kuuh tee"

grakaman
2005-08-10, 08:34:46
Und mit Qt ist man wirklich auf der sehr sicheren Seite, ich denke mal die Rich Text API ist dort sogar mächtiger als die von Windows.


Wie gesagt, ich kenne Qt nicht :( Aber mit RichEdit Control meine ich freilich auch das Rich Text Format, nicht einfach einen Editor mit Formatierung (laut Google scheint das wohl eben gar nicht in Qt vorhanden bzw. man muss auf Fremdkomponenten zurückgreifen).

Coda
2005-08-10, 11:02:07
Hm? http://doc.trolltech.com/4.0/richtext.html

Edit: Hm ja, das scheint doch auf HTML aufzubauen nicht auch dem RTF.

ShadowXX
2005-08-10, 12:14:56
Wer redet denn von .NET und VB6? Qt und wx wrappen wirklich so gut wie alles.

Vor allem Qt sollte das auch tun, weil ganz KDE darauf aufbaut ;)

Qt kostet für die kommerzielle Nutzung zu viel Geld. Leider......

Wir werden deshalb "gezwungen" mit der MFC zu arbeiten....wenn man sich erst mal an die nicht vorhandene Strukturierung bzw. uneinheitliche Namesgebung gewöhnt hat, gehts aber sogar.

.Net sieht zwar Teilweise etwas schöner aus, aber für die meisten .Net-"Gags" habe ich inzwischen selbstgeschriebene Controls erstellt.

ShadowXX
2005-08-10, 12:17:52
jedenfalls wenn man lange genug sucht. In der Doku zur CFileDialog-Klasse steht endlos viel Text, auch zum Thema Open und Save File Dialog. Aber wie man aus einem CFileDialog denn nun einen Save Dialog macht, dazu hab ich erst in der Passage für den Konstruktor was gefunden.

Naja...unter Constuction/Destuction sollte man eigentlich immer mal nachgucken (Eigentlich als zweites, nachdem man den "einleitenden" Text gelesen hat.)

Danach wendet man sich den Members zu.....

Coda
2005-08-10, 12:46:05
Qt kostet für die kommerzielle Nutzung zu viel Geld. Leider......Es gibt wxWidgets, ist zwar nicht so bekannt aber fast so gut wie Qt und hundertausendmillionenfach besser als MFC ;)

Wir werden deshalb "gezwungen" mit der MFC zu arbeiten....*Legt eine Schweigeminute für die Opfer ein*