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.
Aujourd'hui, avant de commencer à vous présenter le reste du menu je vais parler de la fonction
etatTemoins, c'est la seule fonction qui n'a pa été traitée dans la procédure principale.
Elle est appelée quand cette procédure reçoit le message WM_TEMOINS qui a été créé pour
l'application. De ce message dépend la création de telle ou telle fenêtre fille.


Code C :

void etattemoins(wparam wparam,lparam lparam,temoins *temoins)
{
    if (wparam==0) temoins->couv=lparam;
    if (wparam==1) temoins->liste=lparam;
    if (wparam==2) temoins->fiche=lparam;

}
 


Comme vous pouvez voir dans l'organigramme de la fonction, on peut créer facilement une fenêtre fille supplémentaire pour
l'application (c'est prévu pour Wink ). Pour cela il suffit d'ajouter un membre à la structure TEMOINS, une ligne à cette fonction, mettre 4 à la place de 3 dans modifierTemoins et enfin créer la nouvelle fenêtre, sa procédure répondre aux messages que l'application lui envoie... simple non ? Smile
Biensur il faudra prévoir une nouvelle option dans le menu et remplir le nouveau membre de la structure.
Bonjour,
Aujourd'hui je vais commencer à parler de la fenêtre de configuration du programme qui s'ouvre dans le
menu en cliquant sur "Affichage". Cette fenêtre est une boite de dialogue qui contient deux fenêtres qui s'ouvent
chacune avec un onglet (comme dans un classeur).

Patit rappel :
dans la fonction de traitement des messages du menu messagesMenu le cas où l'utilisateur presse sur
l'option "Affichage" est traité comme ceci :
Code C :

            case idm_options :
            dialogbox(hinstance, "dialog3" , hwnd, (dlgproc)dialog3proc);
            sendmessage(findwindow ("dialog","dialog3"),wm_handle,hwndcouv,0);
            break;
 


voici le code du fichier ressource du programme, où apparait les boites de dialogues ressources.

Code C :

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include "fonctions.h"

personne bitmap "personne.bmp"
icone1 icon "bonnet.ico"

dialog1 dialog
   10, 10, 160, 120
          style ws_popup | ws_visible | ws_caption | ws_sysmenu
                                        caption "crã©er un nouveau carnet d'adresses "
begin
    defpushbutton "ok", id_ok, 56, 55, 42, 12
    ltext "nom du nouveau carnet :", -1, 10, 15, 90, 10
    edittext ide_edit1, 45, 30, 60, 12,es_left | ws_border | ws_tabstop
    ltext "caractã¨res permis :", -1, 10, 70, 90, 10
    ltext "abcdefghijklmnopqrstuvwxyz", -1, 10, 80, 150, 10
    ltext "abcdefghijklmnopqrstuvwxyz", -1, 10, 90, 150, 10
    ltext "0123456789_", -1, 10, 100, 150, 10
end

dialog2 dialog
   10, 10, 160, 120
          style ws_popup | ws_visible | ws_caption | ws_sysmenu
                                        caption "a propos du carnet d'adresses "
begin
    ltext "carnet d'adresses 0.0.1", -1, 10, 10, 150, 10
    ltext "© acryline", -1, 10, 20, 150, 10
    ltext "ce programme est fourni sans aucune garantie comme prã©vu par la loi.", -1, 10, 35, 150, 50
    ltext "vous pouvez le redistribuer selon les termes de la licence publique gã©nã©rale gnu.", -1, 10, 60, 150, 50
    defpushbutton "ok", id_ok, 56, 95, 42, 12
end
<strong>
dialog3 dialog
   10, 10, 200, 180
          style ws_popup | ws_visible | ws_caption | ws_sysmenu
                                        caption "affichage "
begin</strong>

end


 


ici nous allons utiliser la boite de dialogue dialog3. cette fenãªtre a une procã©dure que voici :


tout d'abord voici une nouvelle structure que j'ai dã©finie dans le header :
Code C :

typedef struct config config;
    struct config
    {
    char largeur[5];
    char hauteur[5];
    colorref couleur[6];
    char adresse [max_path];
    };
 


j'ai eu du mal avec cette partie du programme, j'apprenais en faisant... donc le code ne correspond pas exactement ã  l'organigramme :

Code C :

bool apientry dialog3proc(hwnd hdlg,uint umsg,wparam wparam,lparam lparam)
{
   static  hwnd hwndonglet1=null, hwndonglet2=null, hboutonok=null, hboutonan=null;
   static hwnd htabs=null,hwndcouv=null;
   static config data, *p_data;
    switch (umsg)
    {
      case wm_initdialog: // ici au je n'ai pas crã©ã© de fonction, le code est placã© directement dans la procã©dure
      {
        tcitem tie;
       //charger la configuration actuelle.
        structureconfig ( &data);

        initcommoncontrols();
        htabs = createwindowex(0 , wc_tabcontrol, "", ws_child | ws_visible,
                                     10, 10, 380, 300,hdlg, null, hinstance, null);
        tie.mask = tcif_text;

        tie.psztext = "couverture";
        tabctrl_insertitem(htabs, 1, &tie);

        tie.psztext = "fiches";
        tabctrl_insertitem(htabs, 2, &tie);
        hwndonglet1=onglet1(htabs); //fonction pour crã©er la premiere fenãªtre onglet
        hwndonglet2=onglet2(htabs); //fonction pour crã©er la seconde fenãªtre onglet
        sendmessage (hwndonglet1,wm_couleur,&data,hdlg);
        sendmessage (hwndonglet2,wm_couleur,&data,hdlg);

        showwindow(hwndonglet1,sw_show);

      //deux boutons au bas de la boite de dialogue : ok et annuler.
        hboutonok=createwindow("button","ok",ws_child|ws_visible | bs_pushbutton ,
                                        120,330,80,20,hdlg,null,hinstance,null);
        hboutonan=createwindow("button","annuler",ws_child|ws_visible | bs_pushbutton ,
                                        220,330,80,20,hdlg,null,hinstance,null);

        return true;
      }
      case wm_command:
      messagestab (hdlg,wparam,lparam,&data);
      invalidaterect(hwndcouv,null,true);

      return true;

      case wm_notify: // pour passer d'une fenãªtre ã  l'autre en pressant sur les onglets
          {
             lpnmhdr pnmhdr = (lpnmhdr)lparam  ;
        if(pnmhdr->code == tcn_selchanging && tabctrl_getcursel(htabs) == 1)
              {
                showwindow(hwndonglet2,sw_hide);
                showwindow(hwndonglet1,sw_show);
              }
        if(pnmhdr->code == tcn_selchanging && tabctrl_getcursel(htabs) == 0)
              {
              showwindow(hwndonglet1,sw_hide);
              showwindow(hwndonglet2,sw_show);
              }
      return true;
          }

     case wm_couleur: //envoie du message wm_couleur aux procã©dures des fenãªtres ã  onglet
        p_data=wparam;
        data=*p_data;
        sendmessage (hwndonglet1,wm_couleur,&data,hdlg);
        sendmessage (hwndonglet2,wm_couleur,&data,hdlg);
     return true;

     case wm_handle: // pour rã©cupã©rer le handle de la couverture.
     if (lparam==0) hwndcouv= (hwnd)wparam;
     return true;

      case wm_close:
       enddialog(hdlg,0);
       return true;

        default:
        return false;
    }
}

 
Bonsoir,
Chaque jour je vien pr voir ce topic marlger que je m'etrise pas le C encore (ces moments je debute avec le php piusque il est proche dans la syntaxe avec le C qui es mon but !) et permez moi de vous annoncer,que j'aime bcq votre methodologie de travail,j'essai d'apprendre un peu Smile
Bonjour !
Hé bien je suis contente que cette présentation te soit utile Learner ! Et merci pour ton message d'encouragement.
Aujourd'hui je vais poursuivre la présentation de ma boite de dialogue à onglets.

Dans la procédure que j'ai mise en ligne hier, les réponses à 6 messages différents sont envisagées. Voyons le message
WM_INITDIALOG. Ce message est envoyé à la procédure juste avant que la fenêtre soit affichée. Donc c'est à la reception
de ce message qu'on pourra modifier l'apparence de la boite de dialogue. Ici on va créer les deux fenêtres filles des deux onglets.
On pourrait en créer d'autres bien sur.

Voici les différentes étapes de la réponse au message WM_INITDIALOG:
- charger les données (couleurs, dimensions, adresse) de l'application avec structureConfig
- créer le contrôle WC_TABCONTROL qui va permettre la présentation des pages à l'aide d'onglets comme dans un classeur.
- remplir la struture TCITEM pour recevoir les attributs des pages (items) que l'on va inserrer dans le classeur.
- inserrer les pages dans le classeur (créer une place dans le classeur).
- créer les deux pages du classeur
Code C :

        hwndonglet1=onglet1(htabs);
        hwndonglet2=onglet2(htabs);
 

- envoyer les informations de configuration du carnet d'adresses aux deux procã©dures des fenãªtres filles (les pages).
- n'afficher que la premiã¨re page
- crã©er les deux boutons ok et annuler de la boite de dialogue.

voci la fonction structureconfig utilisã©e pour remplir la structure config :

Code C :

void structureconfig ( config *p_data)
{

     chargerconfig ((lpvoid) &(p_data->largeur),0, sizeof(char)*5);
     chargerconfig ((lpvoid) &(p_data->hauteur),(sizeof(char)*5), sizeof(char)*5);
     chargerconfig ((lpvoid)&(p_data->couleur[0]),sizeof(char)*10, sizeof(colorref));
     chargerconfig ((lpvoid)&(p_data->couleur[1]),(sizeof(char)*10)+sizeof(colorref), sizeof(colorref));
     chargerconfig ((lpvoid)&(p_data->couleur[2]),(sizeof(char)*10)+sizeof(colorref)*2, sizeof(colorref));
     chargerconfig ((lpvoid)&(p_data->couleur[3]),(sizeof(char)*10)+sizeof(colorref)*3, sizeof(colorref));
     chargerconfig ((lpvoid)&(p_data->couleur[4]),(sizeof(char)*10)+sizeof(colorref)*4, sizeof(colorref));
     chargerconfig ((lpvoid)&(p_data->couleur[5]),(sizeof(char)*10)+sizeof(colorref)*5, sizeof(colorref));
     chargerconfig ((lpvoid)&(p_data->adresse),(sizeof(char)*10)+sizeof(colorref)*6, sizeof(char)*max_path);
}
 


les deux fonctions onglet1 et onglet2 sont presque identiques. j'aurais pu n'en faire qu'une en passant des arguments supplã©mentaires. on voit bien ici que j'ai codã© un peu au petit bonheur la chance Smile. mais je joue le jeu et je vous livre le code tel qu'il est, sans modfication.
voici ces deux fonctions, ã  vous de n'en faire qu'une. onglet1 et onglet2 retournent le handle de la fenãªtre crã©ã©e.
Code C :

hwnd onglet1(hwnd htabs)
{
   static  hwnd hwndonglet1=null;
   static wndclass wc;

    wc.style = 0;
    wc.lpfnwndproc = proconglet1;
    wc.cbclsextra = 0;
    wc.cbwndextra = 0;
    wc.hinstance = null;
    wc.hicon = loadicon(null, idi_application);
    wc.hcursor = loadcursor(null, idc_arrow);
    wc.hbrbackground = (hbrush)(1 + color_btnface);
    wc.lpszmenunamenull;
    wc.lpszclassname = "classeonglet1";
    unregisterclass("classeonglet1",hinstance);
    if(!registerclass(&wc)) return false;

    hwndonglet1= createwindow("classeonglet1", "",
                 ws_child,5, 30, 355, 260,  htabs, null, hinstance, null);
    return hwndonglet1;
}

/******************************************************************************** ****************************/
hwnd onglet2(hwnd htabs)
{
  static  hwnd hwndonglet2=null;
  static  wndclass wc;

    wc.style = 0;
    wc.lpfnwndproc = proconglet2;
    wc.cbclsextra = 0;
    wc.cbwndextra = 0;
    wc.hinstance = null;
    wc.hicon = loadicon(null, idi_application);
    wc.hcursor = loadcursor(null, idc_arrow);
    wc.hbrbackground = (hbrush)(1 + color_btnface);
    wc.lpszmenunamenull;
    wc.lpszclassname = "classeonglet2";
    unregisterclass("classeonglet2",hinstance);
    if(!registerclass(&wc)) return false;

    hwndonglet2= createwindow("classeonglet2", "",
                 ws_child,5, 30, 355, 260,  htabs, null, hinstance, null);

  return hwndonglet2;
}
 


Une classe de fenêtre est enrgistrée pour toute la durée de l'application. Si on utilise plusieurs fois l'option
affichage du menu on va essayer d'enregistrer plusieurs fois les mêmes classes de fenêtre. C'est pour
cela que je supprime la classe avant de la créer. On pourrait aussi imaginer
enregistrer toutes les classes de fenêtre au début du programme et se contenter de créer les fenêtres.
Je pense que c'est ce que j'aurais dû faire puisque les fenêtres ne changent pas d'apparence.
Bonjour,
aujourd'hui vite fait la fonction de réponse aux messages envoyésà la procédure de la boite
de dialogue de configuration, messagesTab.



Code C :

void messagestab (hwnd hdlg,wparam wparam,lparam lparam, config * p_data)
{
    char texte[10];
    if(hiword(wparam)==bn_clicked)
    {
        //lparam= handle du bouton
        getwindowtext(lparam,texte,10);
       if(!strncmp((lptstr)texte,"ok",2))
        {
         if(messagebox(null,"voulez-vous enregistrer la configuration ?",""
                                ,mb_okcancel|mb_iconinformation)==idok)
         {
         enregistrerconfig (p_data);
         enddialog(hdlg,0);
         }

        }
        if(!strncmp((lptstr)texte,"annuler",7))
        {
        enddialog(hdlg,0);
        }
    }
}
 
Bonjour,
si on presse sur le bouton OK de la boite de dialogue de configuration, il faut enregistrer
la nouvelle configuration dans la fichier carnet.config. Voici la fonction qui fait cela :


Code C :

void enregistrerconfig (config *p_data)
{
static char dossier[max_path]={0};
static dword nbcharwrite ;
static handle hfichier;

getcurrentdirectory(max_path,(lptstr)dossier);
strncat(dossier,"\carnet.config",max_path);
hfichier = createfile( dossier, generic_write|generic_read, 0,null,
                                           create_always, file_attribute_normal, null);

setfilepointer(hfichier,0,0,file_begin);
writefile(hfichier, (lptstr)& (p_data->largeur),sizeof(char)*5, &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->hauteur),sizeof(char)*5, &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->couleur[0]),sizeof(colorref), &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->couleur[1]),sizeof(colorref), &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->couleur[2]),sizeof(colorref), &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->couleur[3]),sizeof(colorref), &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->couleur[4]),sizeof(colorref), &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->couleur[5]),sizeof(colorref), &nbcharwrite, null);
writefile(hfichier, (lptstr)& (p_data->adresse),sizeof(char)*(max_path), &nbcharwrite, null);

closehandle(hfichier);
}

 
Bonjour !

voilà j'en ai à peu près fini avec la procédure de la boite de dialogue de configuration. Quand la fenêtre reçoit le
message WM_NOTIFY et si l'utilisateur clique sur un onglet (TCN_SELCHANGING) on trouve le numéro de l'onglet
avec la fonction TabCtrl_GetCurSel(hTabs) et on affiche la fenêtre fille correpondante.

Le message WM_COULEUR envoie les données de configuration aux procédures des fenêtres de configuration (1 parent et 2 filles).

Voyons la procédure de la première fenêtre fille de la boite de dialogue : l'organigramme concerne les deux fenêtres filles, et il manque le cas du message WM_CREATE.


Code C :

lresult callback  proconglet1(hwnd hwndonglet1, uint umsg, wparam wparam, lparam lparam)
{
 hwnd  hbouton[3]={0};
 static hwnd hdlg =null;
 static config data, *p_data;

  switch (umsg)
    {
        case wm_create:

    hbouton[0]=createwindow("button","couleur de la reliure",ws_child|ws_visible | bs_pushbutton ,
                                        5,20,170,20,hwndonglet1,null,hinstance,null);
    hbouton[1]=createwindow("button","couleur de la couverture",ws_child|ws_visible | bs_pushbutton ,
                                        5,90,170,20,hwndonglet1,null,hinstance,null);
    hbouton[2]=createwindow("button","",ws_child|ws_visible | bs_groupbox ,
                                       185,0,170,250,hwndonglet1,null,hinstance,null);
        return 0;

        case wm_command:
        messagesonglet1 (hwndonglet1,wparam,lparam,&data);
        sendmessage(hdlg,wm_couleur,&data,0);
        return 0;

        case wm_paint:
        dessineronglets1(hwndonglet1,&data);
        return 0;

        case wm_couleur:
        p_data=wparam;
        data=*p_data;
        hdlg=lparam;
        return true;

        case wm_destroy:
         destroywindow(hwndonglet1);
        return 0;

        default:
        return defwindowproc(hwndonglet1, umsg, wparam, lparam);

    }

}

 
Bonjour,
aujourd'hui je vais vous montrer ce qui se passe à la reception du message WM_PAINT dans
la procédure de la ProcOnglet1. Voici la fonction dessinerOnglets1:



Code C :

void dessineronglets1(hwnd hwndonglet1, config *p_data)
{

    static hdc hdc=null;
    static paintstruct ps;

    hdc = beginpaint(hwndonglet1,&ps);
    dessinerrectanglesimple (hdc,190, 13 , 220,245,p_data->couleur[0],p_data->couleur[0]);
    dessinerrectanglesimple (hdc,220, 13, 350,245,p_data->couleur[1],p_data->couleur[1]);
    dessinerrectanglesimple (hdc,250, 60 , 310,95,rgb(255,255,255),rgb(255,255,255));
    endpaint(hwndonglet1, &ps);
}

 


et voici une fonction que j'ai crã©ã©e et que j'utilise dans tous mes codes pour dessiner un rectangle :dessinerrectanglesimple.

Code C :


void dessinerrectanglesimple (hdc hdcdessin,int x, int y, int x1, int y1,
                              colorref couleurrectangle,colorref couleurfond)
{
                hpen hrectangle, hpold;
                hbrush hfond, hbrold;


                          hrectangle = createpen(ps_solid, 1, couleurrectangle);
                          hpold = (hpen)selectobject(hdcdessin,(hgdiobj)hrectangle);

                          hfond = createsolidbrush(couleurfond);
                          hbrold = (hbrush)selectobject(hdcdessin,(hgdiobj)hfond);


                          rectangle(hdcdessin, x, y,x1,y1);

                          selectobject(hdcdessin,hbrold);
                          deleteobject(hfond);

                          selectobject(hdcdessin,hpold);
                          deleteobject(hrectangle);
}
 
Hello,

pour la fonction de réponse aux messages envoyés à la première fenêtre fille je ne vais pas montrer l'organigramme.
En effet, j'avais pensé utiliser une ressource pour cette partie du programme et l'organigramme ne correspond plus.

Voici le code de cette fonction :

Code C :

void messagesonglet1 (hwnd hwndonglet1,wparam wparam,lparam lparam, config *p_data)
{
    char texte[40];
    getwindowtext(lparam,texte,40);
    if(hiword(wparam)==bn_clicked)
    {
         if(!strncmp((lptstr)texte,"couleur de la reliure",strlen("couleur de la reliure")))
         {
            changercouleur (hwndonglet1,&(p_data->couleur[0]));
         }
         if(!strncmp((lptstr)texte,"couleur de la couverture",strlen("couleur de la couverture")))
         {
            changercouleur (hwndonglet1,&(p_data->couleur[1]));
         }
    }

}
 


on prend le texte du contrã´le (bouton) sur lequel l'utilisateur a cliquã© et selon la chaine de caractã¨res trouvã©e
on change la couleur de la reliure ou de la couverture.

pour choisir une nouvelle couleur j'utilise une boite de dialogue commune de choix de couleurs dans la fonction changercouleur:


Code C :

void changercouleur(hwnd hwnd,colorref* couleur)
{
choosecolor cc;
static colorref acrcustclr[16];

// structure de la boite de dialogue de choix de couleurs
            zeromemory(&cc, sizeof(choosecolor));
            cc.lstructsize = sizeof(choosecolor);
            cc.hwndowner = hwnd;
            cc.rgbresult = *couleur;
            cc.lpcustcolors = null;
            cc.lpcustcolors = (lpdword) acrcustclr;
            cc.flags = cc_fullopen | cc_rgbinit;
    if (choosecolor(&cc)==true)
    {
    * couleur =  cc.rgbresult ;
    }
   invalidaterect(hwnd, 0, true);
}
 
Voyons, aujourd'hui, la procédure de la deuxième fenêtre fille de la boite de dialogue : (voir l'organigramme de la première fenêtre fille).

Code C :

lresult callback  proconglet2(hwnd hwndonglet2, uint umsg, wparam wparam, lparam lparam)
{
 hwnd  hbouton[5]={0};
 static hwnd hdlg =null;
 static config data, *p_data;

  switch (umsg)
    {
        case wm_create:

    hbouton[0]=createwindow("button","couleur de page 1",ws_child|ws_visible | bs_pushbutton ,
                                        5,10,170,20,hwndonglet2,null,hinstance,null);
    hbouton[1]=createwindow("button","couleur de page 2",ws_child|ws_visible | bs_pushbutton ,
                                        5,50,170,20,hwndonglet2,null,hinstance,null);
    hbouton[2]=createwindow("button","couleur de texte 1",ws_child|ws_visible | bs_pushbutton ,
                                        5,90,170,20,hwndonglet2,null,hinstance,null);
    hbouton[3]=createwindow("button","couleur de texte 2",ws_child|ws_visible | bs_pushbutton ,
                                        5,130,170,20,hwndonglet2,null,hinstance,null);
    hbouton[4]=createwindow("button","",ws_child|ws_visible | bs_groupbox ,
                                       185,0,170,250,hwndonglet2,null,hinstance,null);
        return 0;

        case wm_command:
        messagesonglet2 (hwndonglet2,wparam,lparam, &data);
        sendmessage(hdlg,wm_couleur,&data,0);
        return 0;

        case wm_paint:
        dessineronglets2(hwndonglet2,&data);
        return 0;

        case wm_couleur:
        p_data=wparam;
        data=*p_data;
        hdlg=lparam;
        return true;

        case wm_destroy:
         destroywindow(hwndonglet2);
        return 0;

        default:
        return defwindowproc(hwndonglet2, umsg, wparam, lparam);

    }

}

 


Comme dans la procédure ProcOnglet1 on va créer des boutons (ici 4 boutons et un groupe) à la reception du message WM_CREATE. Je vous montrerai dans les prochains jours la fonction qui dessine la page et la fonction de réponse aux messages envoyés à cette procédure.
Pages: 1 2 3 4 5 6 7
URLs de référence