Utilisation du calendrier fourni avec Windows (>= W95 et NT3.51)


(Testé sous Windows 98)


Modifications apportées par rapport à la première version :

  - Possibilité de choisir le nombre de mois affichés en largeur et hauteur
  - Possibilité de choisir si animation ou pas
  - Possibilité de modifier les couleurs


Les ingrédients ...

Une fenêtre avec les propriétés suivantes :

  - Cadre épais
  - Hors écran à l'ouverture
  - Barre de titre et Menu système

  - et le code suivant...


// *** Ouverture de la fenêtre calendw ***

procedure calendw( datetr , nbl=1 , nbh=1 , anim=1 , fond=-1 , fondc=-1 , fondt=-1 , txtt=-1 , txtdm=-1 , txtd=-1 )

// datetr -> date transmise pour être sélectionnée, si vide date sélecionnée sera la date système
// nbl -> nombre de mois visibles en largeur
// nbh -> nombre de mois visibles en hauteur
// anim -> 1 pour afficher le calendrier avec l'animation ou 0 pour affichage direct
// fond -> couleur fond fenêtre
// fondc -> couleur fond calendrier
// fondt -> couleur fond titres calendrier
// txtt -> couleur texte des titres
// txtdm -> couleur texte des dates
// txtd -> couleur texte des dates hors mois

global

  hwndcalend est un entier long // handle du calendrier
  evencalend est un entier long // evenement pour détecter la sélection d'une date

local

ICC_DATE_CLASSES est un entier long = 0x00000100 // month picker
initcont est compose de
  size est un entier long
  typec est un entier long
fin
initcont.size=8
initcont.typec=ICC_DATE_CLASSES

si pas appeldll32("comctl32.dll","InitCommonControlsEx",&initcont) alors
  erreur("Impossible de créer le calendrier !","Il y a un problème avec le fichier comctl32.dll.")
  ferme()
fin

// coordonnés clic
poss est un entier long=curseurpos(cpecran)
posx est un entier = poidsfaible(poss)
posy est un entier = poidsfort(poss)

// création du calendrier
style est un entier long= 0x40000000 // ws_child
hwndcalend=AppelDLL32("user32","CreateWindowExA", 0 ,"SysMonthCal32" , "" , style , 0 , 0 , 200 , 200 , handle() , null , instance() , null)
si pas hwndcalend alors
   erreur("Erreur à la création du calendrier !")
   ferme()
fin

// lecture dimensions minimales pour le calendrier
rect est compose de
   l est un entier long
   t est un entier long
   r est un entier long
   b est un entier long
fin
sendmessage( hwndcalend , 0x1009 , 0 , &rect ) // mcm_first + mcm_getminreqrect

// résolution écran
largecr est un entier = AppelDLL32("user32","GetSystemMetrics" , 0)
hautecr est un entier = AppelDLL32("user32","GetSystemMetrics" , 1)

// dimensions calendrier
largc est un entier = rect.r
hautc est un entier = rect.b
si nbl>1 alors
   largc = (largc + (nbl*2)) * nbl
fin
si nbh>1 alors
   hautc = (hautc - (nbh*1.5)) * nbh
fin
// si dimensions > résolution
// affichage d'un seul mois
si largc>largecr ou hautc>hautecr alors
   largc=rect.r
   hautc=rect.b
fin
// si fenêtre dépasse l'écran
// modification position
si largc+posx>largecr alors
   posx=largecr-largc-10
fin
si hautc+posy>hautecr alors
   posy=hautecr-hautc-20
fin

appeldll32("user32","SetWindowPos", hwndcalend , 0 , 0 , 0 , largc , hautc , 0x4)

// selection dans le calendrier de la date transmise à la fenêtre
systemtime est compose de
   wYear est un entier
   wMonth est un entier
   wDayOfWeek est un entier
   wDay est un entier
   wHour est un entier
   wMinute est un entier
   wSecond est un entier
   wMilliseconds est un entier
fin
systemtime.wyear=val(datetr[[a 4]])
systemtime.wmonth=val(datetr[[5 a 6]])
systemtime.wday=val(datetr[[7 a 8]])

// mcm_first (0x1000) + mcm_selcursel (0x2)
sendmessage( hwndcalend , 0x1002 , 0 , &systemtime )

// modification des couleurs
// couleur fond
si fond<>-1 alors sendmessage(hwndcalend,0x100A,0,fond)
// couleur fond partie calendrier
si fondc<>-1 alors sendmessage(hwndcalend,0x100A,4,fondc)
// couleur fond des titres
si fondt<>-1 alors sendmessage(hwndcalend,0x100A,2,fondt)
// couleur texte des titres
si txtt<>-1 alors sendmessage(hwndcalend,0x100A,3,txtt)
// couleur des dates
si txtdm<>-1 alors sendmessage(hwndcalend,0x100A,1,txtdm)
// couleur texte des dates représentant m-1 ou m+1
si txtd<>-1 alors sendmessage(hwndcalend,0x100A,5,txtd)

// affichage du calendrier
appeldll32("user32","ShowWindow",hwndcalend,1)

// dimensions et position fenêtre
caption est un entier = appeldll32("user32","GetSystemMetrics",4) // hauteur caption
border est un entier = appeldll32("user32","GetSystemMetrics",46) // bordures
border=border*3
hauteurf est un entier = hautc + border + caption // hauteur totale fenêtre
largeurf est un entier = largc + border // largeur totale fenêtre

// position et dimensions fenetre selon l'endroit du clic et dimensions du calendrier
// la fenêtre est hors écran à l'ouverture
// largeur et hauteur à 0 pour effet animation si anim=1
si anim alors

  appeldll32("user32","SetWindowPos", handle() , 0 , posx , posy , 0 , 0 , 0x4 )

  // augmentation largeur et hauteur jusqu'à la taille normale
  lignef est un entier
  colonnef est un entier
  boucle
     si lignef<hauteurf alors
       lignef++
     fin
     si colonnef<largeurf alors
       colonnef++
     fin

     appeldll32("user32","MoveWindow", handle() , posx , posy , colonnef , lignef , 1 )
     si lignef>=hauteurf et colonnef>=largeurf alors sortir
  fin

sinon

   appeldll32("user32","SetWindowPos",handle(),0,posx,posy,largeurf,hauteurf,0x4)

fin


evencalend=evenement("choix_calend","*.",0x4E) // wm_notify



// *** Fermeture de la fenêtre Calendw ***

appeldll32("user32","DestroyWindow" , hwndcalend )
finevenement(evencalend)
renvoyer datetr



// *** Procédure choix_calend() ***

Procédure choix_calend()


date est compose de
   hwndf est un entier long
   idfrom est un entier long
   code est un entier long

   wYear est un entier
   wMonth est un entier
   wDayOfWeek est un entier
   wDay est un entier
fin

// transfert des 3 premières variables car si code<>-746 -> risque plantage
transfert( &date , _eve.lparam , 12 )

// si sélection d'une date
si date.code=-746 alors
   // transfert totalité
   transfert( &date, _eve.lparam , dimension(date) )
   datetr=verschaine(date.wYear,"04d") + verschaine(date.wMonth,"02d") + verschaine(date.wday,"02d")
   ferme()
fin


Appel du calendrier :


// pour un champ date 'datet'

// 1 mois d'affiché
// calendrier standard

datet=ouvre("calendw", datet )

// ou

// 1 mois en largeur
// 3 mois en hauteur
// animation
// fond fenêtre gris
// fond calendrier gris
// on laisse le fond du titre normal
// texte titre jaune

datet=ouvre("calendw", datet , 1 , 3 , 1 , igrisclair , igrisclair , -1 , ijauneclair )

// ou

// 3 mois en largeur
// 4 mois en hauteur
// pas d'animation
// on change uniquement la couleur des dates hors mois

datet=ouvre("calendw", datet , 3 , 4 , 0 , -1 , -1 , -1 , -1 , -1 , irougefonce )


// ou pour utiliser une chaine et non un champ date

chdate est une chaine = ouvre("calendw", datesys() )