Forum de la C-P-F

Version complète: [Win API] Un carnet d'adresses
Vous regardez actuellement la version basse qualité d'un document. Voir la version complète avec le bon formatage.
je me permet Wink

Code CPP :
strncat(carnet,"\carnets\carnet.adr",max_path);

si comme 3ã¨me paramã¨tres tu mets max_path, c'est que tu n'en as pas besoin ... strncat te permet de concatener des chaines de caractã¨res qui ne seraient pas forcement terminã©es par un '0'. ici ta chaine se termine bien par un '0', donc autant faire court. (le 3ã¨me paramã¨tre n'ã©tant pas le nombre de caractã¨res de la chaine finale, mais le le nombre de caractã¨res maximum ã  concatã©ner si on ne rencontre pas le caractã¨re null avant).
Code CPP :
strcat(carnet,"\carnets\carnet.adr");


y'a un petit dã©tail que je n'aime pas tellement non plus c'est que ta fonction creerfichierconfig crã©e le fichier puis renvoie le pointeur ã  la fonction appelante. du coup elle oblige l'appelant ã  fermer le fichier. dans ton cas c'est ton choix car tu souhaites consulter le fichier aprã¨s l'avoir crã©ã© et initialisã© sans le rã©-ouvrir.

moi je prã©fã¨re tester la prã©sence du fichier et ses droits avec par exemple la fonction:
Code CPP :
int _access( const char *path, int mode );

Si le fichier n'existe pas alors on le crée, on l'initialise puis on le ferme.
Ensuite tu fais le traitement de chargement de configuration. Cela te permet de n'avoir aucune dépendance entre ces 2 fonctions et de pouvoir les réutiliser où bon te semble.

Voilà, mais ce ne sont que des méthodes différentes pour aboutir au même résultat, et il n'y a pas de meilleur méthode, il n'y a que celle qu'on maitrise (enfin tant qu'on travaille tout seul ;D)
pour participer un peu Smile

dans la même lignée du strncat, j'irai plus loin, étant donné que les chemins sont écrits en dur dans le programme, il serait peut être préférable de les placer dans des constantes facilement identifiables et carrément initialiser les variables avec les constantes (si ces variables vont êtres modifiées par la suite) ou utiliser les constantes.

mais comme dit toam, ce ne sont que des méthodes différentes
Toam :

pour la dépendance entre les deux fonctions, effectivement j'y avais penser, c'est pas très net. Je n'ai pas encore tjrs de très bons reflexes.
Très utile : int _access( const char *path, int mode ); Merci !

Sinon pour strncat, j'ai toujours lu que cette fonction était plus sûre que strcat. D'ailleurs qq fois Visual signale une erreur quand on utilise strcat au l ieu de strncat. Pourquoi ?

coca25 : ok pour l'adresse de carnet.config qui ne va pas changer, mais comme dans le carnet d'adresse on pourra ouvrir n'importe quel carnet d'adresse ou en créer à volonté, on ne peut pas mettre cette adresse dans une cste. En revanche très bonne idée pour carnet.config, ça évite de toujours l'écrire à la fin ça prend la tête ... Smile

acryline a écrit :
Sinon pour strncat, j'ai toujours lu que cette fonction était plus sûre que strcat.

Effectivement, il vaut mieux toujours savoir ce que l'on manipule et strncat est plus sûre que strcat. Mais dans ce cas, il faut l'appeler comme il faut Wink.
Dans ton programme ce n'est pas :

Code C :
strncat(carnet,"\carnets\carnet.adr",max_path);

mais
Code C :
strncat(carnet,"\carnets\carnet.adr",strlen("\carnets\carnet.adr"));

Dans l'absolu, il faut même vérifier que la chaine résultante est suffisamment grande pour accueillir le résultat voulu. Il faudrait donc vérifier que la taille allouer pour carnet moins la taille déjà contenu est inférieur à la taille de la chaine que tu vas ajouter. Sans tous ces contrôles, la strncat n'est absolument pas plus sûre que strcat.

acryline a écrit :
D'ailleurs qq fois Visual signale une erreur quand on utilise strcat au l ieu de strncat. Pourquoi ?

Aucune idée, je n'ai jamais ce genre de problème, si tu as le message ça m'intéresse.

Merci pour les explications. Pour le message d'erreur, comme je n'utilise plus Visual depuis pas mal de temps, je ne peux pas le trouver comme ça rapidement. Mais le logiciel est encore installé sup mon pc, je vais essayer de le trouver plus tard.

Voici la fonction d'aujourd'hui : leMenu (bon elle est toute simple)



Code C :

void lemenu (hmenu *hsousmenu)
{

hsousmenu[0] = createmenu();
    appendmenu(hsousmenu[0], mf_string, idm_nouveau, (lpctstr)"&nouveau");
    appendmenu(hsousmenu[0], mf_string, idm_ouvrir, (lpctstr)"&ouvrir");
    appendmenu(hsousmenu[0], mf_separator, 0, null);
    appendmenu(hsousmenu[0], mf_string, idm_quitter, (lpctstr)"&quitter");

hsousmenu[1] = createmenu();
    appendmenu(hsousmenu[1], mf_string, idm_nouvellefiche, (lpctstr)"&nouvelle fiche");
    appendmenu(hsousmenu[1], mf_grayed, idm_retour, (lpctstr)"&retour au rã©pertoire");

hsousmenu[2] = createmenu();
    appendmenu(hsousmenu[2], mf_string, idm_aide, (lpctstr)"&aide");
    appendmenu(hsousmenu[2], mf_string, idm_apropos, (lpctstr)"&a propos de...");

hsousmenu[3] = createmenu();
    appendmenu(hsousmenu[3] ,mf_popup,(uint_ptr)hsousmenu[0],(lpctstr)"fichier");
    appendmenu(hsousmenu[3] ,mf_popup,(uint_ptr)hsousmenu[1],(lpctstr)"rã©pertoire");
    appendmenu(hsousmenu[3] ,mf_popup,idm_options,(lpctstr)"affichage");
    appendmenu(hsousmenu[3] ,mf_popup,(uint_ptr)hsousmenu[2],(lpctstr)"?");
}

 


dans le fichier header on dã©finit les identifiants des options du menu comme ceci : (ce n'est q'un extrait de fonctions.h)

Code C :

//menu

#define idm_quitter             1001
#define idm_nouveau             1002
#define idm_ouvrir              1003
#define idm_nouvellefiche       1004
#define idm_retour              1005
#define idm_aide                1006
#define idm_apropos             1007
#define idm_options             1008
 
remarque sans rapport direct avec la programmation.
les sous-menu aide et à propos ont le même raccourcis 'a'
Ah oui ! mince...encore un truc à modifier Smile
Voci la fonction du jour ! Celle ci est très importante, c'est la procédure de la fenêtre principale. C'est dans cette fonction qu'on récupère les messages envoyés à la fenêtre ( par la souris, le clavier, le programme lui même, l'ordinateur pendant ou après une action etc...) et qu'on les traite.

Voici l'organigramme Sadil manque WM_HANDLE)


Code C :

lresult callback  procedure(hwnd hwnd, uint umsg, wparam wparam, lparam lparam)
{
    static temoins temoins={true,false,false};
    static hwnd hwndfille[4]={0}, hwndcouv=null;

  switch (umsg)
    {
       
        case wm_create: // ã  la crã©ation de la fenãªtre
            creerfonctiontemoins(hwnd,hwndfille, temoins,wparam);
        return 0;

//ã  la reception d'un message provenant du menu, d'une fenãªtre "enfant" ou d'un accã©lã©rateur
        case wm_command:
            messagesmenu (hwnd,hwndcouv,wparam,lparam);
        return 0;

//ã  la reception du message  crã©ã© pour envoyer l'ã©tat des tã©moins
        case wm_temoins:
            etattemoins(wparam,lparam,&temoins);
        return 0;

//quand on clique sur le bouton de fermeture de la fenãªtre
        case wm_close:
        destroywindow(hwnd);
        return 0;

// ã  la reception d'un message crã©ã©
        case wm_handle:
        if(lparam==0) hwndcouv=(hwnd)wparam;
        return 0;

// ã  la reception du message "dã©truire la fenãªtre"
        case wm_destroy:
       fermeapplication(hwnd);
        return 0;

//si le traitement du message n'a  pas ã©tã© prã©vu.
        default:
        return defwindowproc(hwnd, umsg, wparam, lparam);

    }

}


 

temoins est une structure que j'ai crã©ã©e et que j'utilise pour montrer quelle fenãªtre fille est ouverte.
cette structure est dã©finie dans fonctions.h ainsi :

Code C :

typedef struct temoins temoins;
    struct temoins
    {
    bool couv;
    bool liste;
    bool fiche;
    };
 


;d je dã©clare mes structures comme ã§a, et vu que ã§a marche je n'ai pas vraiment ã©tã© chercher plus loin.
il faudrait que je relise un ou deux tuto pour "resaisir" la signification de cette prã©sentation ou qu'une ame
charitable fasse un mini- tuto ci-dessous Wink

autrement, pour la procã©dure elle mãªme, ici on voit bien que pour chaque message reã§u (wm_create, wm-paint, wm_command etc... avec wm=window message) il y a une rã©ponse appropriã©e.

wm_message et wm_handle sont des messages crã©ã©s pour l'application, on les dã©finit dans "fonctions.h" ã©galement. on les utilise
pour passer des donnã©es d'une procã©dure ã  une autre. ces donnã©es sont passã©es dans les paramã¨tres wparam et lparam du
message. pour envoyer un message ã  une procã©dure on utilise la fonction sendmessage dont la syntaxe est :
Code C :

lresult sendmessage(     
  //handle de la fenãªtre ã  qui on envoit le message (la difficultã© est d'avoir ce handle  <img src="http://www.c-p-f.org/forum/images/smilies/smile.gif" style="vertical-align: middle;" border="0" alt="Smile" title="Smile" /> )
    hwnd hwnd,           
  // message
    uint msg,                 
 //paramã¨tre avec ce que vous voulez dedans si le message a ã©tã© crã©ã©
   wparam wparam,
    lparam lparam
);
 

voici tous les messages crã©ã©s pour ce programme dans fonctions.h :
Code C :


//messages
#define wm_temoins     wm_app+1
#define wm_couleur     wm_app+2
#define wm_handle      wm_app+3
#define wm_creer       wm_app+4
 
sans rentrer dans tous les détails ...
Voici une petite synthèse de ce que l'on peut faire dans les deux langages.
Code CPP :

struct st1{int a;};              //st1 est un type
typedef st1 st1,*p_st1;          //st1 est un alias sur "struct st1", p_st1 est un alias sur "struct st1*"
struct {int a;} mast2;           //mast2 est un objet, aucun autre objet de ce type ne peut etre cree
typedef struct {int a;} st3;     //st3 est un alias sur un type non taggue
typedef struct _st4 {int a;} st4;//_st4 est un type, st4 est un alias sur "struct _st4"
struct _st5{int a;} st5;         //_st5 est un type, st5 est un objet

int main()
{
        st1 mast1_cpp;         // uniquement c++, creation d'un objet st1
        mast1_cpp.a=0;
        struct st1 mast1_c;    // c/c++, creation d'un objet st1
        mast1_c.a=0;
        st1 var_mast1;         // c/c++, creation d'un objet st1
        var_mast1.a=0;
        p_st1 pointeurst1=null;// c/c++, pointeur vers un objet st1
        pointeurst1=(p_st1)malloc(sizeof(st1));
        pointeurst1->a=0;
        mast2.a=0;             // utilisation direct en c/c++
        st3 mast3;             // c/c++, creation d'un objet st3
        mast3.a=0;
        st4 mast4_1;           // c/c++, creation d'un objet st4
        mast4_1.a=0;
        struct _st4 mast4_2;   // c/c++, creation d'un objet st4
        mast4_2.a=0;
        _st5 mast5_cpp;        // uniquement c++, creation d'un objet _st5
        mast5_cpp.a=0;
        struct _st5 mast5_c;   // c/c++, creation d'un objet st5
        mast5_c.a=0;
        st5.a=0;               // utilisation direct en c/c++
       
        return 0;
}
 


en espérant ne pas avoir écrit de bêtise ;D
Merci Toam ! Smile

Aujourd'hui je vais vous présenter ma fonction creerFonctionTemoins. Cette fonction répond au message WM_CREATE envoyé à la fenêtre parent. Ainsi quand la fenêtre parent est créée ou quand on envoie le message WM_CREATE à la procédure de la fenêtre parent, l'application créer la fenêtre fille qui correspond à l'état de la structure TEMOINS du moment.

Pour chaque fenêtre fille créée il faudra écrire une procédure.

Organigramme :



Et le code :
Code C :

void creerfonctiontemoins(hwnd hwnd,hwnd *hwndfille, temoins temoins, wparam wparam)
{

  if (temoins.couv==true)
  {
      creerafficherfenetrefille (hwnd,hwndfille,0,"classecouv",proccouv,-1);
   // rã©actualisation de la fenãªtre->la fenãªtre fille s'affiche dans la fenãªtre parent.
      updatewindow(hwndfille[0]);
      return true;
  }

  if (temoins.liste==true)
  {
      /*le dernier paramã¨tre de la fonction sera utilisã© pour afficher les onglets c'est le
      numã©ro de l'onglet sã©lectionnã© (lettres de a ã  z ) qui est passã© dans la paramã¨tre wparam
       du message wm_create*/

      creerafficherfenetrefille (hwnd,hwndfille,1,"classeliste",procliste, (long)wparam);
      updatewindow(hwndfille[1]);
      return true;
  }

  if (temoins.fiche==true)
  {
      creerafficherfenetrefille (hwnd,hwndfille,2,"classefiche",procfiche,-1);
      updatewindow(hwndfille[2]);
      return true;
  }

  return false;
}

 


c'est le code tel qu'il etait au moment del a compilation du programme qui est en ligne.
j'aurais sans doute du ã©crire :

Code C :

bool creerfonctiontemoins(hwnd hwnd,hwnd *hwndfille, temoins temoins, wparam wparam)
 

puisque je retourne TRUE et FALSE... Smile C'est cela ?
Pages: 1 2 3 4 5 6 7
URLs de référence