IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Utilisation de GetSaveFileName()


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut Utilisation de GetSaveFileName()
    Bonjour,

    Je programme avec l'API Windows et SDL.
    J'utilise GetOpenFileName() sans souci, mais j'ai un problème avec GetSaveFileName().

    Dans le code ci-dessous (aucun warning) tout se déroule sans problème mais la boîte de sélection de fichiers ne s'ouvre pas.
    Le programme continue sans que rien ne se passe.

    Auriez-vous une idée du problème ?

    Merci d'avance.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
        OPENFILENAME Ofn;
        char szFile[MAX_PATH];
        ZeroMemory(szFile, MAX_PATH);
        char fileTitle[MAX_PATH];
        ZeroMemory(fileTitle, MAX_PATH);
        Ofn.lStructSize = sizeof(Ofn);
        memset(&Ofn, 0, sizeof(Ofn));
        ZeroMemory(&Ofn, sizeof(Ofn));
        Ofn.hwndOwner = NULL;
        Ofn.lpstrFilter = "Image File\0*.bmp\0\0";
        Ofn.lpstrFile=szFile;
        //Ofn.nMaxFile = sizeof(szFile)/ sizeof(*szFile);
        Ofn.nMaxFile = MAX_PATH;
        Ofn.lpstrFileTitle = fileTitle;
        Ofn.nMaxFileTitle = sizeof(fileTitle);
        Ofn.lpstrInitialDir = "C:\\Users\\Alain\\Pictures";
        //Ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
        Ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
        Ofn.lpstrDefExt = (LPSTR)L"bmp";
        Ofn.lpstrTitle = "Save .bmp";
     
        GetSaveFileName(&Ofn);

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Quelle est la valeur de retour de GetSaveFileName(), quelle est la valeur de GetLastError()/CommDlgExtendedError()?

    (aussi, je ne suis pas sûr, mais il est possible qu'il faille appeler CoInitialize() avant usage)


    Aussi, à cette ligne: Ofn.lpstrDefExt = (LPSTR)L"bmp"; le cast est hautement suspect.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    Merci pour ces pistes Médinoc, voici ce que j'obtiens:

    GetSaveFileName = 0
    GetLastError = 87 (The parameter is incorrect.)
    CommDlgExtendedError = 1 (The lStructSize member of the initialization structure for the corresponding common dialog box is invalid.)

    Ceci que j'appelle ou non "CoInitialize(NULL);" avant.

    Cela ne change rien avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ofn.lpstrDefExt = "bmp";

  4. #4
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par nanosoft Voir le message
    Auriez-vous une idée du problème ?
    Mon idée, c'est que c'est le bazar.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        Ofn.lStructSize = sizeof(Ofn);
        memset(&Ofn, 0, sizeof(Ofn));
        ZeroMemory(&Ofn, sizeof(Ofn));
    Après avoir mis deux fois la structure Ofn à zéro, penses-tu vraiment que la valeur Ofn.lStructSize est conservée ? Mon avis est plutôt qu'elle est assez vraisemblablement à zéro.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ofn.lpstrDefExt = (LPSTR)L"bmp";
    Tu mélanges allègrement les chaînes de caractères UNICODE et chaînes de char, tu les cast, ça ne peut que pas marcher.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ofn.lpstrFilter = "Image File\0*.bmp\0\0"
    Le deuxième "\0" est inutile (il est automatiquement ajouté en fin de chaîne littérale).

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par 10_GOTO_10 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ofn.lpstrFilter = "Image File\0*.bmp\0\0"
    Le deuxième "\0" est inutile (il est automatiquement ajouté en fin de chaîne littérale).
    ATTENTION CETTE PARTIE DE TA RÉPONSE EST FAUSSE: lpstrFilter est une liste de paires de chaînes, terminée par deux chaînes vides (et donc, trois caractères nuls consécutifs, dont deux explicites). La chaîne spécifiée est correcte.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    Merci à tous les 2, cela fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        OPENFILENAME Ofn;
        char szFile[MAX_PATH];
        ZeroMemory(szFile, MAX_PATH);
        char fileTitle[MAX_PATH];
        ZeroMemory(fileTitle, MAX_PATH);
     
        memset(&Ofn, 0, sizeof(Ofn));
        Ofn.lStructSize = sizeof(OPENFILENAME);
        Ofn.hwndOwner = NULL;
        Ofn.lpstrFilter = "Image File\0*.bmp\0\0";
        Ofn.lpstrFile=szFile;
        Ofn.nMaxFile = MAX_PATH;
        Ofn.lpstrFileTitle = fileTitle;
        Ofn.nMaxFileTitle = sizeof(fileTitle);
        Ofn.lpstrInitialDir = "C:\\Users\\Alain\\Pictures";
        Ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
        Ofn.lpstrDefExt = "bmp";
        Ofn.lpstrTitle = "Save .bmp";
     
        int retour_GSFN = GetSaveFileName(&Ofn);

  7. #7
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    ATTENTION CETTE PARTIE DE TA RÉPONSE EST FAUSSE: lpstrFilter est une liste de paires de chaînes, terminée par deux chaînes vides (et donc, trois caractères nuls consécutifs, dont deux explicites). La chaîne spécifiée est correcte.
    Mmmmmhh... Pas convaincu.

    Si on regarde la doc MSDN de OPENFILENAME on y lit :

    The last string in the buffer must be terminated by two NULL characters.
    Deux, donc pas trois... Mais juste en dessous il y a un exemple, et ils en mettent deux explicites, plus un implicite :


    To retrieve a shortcut's target without filtering, use the string "All Files\0*.*\0\0"
    En cherchant d'autres sources

    This is the correct code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lofn.lpstrFilter = L"Equalizer Preset (*.feq)\0*.feq\0";
    Le mieux, c'est d'essayer. J'ai donc fait le test avec juste deux zéros et du texte après:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ofn.lpstrFilter = "Image File\0*.bmp\0\0*.*\0\0";
    Et je n'ai bien qu'une seule ligne de filtre. Je suis donc assez convaincu que deux \0 suffisent (un explicite et un implicite).

    Après, dans la mesure où la doc n'est pas très claire, je te conseille quand même d'en mettre explicitement deux. Le code est plus lisible et en général on n'est pas à un octet gaspillé près.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    En effet, ce n'est pas aussi clair que je le croyais, je me demande pourquoi j'en étais aussi certain (je me suis probablement brûlé dessus une fois).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/12/2009, 17h40
  2. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo