|
[Win API] Un carnet d'adresses
|
| Auteur |
Message |
Toam
Junior Member
 
Messages : 36
Groupe : Membres
Inscription : Nov 2006
Statut :
Hors ligne
Réputation : 0
|
je me permet 
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).
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:
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)
|
|
| 12/12/2006 09:18 |
|
 |
coca25
Junior Member
 
Messages : 20
Groupe : Membres
Inscription : Nov 2006
Statut :
Hors ligne
Réputation : 0
|
pour participer un peu 
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
|
|
| 12/12/2006 11:26 |
|
 |
acryline
Member
  
Messages : 68
Groupe : Membres
Inscription : Dec 2006
Statut :
Hors ligne
Réputation : 2
|
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 ...
|
|
| 12/12/2006 13:27 |
|
 |
Toam
Junior Member
 
Messages : 36
Groupe : Membres
Inscription : Nov 2006
Statut :
Hors ligne
Réputation : 0
|
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 .
Dans ton programme ce n'est pas :
strncat(carnet,"\carnets\carnet.adr",max_path);
mais
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.
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.
|
|
| 12/12/2006 13:52 |
|
 |
acryline
Member
  
Messages : 68
Groupe : Membres
Inscription : Dec 2006
Statut :
Hors ligne
Réputation : 2
|
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)

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)
//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
|
|
| 13/12/2006 08:54 |
|
 |
coca25
Junior Member
 
Messages : 20
Groupe : Membres
Inscription : Nov 2006
Statut :
Hors ligne
Réputation : 0
|
remarque sans rapport direct avec la programmation.
les sous-menu aide et à propos ont le même raccourcis 'a'
|
|
| 13/12/2006 11:26 |
|
 |
acryline
Member
  
Messages : 68
Groupe : Membres
Inscription : Dec 2006
Statut :
Hors ligne
Réputation : 2
|
Ah oui ! mince...encore un truc à modifier
|
|
| 13/12/2006 11:47 |
|
 |
acryline
Member
  
Messages : 68
Groupe : Membres
Inscription : Dec 2006
Statut :
Hors ligne
Réputation : 2
|
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 il manque WM_HANDLE)

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 :
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
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 :
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 :
//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
|
|
| 14/12/2006 06:40 |
|
 |
Toam
Junior Member
 
Messages : 36
Groupe : Membres
Inscription : Nov 2006
Statut :
Hors ligne
Réputation : 0
|
sans rentrer dans tous les détails ...
Voici une petite synthèse de ce que l'on peut faire dans les deux langages.
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
|
|
| 14/12/2006 10:03 |
|
 |
acryline
Member
  
Messages : 68
Groupe : Membres
Inscription : Dec 2006
Statut :
Hors ligne
Réputation : 2
|
Merci Toam ! 
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 :
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 :
bool creerfonctiontemoins(hwnd hwnd,hwnd *hwndfille, temoins temoins, wparam wparam)
puisque je retourne TRUE et FALSE...  C'est cela ?
|
|
| 15/12/2006 09:08 |
|
 |
|
|