Oeffnen-Dialog erscheint nicht



  • also erstens:

    es wäre wesentlich übersichtlicher gewesen, wenn du nur gepostet hättest, worauf es ankommt:

    // ...
    OPENFILENAME ofn;       // common dialog box structure
    char szFile[260];       // buffer for file name
    HWND hwnd;              // owner window
    HANDLE hf;              // file handle
    
    // Initialize OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwnd;
    ofn.lpstrFile = szFile;
    //
    // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
    // use the contents of szFile to initialize itself.
    //
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(szFile);
    ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    
    // Display the Open dialog box. 
    
    if (GetOpenFileName(&ofn)==TRUE) 
        hf = CreateFile(ofn.lpstrFile, GENERIC_READ,
            0, (LPSECURITY_ATTRIBUTES) NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
            (HANDLE) NULL);
    // ...
    

    zweitens:
    wer ab und zu in die MSDN guckt, weiß, dass OFN_FILEMUSTEXIST OFN_PATHMUSTEXIST beinhaltet.
    also ist das OFN_PATHMUSTEXIST sinnlos.

    und drittens (das wichtigste zum Schluss^^):
    Microsoft lässt dir die Möglichkeit ein eigenes Dialogtemplate zu nutzen.
    also mache Windows erst klar, dass du den Standard-Dialog willst.
    ich mach das immer so:

    // ...
    			OPENFILENAME ofn;
    			ofn.dwReserved = 0;
    			ofn.Flags = OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_LONGNAMES;
    			ofn.FlagsEx = 0;
    			ofn.hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWL_HINSTANCE);
    			ofn.hwndOwner = g_hFrameWnd;
    			ofn.lCustData = NULL;
    			ofn.lpfnHook = 0;
    			ofn.lpstrCustomFilter = NULL;
    			ofn.lpstrDefExt = "TXT";
    			PFileName pFN = (PFileName)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    			char szFileName[MAX_PATH];
    			if (pFN != NULL)
    				strncpy_s(szFileName, MAX_PATH, pFN->szFileName, MAX_PATH);
    			else
    				szFileName[0] = '\0';
    			ofn.lpstrFile = szFileName;
    			ofn.lpstrFileTitle = NULL;
    			ofn.lpstrFilter = "Textdateien (*.txt)\0*.txt\0Alle Dateien\0*.*\0\0";
    			ofn.lpstrInitialDir = NULL;
    			ofn.lpstrTitle = NULL;
    			ofn.lpTemplateName = NULL;
    			ofn.lStructSize = sizeof(OPENFILENAME);
    			ofn.nFileExtension = 0;
    			ofn.nFileOffset = 0;
    			ofn.nFilterIndex = 0;
    			ofn.nMaxCustFilter = 0;
    			ofn.nMaxFile = MAX_PATH;
    			ofn.nMaxFileTitle = 0;
    			ofn.pvReserved = NULL;
    			if (GetOpenFileName(&ofn) != FALSE)
    // ...
    

    das stammt aus einem Texteditor mit MDI von mir.

    da fällt mir gleich noch was auf:
    man überprüft NIE, ob etwas gleich TRUE ist.
    denn FALSE wird IMMER als 0 definiert.
    TRUE ist jedoch != 0 und damit undefiniert.
    Es ist somit dem Compilerhersteller, oder bei der WinAPI Microsoft überlassen, welchen Wert TRUE hat.
    Wenn man aber überprüft, ob etwas ungleich FALSE ist, so ist man immer auf der sicheren Seite.

    MfG DrakoXP

    PS.:
    merker muss ich auch Recht geben.
    lass das

    HWND hwnd;
    

    weg und schreib

    ofn.hwndOwner = hWnd;
    

    denn das Handle bekommst du ja als Parameter und somit brauchst du nicht extra eine neue Handle-Variable deklarieren, die nichtmal einen definierten Wert besitzt.



  • Ach so! Danke!
    Lustigerweise ist der Ausschnitt aus der MSDN.



  • DrakoXP schrieb:

    da fällt mir gleich noch was auf:
    man überprüft NIE, ob etwas gleich TRUE ist.
    denn FALSE wird IMMER als 0 definiert.
    TRUE ist jedoch != 0 und damit undefiniert.
    Es ist somit dem Compilerhersteller, oder bei der WinAPI Microsoft überlassen, welchen Wert TRUE hat.
    Wenn man aber überprüft, ob etwas ungleich FALSE ist, so ist man immer auf der sicheren Seite.

    Nicht wirklich, oder? Das kann doch nicht sein, dass die solche Fallen einbauen.



  • naja, soweit ich weiß, definiert Microsoft TRUE als -1, aber sicher ist halt sicher.

    denn wenn du in der MSDN liest, z.B. bei

    BOOL UpdateWindow(
      HWND hWnd   // handle to window
    );
    

    dann liest man da:
    If the function succeeds, the return value is nonzero.
    If the function fails, the return value is zero.

    und nonzero heißt bei mir ungleich 0 und nicht -1.
    also lieber mit FALSE überprüfen, anstatt mit TRUE.



  • DrakoXP schrieb:

    also lieber mit FALSE überprüfen, anstatt mit TRUE.

    Man sollte IMHO diese Konstanten in bool-Ausdrücken gar nicht benutzen.

    if( foo == TRUE )
    

    ist genauso überflüssig wie

    if( foo != FALSE )
    

    Einfach nur:

    if( foo )
    

    -> Fertig.



  • ähm, vielleicht hast du übersehen, dass es keine bool-Ausdrücke sind,
    sondern BOOL-Ausdrücke, und BOOL ist von Microsoft als int definiert.

    deshalb kann man BOOL auch nich einfach zu bool casten.
    jedenfalls nicht ohne den Hinweis auf einen Datenverlust...



  • DrakoXP schrieb:

    ähm, vielleicht hast du übersehen, dass es keine bool-Ausdrücke sind,
    sondern BOOL-Ausdrücke, und BOOL ist von Microsoft als int definiert.

    Nein, das habe ich nicht übersehen.

    deshalb kann man BOOL auch nich einfach zu bool casten.
    jedenfalls nicht ohne den Hinweis auf einen Datenverlust...

    Die Verwendung eines int-Ausdrucks in einer if-Anweisung erzeugt bei keinem mir bekannten Compiler einen "Hinweis auf einen Datenverlust". Hast du ein Beispiel?



  • ja, in diesem Fall geht es^^

    der Hinweis sollte kommen bei bei

    BOOL x = TRUE;
    bool y = (bool)x;
    

    im Endeffekt geht das trotzdem, aber halt Warnung...


  • Mod

    Nein! Auch in diesem Fall kommt keine Warnung. Denn Du führst einen cast aus. Un der cast von int auf bool ürt nichts anderes aus als ein das Ergebnis von x!=0 zu setzen.

    Eine Warnung kommt nur, wenn Du du Zuweisung ohne cast ausführst.



  • Martin Richter schrieb:

    Eine Warnung kommt nur, wenn Du du Zuweisung ohne cast ausführst.

    C4800 kommt auch bei einem Cast:

    MSDN Library schrieb:

    Casting the expression to type bool will not disable the warning, which is by design.


  • Mod

    Upps...
    Ja es kommt eine Warnung, aberist ist keine Warnung über Datenverlust! Es ist eine Performance Warnung!

    Aber Ok! Ganz korrekt war meine Antwort nicht.

    Dann ist der korrekte Weg einzig und alleine

    BOOL x = TRUE;
    bool y = x!=0;
    


  • Jedenfalls funktioniert es bei mir nun ordentlich; wegen der Prüfung, müsste mal jedes Szenario ausprobieren.
    Gibt es eine andere Möglichkeit auf den Dateinamen zuzugreifen als ofn.lpstrFile ?

    Vielen Dank


  • Mod

    Was meinst Du mit andere Möglichkeiten?



  • Anstelle z.B. MessageBox (ofn.lp..... ...) den namen in einem normalen Char oder string zu haben


  • Mod

    lpstrFile ist ein normaler TCHAR*, was möchtest Du mehr?



  • Ja ein Zeiger oder irre ich mich da? Den Wert in einrm "normalen" char, nicht als Zeiger



  • APIAnfaenger schrieb:

    Ja ein Zeiger oder irre ich mich da? Den Wert in einrm "normalen" char, nicht als Zeiger

    Es ist ein Zeiger! TCHAR ist entweder char oder wchar_t je nach Zeichensatz.
    BTW:

    DrakoXP schrieb:

    TRUE ist jedoch != 0 und damit undefiniert.

    Natürlich ist TRUE definiert und zwar als 1 -sinnigerweise.

    DrakoXP schrieb:

    Es ist somit dem Compilerhersteller, oder bei der WinAPI Microsoft überlassen, welchen Wert TRUE hat.

    Ein Compilerhersteller hat damit wenig zu tun, da diese nicht im Compiler (bzw. in der entsprechenden Sprache) verankert sind, im Gegensatz zu (bspw.) true oder false. Damit ist es also nur Microsoft überlassen, welchen Wert diese Konstanten wirklich haben, und der steht in den Headern.
    q.e.d.:

    windef.h [WinApi-Standardheader] schrieb:

    // ...

    #ifndef FALSE
    #define FALSE               0
    #endif
    
    #ifndef TRUE
    #define TRUE                1
    #endif
    

    // ...


  • Mod

    Soweit ich den Standard im Kopf habe ist das Ergebnis von 1==1 definiert als true, 1!=0 als false. Weißt man ein boolsches Ergebnis einer int Variable zu ist dies definiert als 1 oder 0.

    Richtig ist, dass die interne Darstellung eines bool Datatypes dem Compilerhersteller überlassen ist.
    Die Zuweisung in einen int ist keineswegs undefiniert.
    Insofern ist es nur zu logisch 0 als FALSE und 1 als TRUE zu definieren.

    Unterscheiden muss man dennoch die Nutzung des Datentypes BOOL in der WinAPI. Hier gilt nur folgendes hat ein BOOL Typ den Wert 0, heißt dies false. !=0 bedeutet false. Man kann aber eben nicht mit Sicherheit sagen, dass TRUE returniert wird. Die Ergebnisse 5, 1234 und so weiter würden ebenfalls true signalisieren.
    Der Vergleich eines BOOL Wertes mit TRUE führt also nicht unbedingt zum gewünschten Ergebnis. Der Vergleich eines BOOL Wertes mit FALSE dagegen schon...

    Ich hoffe das ist verständlich.



  • Martin Richter schrieb:

    [...]
    Ich hoffe das ist verständlich.

    Joar klaro 😉 . Damit sollte man damit doch auf der richtigen Seite sein:

    BOOL bSuccess = IrgendEineFunktionDieBOOLZurueckGibt();
    if(bSuccess)
      // Erfolgreich...
    else
      // Aua...
    

    (Bereits von MFK gepostet; diese Prüfung bevorzuge ich nämlich auch.)


  • Mod

    Und man kann es auch wirklich wörtlich einfach lesen...

    if (bSuccess) // Wenn erfolgreich
    ...
    if (!bSuccess) // Wenn nicht erfolgreich
    ...
    

    alle != und == Operatoren an dieser Stelle empfinde ich persönlich als verwirrend.


Anmelden zum Antworten