Problem mit dem Setzen von OPENFILENAME.lpstrFilter



  • Guten Abend,

    So langsam bin ich am Verzweifeln.
    Folgendes Problem, ich will eine Datei öffnen, funktioniert beim ersten Mal alles prima. Beim zweiten Durchlauf stehen im Filter irgendwelche Pfadreste drin, also bin ich zu der Stelle durchdebugged.

    void __fastcall TForm1::OnClick2(TObject *Sender){
    
     //	OPENFILENAME ofn;       // common dialog box structure
    	HWND hwnd = NULL;              // owner window
    	HANDLE hf ;            // file handle
            char XFileName[1000];
    
    	// Initialize OPENFILENAME
    	ZeroMemory(&ofn, sizeof(OPENFILENAME));
    	ofn.lStructSize = sizeof(OPENFILENAME);
    	ofn.hwndOwner = hwnd;
    	ofn.lpstrFile = "";
    	ofn.nMaxFile = sizeof(XFileName);
    	ofn.lpstrFilter ="NOD-Dateien\0*.nod\0";
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFileTitle = "Plan oeffnen";
    	ofn.nMaxFileTitle = 0;
    	ofn.lpstrInitialDir = Application->ExeName.c_str();
    	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    
            if(GetOpenFileName(&ofn)==true){
            ...
    

    Bevor ich zu der Zeile

    ofn.lpstrFilter ="*.nod\0*.nod\0";
    

    komme, ist der Inhalt wie gewünscht NULL. Sobald ich aber an der Zeile vorbei bin, steht statt dem Filterinhalt die letzten zwanzig Zeichen meines vorherigen Pfades da drin.

    Irgendwas läuft da speichertechnisch schief, aber bitte was Oo

    Thx in advance

    Windows XP, Borland Builder 3.



  • Hallo,

    ofn.lpstrFile muss auf einen von dir reservierten Speicher verweisen, und nicht auf einen Platz, der in deinem Falle so liegt, dass andere Bereiche für nicht änderbare Zeichenketten bzw. Daten (in denen z.B. auch "NOD-Dateien\0.nod\0"* abgelegt wird) überschrieben werden. Dabei hast du die Reservierung doch schon gemacht:

    char XFileName[1000];
    

    also was liegt näher, als darauf zu verweisen:

    ofn.lpstrFile = XFileName;
    

    Da GetOpenFileName die Zeichen ab XFileName aber auch schon zur Initialisierung verwenden würde, kann man durch den Zusatz:

    char XFileName[1000] = {0};
    

    dafür sorgen, dass zunächst "nichts" (eine Leerzeichenkette) dort gefunden wird, nach dem Aufruf steht dort der Name der gewählten Datei.

    MfG,

    Probe-Nutzer



  • Der Filter muß mit einer doppel ascii Null geschlossen werden.

    ofn.lpstrFilter ="NOD-Dateien\0*.nod\0\0";
    

    Klar kann man den ganzen String ausnullen, das hat den gleichen Effekt.



  • Hallo,

    papa_multi schrieb:

    Der Filter muß mit einer doppel ascii Null geschlossen werden.

    ofn.lpstrFilter ="NOD-Dateien\0*.nod\0\0";
    

    Klar kann man den ganzen String ausnullen, das hat den gleichen Effekt.

    Müssen muss man hier nicht (drei Nullen stören auch nicht, sind aber reinste Speicherverschwendung 😃 ), der Compiler hängt an das Ende noch ein Nullbyte an, wenn das Ende einer Zeichenkette gefunden wird.

    MfG,

    Probe-Nutzer



  • In der MSDN heißt es dazu:

    lpstrFilter
    Pointer to a buffer containing pairs of null-terminated filter strings. The last string in the buffer must be terminated by two NULL characters.
    The first string in each pair is a display string that describes the filter (for example, "Text Files"), and the second string specifies the filter pattern (for example, ".TXT"). To specify multiple filter patterns for a single display string, use a semicolon to separate the patterns (for example, ".TXT;.DOC;.BAK"). A pattern string can be a combination of valid file name characters and the asterisk (*) wildcard character. Do not include spaces in the pattern string.

    The system does not change the order of the filters. It displays them in the File Types combo box in the order specified in lpstrFilter.

    If lpstrFilter is NULL, the dialog box does not display any filters.



  • Was Probe-Nutzer sagen wollte:

    const char* str = "Hello";
    

    Der Compiler hängt automatisch eine Null dran.
    Jedesmal selbst

    const char* str = "Hello\0";
    

    zu schreiben, wäre auch etwas lästig und fehleranfällig.



  • Moin,

    Das Problem ist, dass wenn ich

    ofn.lpstrFile = XFileName;
    

    mache, sich bei mir das GetOpenFileName mit dem Fehler FNERR_INVALIDFILENAME quer stellt.
    Wenn ich XFileName mit Nullen fülle, schmiert er mir weiter hinten beim Parsen des Strings in einer DLL aus mir unbekannten Gründen ab.

    Krise 😣

    Doppel

    \0
    

    hatte ich vorher drin, aus den von Probe-Nutzern genannten Grund aber wieder entfernt. Daran liegts auch nicht, hab beides getestet.



  • Ok, jetzt bin ich verwirrt.

    Mit einem Dummy

    char ladida[1000]={0};
    

    funktionierts, obwohl ich schwören könnte dass ich das gestern noch ausprobiert habe...

    Jedenfalls thx Probenutzer 🙂


Anmelden zum Antworten