[win32 - C/C++] Problème d'intialisation d'un calendrier [Résolu]

Signaler
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
-
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
-
Bonjour à tous.
Après de nombreuses recherches sur le réseau Codes-Sources, la msdn, google, etc... je viens vous exposer directement mon problème ici.
J'ai créé un contrôle calendrier (MONTHCAL_CLASS) et, mon but étant de pouvoir ajouter des événements, je lui ai rajouté le style MCS_DAYSTATE afin de pouvoir mettre certaines dates en gras.
Le soucis est qu'à l'ouverture de ma fenêtre, certaines dates se mettent en gras toutes seules. Or, d'une part je voudrais qu'aucune ne soit mise en gras, pour ensuite en mettre certaines dès l'ouverture de la fenêtre.
D'après la msdn, le seul moyen de mettre des dates en gras est d'intercepter le message WM_NOTIFY de la fonction callback, (avec le code MCN_GETDAYSTATE).
J'ai donc récupéré un code (toujours sur la msdn) qui permette de mettre en gras des dates (visible ici ).
Il fonctionne bien, mais pas à l'initialisation du contrôle (il faut cchanger de mois au moins 1fois pour que ça fonctionne).
J'ai donc tenté de forcer l'envoi d'un message WM_NOTIFY juste après la création de mon contrôle... ça compile, mais le résultat n'y est pas.

Voici une de mes nombreuses tentatives pour enlever toute date en gras à l'initialisation :
// Dans mon WinMain();
mois1= CreateWindowEx(0 , MONTHCAL_CLASS,NULL,WS_CHILD|WS_VISIBLE|MCS_DAYSTATE,0,0,0,0,hwnd,(HMENU)NULL,hinst,NULL);
MONTHDAYSTATE rgMonths[12] ={0};
NMDAYSTATE state;
state.nmhdr.code= MCN_GETDAYSTATE ;
state.nmhdr.hwndFrom =mois1;// HWND de mon contrôle
state.stStart.wDay= 1 ; // Jour de départ (d'après la doc msdn)
state.stStart.wMonth =1;// Mois de départ (d'après la doc msdn)
state.stStart.wYear= 1601 ; // Année de départ (d'après la doc msdn)
state.cDayState =12;// Nombre d'éléments dans le tableau affecté à 'prgDayState'
for(int i= 0 ; i < state.cDayState;i++) { BOLDDAY(rgMonths[i],0); }// Initialise les dates à 0 (sans gras), j'ai aussi tenté sans cette boucle, ça ne change rien
state.prgDayState =rgMonths;// Structure 'MONTHDAYSTATE' contenant les états des dates
SendMessage(hwnd,WM_NOTIFY,0,(LPARAM)&state);

Ensuite j'intercepte le message WM_NOTIFY et, pour tester, je mets le 15ème jour de chaque mois en gras.
//Dans ma MainWndProc();
[...]
case WM_NOTIFY:
    if((((LPNMHDR)lParam)->hwndFrom)= = mois1) {
        if ((((LPNMHDR)lParam)->code) == MCN_GETDAYSTATE) {
            MONTHDAYSTATE rgMonths[12]={0} ;
            int cMonths =((NMDAYSTATE*)lParam)->cDayState;
            for(int i= 0 ; i < cMonths;i++) {
                BOLDDAY(rgMonths[i],15);
            }
            ((NMDAYSTATE*)lParam)->prgDayState =rgMonths;
        }
    }
[...]

En bref, si quelqu'un pourrait m'expliquer comment le code MCN_GETDAYSTATE fonctionne exactement car j'avoue ne pas avoir compris du tout.
Par la même occasion, si on pouvait m'expliquer comment initialiser mon contrôle en virant toutes dates en gras, ça ne serait pas de refus ^^.
(ce dont je suis sûr, c'est que mon SendMessage(mois1,WM_NOTIFY,0,(LPARAM)&state); appelle bien le message).

Merci d'avance.

Cordialement, uaip.

5 réponses

Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Salut,
<<D'après la msdn, le seul moyen de mettre des dates en gras est
d'intercepter le message WM_NOTIFY de la fonction callback, (avec le
code MCN_GETDAYSTATE).>> La MSDN a vraiment dit ça?
Pour initialiser correctement le calendrier dès sa création, il suffit de faire:
SYSTEMTIME st[2];
int nbrmois=SendMessage(mois1,MCM_GETMONTHRANGE , GMR_DAYSTATE, (LPARAM)st);          SendMessage(mois1,MCM_SETDAYSTATE,nbrmois,(LPARAM)rgMonths);
Le tableau rgMonths doit être péalablement initialisé comme dans la boucle de ton code.
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
Salut racpp.
Ton code fonctionne en effet, c'est beau (vu le temps que j'ai galéré) mais j'avoue ne toujours pas comprendre comment fonctionne réellement ce contrôle.
J'avais déjà tenté un MCM_SETDAYSTATE mais j'avoue ne pas avoir pensé au MCM_GETMONTHRANGE. En fait je tatillonne un peu.
Je suis peut-être un peu bê-bête, mais je ne comprends pas ce que sont réellement les paramètres à envoyer / recevoir au contrôle. Si tu m'avais dit d'utiliser ces deux messages (cités plus haut) j'aurais sans doute réussi, mais sans savoir "pourquoi" utiliser ces deux messages.

Ne connais-tu pas un tuto ou quelque chose du genre qui explique clairement l'utilisation de ce contrôle ? Je trouve la msdn trop abstraite sur ce sujet. Et je n'ai pas réussi à trouver d'exemple sur le net qui corresponde à peu près à ce que je cherche à faire.
Merci en tout cas pour ta réponse.

Cordialement, uaip.
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
Bon, même sans avoir tout compris, j'ai réussi à faire ce que je voulais :
l'utilisateur rentre du texte dans un edit et l'enregistre. Cela écrit le texte dans un fichier + la date sélectionnée sur le calendrier. En navigant sur le calendrier, les dates en gras signifient que l'utilisateur a tapé du texte. Il suffit de cliquer dessus pour afficher le texte.

C'était simplement le fait de mettre les dates en gras que je n'arrivais pas. Là j'utilise seulement les 2 messages que tu m'as donné, j'ai ainsi pu virer le MCN_GETDAYSTATE du WM_NOTIFY.
Ce n'est sans doute pas la meilleure solution, mais bon... disons qu' "au moins ça marche".
Un grand merci, donc. :)

Cordialement, uaip.
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Le message MCM_GETMONTHRANGE permet de récupérer le nombre de mois affichés totalement ou partiellement par le controle. En général c'est 3 pour  le calendrier d'un mois mais la MSDN conseille toujours d'utiliser ce message.
Si tu veux également déterminer la date de début et de fin du calendrier, tu peux utiliser le message MCM_SETRANGE.
Par rapport à d'autres controles, je trouve que le calendrier est beaucoup plus simple à utiliser:
http://msdn.microsoft.com/en-us/library/bb760921(VS.85).aspx
http://msdn.microsoft.com/en-us/library/cc656514(VS.85).aspx
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
"Par rapport à d'autres controles, je trouve que le calendrier est beaucoup plus simple à utiliser"
En effet il n'est pas très dur dans l'absolu (disons que pratiquement tout est automatique) mais je pense qu'il me faudra pas mal de temps pour le manipuler "à l'aise".
Cela dit, pour ma part, je trouve les autres contrôles plus simples, au contraire, du moins la ListView, TreeView, StatusBar, RichEdit, etc...
Par contre il faudra que j'essaye la Rebar (là aussi, j'ai compris le principe, mais je trouve la manipulation assez laborieuse), le Pager et le SysLink. Peut-être que eux sont plus difficiles, comme tu le dis.

Sinon, pour en revenir au calendrier, j'ai posté cette après-midi, en espérant obtenior encore un peu plus d'aide sur ce qui ne va pas dans mon code.
Bonne continuation.

Cordialement, uaip.