Afficher "l'heure a sonnée" si correspondance il y

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Et le résultat du mélange des deux code ci-dessus c'est ce code ci-dessous. Là, tout fonctionne SAUF ce foutu bouton d'acquittement général quand on lui déplace une fenêtre dessus, il "disparaît" même s'il continue d'être opérationnel (il faut juste cliquer "dans le vide", à sa place habituelle). Pourquoi? Chais pô...

A part ça, tout est thread qui finit thread, avec de la sueur et une pluie de Delay() dans tous les sens...

Code : Tout sélectionner

EnableExplicit

Structure Thread
   *Root
   *MessageRequester
   *InputRequester
   *CreateRequester
   Title.S
   Message.S
   InputString.S
   *Command
   *Result
   CIndex.L
   No.L[16]
   *Mem[16]
   Qty.L
EndStructure

Structure Requester
   Command.L
   Win.L
   MessageGdt.L   
   InputGdt.L
   *Result
   OkGdt.L
   Event.L
   EventGdt.L
EndStructure

Structure Alarm
   *Root
   *ResetAll
   *CheckSyntax
   *Ack
   *AckAll
   *InputDate
   *CheckAll
   *CloseAll
   *AvailableOne
   *Set
   *Reset
   *NewOne
   Start.L
   ListWin.L
   ListGdt.L
   AckGdt.L
   Menu.L
   MenuItem.L
   Event.L
   EventGdt.L
   EventType.L
   HourSet.S
   StatSet.L
   DateSys.L
   HmsSys.S
   HourSys.L
   MinuteSys.L
   SecondSys.L
   MaxQty.L
   Index.L
   DateError.L
   RequestFlag.L
   *Hours
EndStructure


Structure AlarmSet
   Ymd.S
   Year.L
   Month.L
   Day.L
   Hms.S
   Hour.L
   Minute.L
   Second.L
   Stat.L
EndStructure


Structure AlarmTable
   Get.AlarmSet[256]
EndStructure

Structure Root
   *Requester
   *Alarm
   ShutDown.L
EndStructure

Procedure ThreadRequester(*C.Thread)
   Protected *M.Requester
   Protected *ResultString
   With *C
      *M = AllocateMemory(SizeOf(Requester) )
      *C\Mem[\CIndex] = *M
      *M\Command = \Command
      *M\Result = \Result
      *M\Win = OpenWindow(-1, 0, 0, 384, 128, \Title, $CF0001)
      *M\MessageGdt = TextGadget(-1, 16, 16, 352, 24, \Message, 1)
      If \Command = \InputRequester
         *M\InputGdt = StringGadget(-1, 16, 56, 352, 24, "")
         *M\OkGdt = ButtonGadget(-1, 96, 96, 192, 24, "Ok")      
      Else
         *M\OkGdt = ButtonGadget(-1, 96, 56, 192, 24, "Ok")      
         ResizeWindow(*M\Win, #PB_Ignore, #PB_Ignore, 384, 88)
      EndIf
      Repeat
         *M\Event = WaitWindowEvent()
         Select *M\Event
            Case #PB_Event_Gadget
               *M\EventGdt = EventGadget()
               Select *M\EventGdt
                  Case *M\OkGdt
                     If *M\Command = \InputRequester
                        \InputString = GetGadgetText(*M\InputGdt)
                        *ResultString = AllocateMemory(Len(\InputString) + 1)
                        PokeS(*ResultString, \InputString)
                        PokeL(\Result, *ResultString) ; /!\ Pointeur 32 bits
                     EndIf
                     *M\Event = 16
               EndSelect   
         EndSelect           
      Until *M\Event = 16
      CloseWindow(*M\Win)   
      FreeMemory(*M)
   EndWith   
EndProcedure

Procedure ThreadMessageRequester(*C.Thread)
   ThreadRequester(*C)
   Delay(500)
EndProcedure

Procedure ThreadInputRequester(*C.Thread)
   ThreadRequester(*C)
   Delay(500)
EndProcedure

Procedure StartRequesterThread(*C.Thread)
   Protected Index.L
   For Index = 0 To 15
      If IsThread(*C\No[Index]) = 0
         *C\CIndex = Index
         *C\No[Index] = CreateThread(*C\Command, *C)
         Break
      EndIf
   Next Index
   Repeat
      Delay(50)
   Until IsThread(*C\No[Index])
EndProcedure

Procedure RequesterMain(*Root.Root)
   Protected Index.L
   Protected Thread.Thread
   Protected *MyString1
   *Root\Requester = Thread
   With Thread
      \MessageRequester = @ThreadMessageRequester()
      \InputRequester = @ThreadInputRequester()
      Repeat
         Delay(100)
      Until *Root\ShutDown
   EndWith   
EndProcedure   




Procedure AlarmResetAll(*C.Alarm)
   Protected Index.L
   Protected i.L
   With *C
      *C\RequestFlag = 1
      \ListWin = OpenWindow(-1, 0, 0, 256, 384, "Alarmes", $CF0001)
      \ListGdt = ListIconGadget(-1, 16, 16, 224, 312, "N°", 32, #PB_ListIcon_FullRowSelect)
      \AckGdt = ButtonGadget(-1, 16, 342, 224, 24, "Acquitter toutes les alarmes signalées")
      AddGadgetColumn(\ListGdt, 1, "Horaires", 128)
      AddGadgetColumn(\ListGdt, 2, "Etat", 64)
      For Index = 0 To \MaxQty - 1
         AddGadgetItem(\ListGdt, Index, Str(Index) )
      Next Index
      \Hours = AllocateMemory(SizeOf(AlarmSet) * \MaxQty)
      \Menu = CreatePopupMenu(-1)
      MenuItem(1, "Activer")
      MenuItem(2, "Désactiver")
      MenuItem(3, "Acquitter")
      MenuBar()
      MenuItem(4, "Modifier l'horaire") 
      MenuBar()
      MenuItem(7, "Quitter")
      For i = 0 To 500
         WindowEvent()
      Next
   EndWith
EndProcedure



Procedure AlarmSet(*C.Alarm)
   Protected Index.L
   Protected *AlarmTable.AlarmTable
   With *AlarmTable\Get[Index]
      SetGadgetItemText(*C\ListGdt, *C\Index, Str(*C\Index), 0)
      SetGadgetItemText(*C\ListGdt, *C\Index, *C\HourSet, 1)
      *AlarmTable = *C\Hours
      Index = *C\Index
      \Ymd = Left(*C\HourSet, 8)
      \Year = Val(StringField(\Ymd, 3, "/") )
      \Month = Val(StringField(\Ymd, 2, "/") )
      \Day = Val(StringField(\Ymd, 1, "/") )
      \Hms = Right(*C\HourSet, 8)
      \Hour = Val(StringField(\Hms, 1, ":") )
      \Minute = Val(StringField(\Hms, 2, ":") )
      \Second = Val(StringField(\Hms, 3, ":") )
      \Stat = *C\StatSet
   EndWith
EndProcedure



Procedure AlarmCheckSyntax(*C.Alarm)
   Protected Error.L
   Protected S.S
   Protected i.L
   Protected j.L
   Protected a.L
   Protected *Root.Root
   Protected *Req.Thread
   *Root = *C\Root
   *Req = *Root\Requester
   *C\DateError = 1
   S = Trim(*C\HourSet)
   S = Left(S, 8) + " " + Right(S, 8)
   If Len(S) = 17
      If Mid(S, 3, 1) = "/"
         If Mid(S, 6, 1) = "/"
            If Mid(S, 9, 1) = " "
               If Mid(S, 12, 1) = ":"
                  If Mid(S, 15, 1) = ":"
                     *C\DateError = 0
                     For i = 1 To 16 Step 3
                        For j = 0 To 1
                           a = Asc(Mid(S, i + j, 1) )
                           If (a < 48) Or (a > 57)
                              *C\DateError = 1
                           EndIf
                        Next j
                     Next i   
                  EndIf
               EndIf
            EndIf
         EndIf
      EndIf 
   EndIf
   If *C\DateError
      If *C\RequestFlag
         *Req\Command = *Req\MessageRequester
         *Req\Title = "Erreur"
         *Req\Message = "La syntaxe de la date est invalide !"
         StartRequesterThread(*Req)
      EndIf
      *C\HourSet = ""
      *C\StatSet = 0
   Else
      *C\HourSet = S
   EndIf
EndProcedure



Procedure AlarmAck(*C.Alarm)
   Protected DateSet.L
   Protected *AlarmTable.AlarmTable
   *AlarmTable = *C\Hours
   With *AlarmTable\Get[*C\Index]
      *C\HourSet = \Ymd + " " + \Hms
      DateSet = ParseDate("%dd/%mm/%yy %hh:%ii:%ss", *C\HourSet)
      DateSet + 86400               
      *C\HourSet = FormatDate("%dd/%mm/%yy %hh:%ii:%ss", DateSet)
   EndWith
   *C\StatSet = 1
   AlarmSet(*C)                        
EndProcedure



Procedure AlarmAckAll(*C.Alarm)
   Protected Index.L
   Protected DateSet.L
   Protected *AlarmTable.AlarmTable
   With *C
      *AlarmTable = \Hours
      For Index = 0 To \MaxQty - 1
         If *AlarmTable\Get[Index]\Stat = 2
            EndWith
            With *AlarmTable\Get[Index]
               *C\HourSet = \Ymd + " " + \Hms
               DateSet = ParseDate("%dd/%mm/%yy %hh:%ii:%ss", *C\HourSet)
               DateSet + 86400               
               *C\HourSet = FormatDate("%dd/%mm/%yy %hh:%ii:%ss", DateSet)
            EndWith
            With *C
            \Index = Index
            \StatSet = 1
            AlarmSet(*C)                        
         EndIf
      Next Index
   EndWith
EndProcedure



Procedure AlarmInputDate(*C.Alarm)
   Protected *Root.Root
   Protected *Req.Thread
   *Root = *C\Root
   *Req = *Root\Requester
   Protected MyString1.L
   Protected *AlarmTable.AlarmTable
   With *AlarmTable\Get[*C\Index]
      *Req\Command = *Req\InputRequester
      *Req\Title = "Modifier l'horaire"
      *Req\Message = "Respectez la syntaxe JJ/MM/AA HH:MM:SS"
      *Req\Result = @MyString1
      StartRequesterThread(*Req)
      Repeat
         Delay(500)
      Until MyString1 <> 0
      *C\HourSet = PeekS(MyString1)
      FreeMemory(MyString1)
      AlarmCheckSyntax(*C)
      AlarmSet(*C)
   EndWith      
EndProcedure



Procedure AlarmCheckAll(*C.Alarm)
   Protected *AlarmTable.AlarmTable
   Protected Index.L
   Protected Field.S
   Protected AlarmValue.L
   Protected i.L
   Protected *Root.Root
   Protected *Req.Thread
   *Root = *C\Root
   *Req = *Root\Requester
   *AlarmTable = *C\Hours   
   Delay(500)
      Repeat
         With *C
            \DateSys = Date()
            \HourSys = Hour(\DateSys)
            \MinuteSys = Minute(\DateSys)
            \SecondSys = Second(\DateSys)
            \HmsSys = RSet(Str(\HourSys ), 2, "0") + ":"
            \HmsSys + RSet(Str(\MinuteSys), 2, "0") + ":"
            \HmsSys + RSet(Str(\SecondSys), 2, "0")
            SetWindowTitle(\ListWin, \HmsSys)
         EndWith
         For Index = 0 To *C\MaxQty - 1
            With *AlarmTable\Get[Index]
               Select \Stat
                  Case 1
                     Field = "Active"
                     If *C\Start = 0
                        AlarmValue = ParseDate("%dd/%mm/%yy %hh:%ii:%ss", \Ymd + " " + \Hms)
                        If AlarmValue <= *C\DateSys
                           \Stat = 2
                           *Req\Command = *Req\MessageRequester
                           *Req\Title = "Avertissement"
                           *Req\Message = "Alarme n°" + Str(Index) + " !"
                           StartRequesterThread(*Req)
                           *C\Start = 1
                        EndIf                        
                     EndIf          
                  Case 0
                     Field = "Inactive"
                  Case 2
                     Field = "Signalée"
               EndSelect
               SetGadgetItemText(*C\ListGdt, Index, Field, 2)
            EndWith      
         Next Index
         *C\Start = 0
         Delay(25)
         *C\Event = WindowEvent()
         If *C\Event = #PB_Event_Gadget
            *C\EventGdt = EventGadget()
            *C\EventType = EventType()
            Select *C\EventGdt
               Case *C\AckGdt
                  AlarmAckAll(*C)
               Case *C\ListGdt
                  If *C\EventType = #PB_EventType_RightClick
                     *C\Index = GetGadgetState(*C\ListGdt)
                     If *C\Index <> -1
                        With *AlarmTable\Get[*C\Index]
                           For i = 1 To 3
                              DisableMenuItem(*C\Menu, i, 1)
                              DisableMenuItem(*C\Menu, i + 3, 1)
                           Next i
                           DisableMenuItem(*C\Menu, 4, 0)
                           If \Stat = 0
                              *C\HourSet = \Ymd + " " + \Hms
                              *C\RequestFlag = 0
                              AlarmCheckSyntax(*C)
                              *C\RequestFlag = 1
                              If *C\DateError = 0
                                 DisableMenuItem(*C\Menu, 1, 0)
                              EndIf
                           EndIf
                           If \Stat = 1
                              DisableMenuItem(*C\Menu, 2, 0)
                           EndIf
                           If \Stat = 2
                              DisableMenuItem(*C\Menu, 3, 0)
                           EndIf
                        EndWith
                        DisplayPopupMenu(*C\Menu, WindowID(*C\ListWin) )
                     EndIf
                  EndIf
            EndSelect
         EndIf
         If *C\Event = #PB_Event_Menu
            *C\MenuItem = EventMenu()
            With *AlarmTable\Get[*C\Index]
            Select *C\MenuItem
               Case 1
                  \Stat = 1
               Case 2
                  \Stat = 0
               Case 3
                  AlarmAck(*C)
               Case 4
                  AlarmInputDate(*C)
               Case 7
                  *C\Event = 16
            EndSelect
            EndWith                  
         EndIf
      Until *C\Event = 16
EndProcedure



Procedure AlarmCloseAll(*C.Alarm)
   With *C
      CloseWindow(\ListWin)
      FreeMemory(\Hours)
   EndWith
EndProcedure



Procedure AlarmAvailableOne(*C.Alarm)
   Protected Index.L
   Protected *AlarmTable.AlarmTable
   With *C
      *AlarmTable = \Hours
      For Index = 0 To \MaxQty - 1
         If *AlarmTable\Get[Index]\Hms = ""
            \Index = Index
            Break
         EndIf
      Next Index
   EndWith
EndProcedure



Procedure AlarmReset(*C.Alarm)
   Protected Index.L
   Protected *AlarmTable.AlarmTable
   With *AlarmTable
      *AlarmTable = *C\Hours
      Index = *C\Index
      \Get[Index]\Stat = 0
   EndWith
EndProcedure



Procedure AlarmNewOne(*C.Alarm)
   With *C
      AlarmAvailableOne(*C)
      AlarmSet(*C)
   EndWith
EndProcedure



Procedure AlarmMain(*Root.Root)
   Protected Alarm.Alarm
   Alarm\Root = *Root
   *Root\Alarm = Alarm
   Alarm\ResetAll = @AlarmResetAll()
   Alarm\Set = @AlarmSet()
   Alarm\CheckSyntax = @AlarmCheckSyntax()
   Alarm\Ack = @AlarmAck()
   Alarm\AckAll = @AlarmAckAll()
   Alarm\InputDate = @AlarmInputDate()
   Alarm\CheckAll = @AlarmCheckAll()
   Alarm\CloseAll = @AlarmCloseAll()
   Alarm\AvailableOne = @AlarmAvailableOne()
   Alarm\Reset = @AlarmReset()
   Alarm\NewOne = @AlarmNewOne()
   ; Initialisation
   Alarm\MaxQty = 16 ; Nombre max d'alarmes
   AlarmResetAll(Alarm)
   
   ; On rentre une première alarme inactive
   Alarm\HourSet = "21/02/09 21:02:00"
   Alarm\StatSet = 0
   AlarmNewOne(Alarm)

   ; On rentre une seconde alarme active
   Alarm\StatSet = 1
   Alarm\HourSet = "21/02/09 20:03:00"
   AlarmNewOne(Alarm)
   
   ; On rentre une seconde alarme signalée
   Alarm\StatSet = 2
   Alarm\HourSet = "21/02/09 20:40:00"
   AlarmNewOne(Alarm)
   
   ; On rentre une seconde alarme signalée
   Alarm\StatSet = 1
   Alarm\HourSet = "20/02/09 23:20:00"
   AlarmNewOne(Alarm)
   
   Alarm\Start = 1
   AlarmCheckAll(Alarm)

   AlarmCloseAll(Alarm)
   *Root\ShutDown = 1
EndProcedure



   Define Root.Root
   CreateThread(@RequesterMain(), Root)
   WaitThread(CreateThread(@AlarmMain(), Root) )
   
SpaceMan
Messages : 290
Inscription : mar. 26/oct./2004 19:35
Contact :

Message par SpaceMan »

woahh tout cela pour moi seul 8O
Ollivier je ne te remercierai jamais assez pour ce boulot ! maintenant c'est à moi de décortiquer tout ça et je te promets que des questions vont jaillirent.
encore merci et bon après midi à toi
:D
Un défaut qui empêche les hommes d’agir, c’est de ne pas sentir de quoi ils sont capables.
Jacques Bénigne Bossuet
brossden
Messages : 821
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Il y a peut être plus simple non ? :oops:

Code : Tout sélectionner

Enumeration
  #Window_0 : #StatusBar_Window_0 : #ListIcon_0
EndEnumeration

Define.l Event, EventWindow, EventGadget, EventType, EventMenu

Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 643, 30, 372, 288, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_0))
    EndIf
    ListIconGadget(#ListIcon_0, 20, 25, 335, 215, "N°",100, #PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    AddGadgetColumn(#ListIcon_0, 1, "Time", 100)
    AddGadgetColumn(#ListIcon_0, 2, "", 300)
    AddGadgetItem(#ListIcon_0, -1, "1" + Chr(10)+"13:20:25")
    AddGadgetItem(#ListIcon_0,  1, "2" + Chr(10)+"14:20:35")
    AddGadgetItem(#ListIcon_0,  2, "3" + Chr(10)+"15:20:25")
    AddGadgetItem(#ListIcon_0,  3, "4" + Chr(10)+"16:23:25")
    AddGadgetItem(#ListIcon_0,  4, "5" + Chr(10)+"20:23:25")
  EndIf
EndProcedure

Procedure GetTime_(Parameter)
  Repeat
    x=CountGadgetItems(#ListIcon_0) 
    time=Date()
    h=Hour(time) : m=Minute(time) : s=Second(time)
    For n=0 To x-1
      Debug GetGadgetItemText(#ListIcon_0,n,1)
      hl = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),1,2))
      ml = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),4,2))
      sl = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),7,2))
      If h>hl Or ( h=hl And m>ml ) Or (h=hl And m=ml And s>sl)
        SetGadgetItemText(#ListIcon_0,n,"L'heure a sonné",2)
      Else
        SetGadgetItemText(#ListIcon_0,n,"Pas encore",2)
      EndIf
    Next
    Delay(1000)
  ForEver
EndProcedure
OpenWindow_Window_0()
CreateThread(@ GetTime_(),255)
Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_CloseWindow
        CloseWindow(#Window_0)
  EndIf
ForEver

102
Dernière modification par brossden le mar. 24/févr./2009 8:15, modifié 1 fois.
Denis

Bonne Jounée à tous
SpaceMan
Messages : 290
Inscription : mar. 26/oct./2004 19:35
Contact :

Message par SpaceMan »

Bien vu Brossden ! ça marche au poil et très simple comme tu le dis :)
il faut juste mettre le Brek avant CloseWindow(#Window_0).
Merci encore
Un défaut qui empêche les hommes d’agir, c’est de ne pas sentir de quoi ils sont capables.
Jacques Bénigne Bossuet
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Spaceman a écrit :maintenant c'est à moi de décortiquer tout ça et je te promets que des questions vont jaillirent.
encore merci et bon après midi à toi
Je t'en prie. J'attends sereinement tes questions. Si tu veux décortiquer quelquechose, commence par le premier code, notamment la procédure AlarmCheckAll() et la Structure Alarm.

Aspect programmeur

Code : Tout sélectionner

Structure Alarm 
   *ResetAll ; Pointeur de procédure/Procédure de réinitialisation
   *CheckSyntax ; Idem/Vérifie la syntaxe de la date saisie
   *Ack ; Idem/Acquitte une alarme
   *AckAll ; Idem/Acquitte toutes les alarmes signalées
   *InputDate ; Idem/Saisie une date
   *CheckAll ; Idem/Boucle principale de vérification des alarmes
   *CloseAll ; Idem/Procédure de fermeture du programme
   *AvailableOne ; Idem/Retourne l'Index d'une alarme inutilisée
   *Set ; Idem/Modifie les caractéristiques d'une alarme
   *Reset ; Idem/Désactive une alarme
   *NewOne ; Idem/Ajoute une nouvelle alarme
   Start.L ; Mis à un : effectue une boucle d'affichage de toutes les alarmes
      ; Passe automatiquement à zéro pour vérifier les alarmes
   ListWin.L ; Numéro attribué à la fenêtre contenant les alarmes
   ListGdt.L ; Numéro attribué au gadget contenant les alarmes
   AckGdt.L ; Numéro attribué au gadget du bouton d'acquittement général
   Menu.L ; Numéro attribué au menu popup d'interface des alarmes
   MenuItem.L ; Item sélectionné par l'utilisateur
   Event.L ; Evénement en temps réel
   EventGdt.L ; Gadget subissant l'événement
   EventType.L ; Type d'événement produit
   HourSet.S ; Chaîne contenant la date et l'heure d'une alarme à modifier
        ; (avec AlarmSet() )
   StatSet.L ; Etat d'une alarme à modifier ( avec AlarmSet() )
   DateSys.L ; Heure (et date) système en secondes
   HmsSys.S ; Chaîne contenant l'heure système
   HourSys.L ; Heure système (en heures)
   MinuteSys.L ; Minutes système (en minutes)
   SecondSys.L ; Secondes système (en secondes)
   MaxQty.L ; Quantité maximum d'alarmes disponibles
   Index.L ; Dans le traitement individuel d'une alarme, n° de l'alarme traitée
   DateError.L ; Si =1 alors la syntaxe de la date saisie est mauvaise 
   RequestFlag.L ; Si =0 alors aucune requête ne fonctionne (pas de signalement, pas de modification d'alarmes possibles)
   *Hours ; Pointeurs vers la table des alarmes
EndStructure 
La table des alarmes contient les données nécessaires pour chaque alarme:

Code : Tout sélectionner

Structure AlarmSet 
   Ymd.S ; (Y+m+d = Year+Month+Day = Année+Mois+Jour
      ; sous la forme JJ/MM/AA)
   Year.L ; N° de l'année sous la forme AAAA (ex:2009)
   Month.L ; N° du mois
   Day.L ; N° du jour
   Hms.S ; (H+m+s = Heure + Minute + Seconde
     ; sous la forme HH:MM:SS)
   Hour.L ; N° de l'heure
   Minute.L ; N° de la minute
   Second.L ; N° de la seconde
   Stat.L ; Etat de l'alarme
     ; 0 = Inactive
     ; 1 = Active
     ; 2 = Signalée (L'utilisateur devra l'acquitter pour qu'elle soit à nouveau active)
EndStructure 
La procédure AlarmMain() contient quelque exemples d'alarme pré-programmées. ça te donne une idée de la manière simplissime de rajouter une alarme depuis le programme :

Code : Tout sélectionner

; Rajout d'une alarme 
   Alarm\HourSet = "21/02/09 21:02:00" 
   Alarm\StatSet = 0 ; Alarme inactive 
   AlarmNewOne(Alarm) 
Cette intervention peut avoir lieu N'IMPORTE OU dans ton programme. Tu peux appeler la procédure AlarmNewOne() de toutes les manière possibles:
AlarmNewOne(Alarm) ; Direct
CallFunctionFast(Alarm\NewOne, Alarm) ; Indirect
CreateThread(Alarm\NewOne, Alarm) ; Parallèle
Toutes les procédures peuvent être accessibles de cette manière si bien que ce programme est compatible avec une compilation en DLL.

Pour modifier une alarme:

Code : Tout sélectionner

; Modifier une alarme 
   Alarm\Index = 3 ; On modifie l'alarme n°3
   Alarm\HourSet = "21/02/09 21:02:00" 
   Alarm\StatSet = 1 ; Alarme active 
   AlarmSet(Alarm) 
Au démarrage, tu peux augmenter le nombre d'alarmes jusqu'à 256:

Code : Tout sélectionner

   ; Initialisation 
   Alarm\MaxQty = 256 ; 256 alarmes disponibles 
   AlarmResetAll(Alarm) 
Il y a d'autres options avec chacunes des procédures. Tu me questionneras si besoin.

Aspect utilisateur
Au démarrage, s'ouvre la fenêtre avec la liste des alarmes et un bouton d'acquittement général. Ce programme permet de régler et surveiller 16 alarmes différentes.

Process d'une alarme:
A) Inactive >>(Activer)>> Active
B) Active >>[SONNER]>> Signalée
C) Signalée >>(Acquitter)>> Active
D) Active >>(Désactiver)>> Inactive

Légende du process:
Etat initial >>(Action de l'utilisateur)>> Etat final
Etat initial >>[ACTION DE LA MACHINE]>> Etat final

Modifier une alarme:
1) Choisisr l'alarme à modifier
2) Clic bouton droit
3) Clic sur « Modifier l'horaire »
4) Une fenêtre s'ouvre et invite à saisir un horaire
>> Il respecter la syntaxe JJ/MM/AA HH:MM:SS
>> Syntaxe = Jour slash mois slash année espace heure 2points minutes 2points secondes
>> chaque nombre doit toujours avoir 2 chiffres. Rajouter un chiffre zéro à gauche si nécessaire. 1/1/9=Mauvais 01/01/09=Bon
5) Clic sur Ok
6) Si la syntaxe de la date est invalide, une fenêtre s'ouvre et indique une erreur de syntaxe de la date. Il faut alors revenir à l'étape 1
Si la date de la syntaxe est valide, cette date s'affiche désormais dans la liste.

Activer une alarme:
1) Choisir l'alarme à activer
2) Clic bouton droit
3) Clic sur « Activer »

Une alarme s'est mise en route
Dans ce cas, une fenêtre s'ouvre et indique quel est le numéro de l'alarme concernée. Cliquer sur Ok.
L'alarme n'est plus active. Elle est désormais Signalée.

Acquitter une alarme signalée:
1) Choisir l'alarme à acquitter
2) Clic bouton droit
3) Clic sur « Acquitter »
L'horaire de l'alarme est reporté à 24H (incrémentation d'une journée)
L'alarme est à nouveau active.

Acquitter toutes les alarmes signalées:
Pour éviter une action trop laborieuse pour acquitter toutes les alarmes, cliquer sur le bouton « Acquitter toutes les alarmes signalées »
Toutes les alarmes signalées sont à nouveau actives après une incrémentation automatique de 24 heures.

Désactiver une alarme:
1) Choisir l'alarme à désactiver
2) Clic bouton droit
3) Clic sur « Désactiver »
L'alarme est désormais inactive.
SpaceMan
Messages : 290
Inscription : mar. 26/oct./2004 19:35
Contact :

Message par SpaceMan »

On dirait qu'il n'y aura plus de question... :lol:
je propose que Dobro mette ce poste dans les tutos tellement c'est bien expliqué qu'un n'importe qui pourrait comprendre avec un peu de volonté..
:D
Un défaut qui empêche les hommes d’agir, c’est de ne pas sentir de quoi ils sont capables.
Jacques Bénigne Bossuet
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Spaceman a écrit :On dirait qu'il n'y aura plus de question...
je propose que Dobro mette ce poste dans les tutos tellement c'est bien expliqué qu'un n'importe qui pourrait comprendre avec un peu de volonté..
:? C'est moyen comme tutoriel pour un débutant...

Sinon, il faudra que tu fasses attention à la mise en veille de l'OS!
SpaceMan
Messages : 290
Inscription : mar. 26/oct./2004 19:35
Contact :

Message par SpaceMan »

Ollivier a écrit :
Spaceman a écrit :On dirait qu'il n'y aura plus de question...
je propose que Dobro mette ce poste dans les tutos tellement c'est bien expliqué qu'un n'importe qui pourrait comprendre avec un peu de volonté..
:? C'est moyen comme tutoriel pour un débutant...

Sinon, il faudra que tu fasses attention à la mise en veille de l'OS!
Ouais c'est pas aussi facile à assimiler...
Un défaut qui empêche les hommes d’agir, c’est de ne pas sentir de quoi ils sont capables.
Jacques Bénigne Bossuet
SpaceMan
Messages : 290
Inscription : mar. 26/oct./2004 19:35
Contact :

Message par SpaceMan »

salut à tous !
voilà je reviens avec des questions sur le code de Brossden.
si le code doit afficher un message du genre "il est l'heure" dans un requester chaque fois qu'il y aura correspondance, dois-je obligatoirement les mots:PauseThread, ResumeThread... ? sinon quelqu'un aurait une autre solution ?

Code : Tout sélectionner

Enumeration 
  #Window_0 : #StatusBar_Window_0 : #ListIcon_0 
EndEnumeration 

Define.l Event, EventWindow, EventGadget, EventType, EventMenu 

Procedure OpenWindow_Window_0() 
  If OpenWindow(#Window_0, 643, 30, 372, 288, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar) 
    If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_0)) 
    EndIf 
    ListIconGadget(#ListIcon_0, 20, 25, 335, 215, "N°",100, #PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect) 
    AddGadgetColumn(#ListIcon_0, 1, "Time", 100) 
    AddGadgetColumn(#ListIcon_0, 2, "", 300) 
    AddGadgetItem(#ListIcon_0, -1, "1" + Chr(10)+"01:33:05") 
    AddGadgetItem(#ListIcon_0,  1, "2" + Chr(10)+"01:28:10") 
    AddGadgetItem(#ListIcon_0,  2, "3" + Chr(10)+"01:28:25") 
    AddGadgetItem(#ListIcon_0,  3, "4" + Chr(10)+"01:28:25") 
    AddGadgetItem(#ListIcon_0,  4, "5" + Chr(10)+"01:28:35") 
  EndIf 
EndProcedure 

Procedure GetTime_(Parameter) 
  Repeat 
    x=CountGadgetItems(#ListIcon_0) 
    time=Date() 
    h=Hour(time) : m=Minute(time) : s=Second(time) 
    For n=0 To x-1 
      Debug GetGadgetItemText(#ListIcon_0,n,1) 
      hl = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),1,2)) 
      ml = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),4,2)) 
      sl = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),7,2)) 
      If h>hl Or ( h=hl And m>ml ) Or (h=hl And m=ml And s>sl) 
        SetGadgetItemText(#ListIcon_0,n,"L'heure à sonné",2)
          ;PauseThread(MonThread)
          MessageRequester("AutoStart","Il est l'heure !");ce message doit d'afficher une seule fois
          ;ResumeThread(MonThread)
      Else  
        SetGadgetItemText(#ListIcon_0,n,"Pas encore",2) 
      EndIf  
     Next 
    Delay(1000) 
  ForEver 
EndProcedure 
OpenWindow_Window_0() 
MonThread = CreateThread(@ GetTime_(),255) 



Repeat 
  Event = WaitWindowEvent() 
  If Event = #PB_Event_CloseWindow 
        CloseWindow(#Window_0) 
          Break
   EndIf 
ForEver
Un défaut qui empêche les hommes d’agir, c’est de ne pas sentir de quoi ils sont capables.
Jacques Bénigne Bossuet
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Afficher "l'heure a sonnée" si correspondance il y

Message par Ollivier »

Yop l'équipe, ce code fonctionne-t-il en dernière version? Ou bien une màj?
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Afficher "l'heure a sonnée" si correspondance il y

Message par falsam »

Ollivier a écrit :Yop l'équipe, ce code fonctionne-t-il en dernière version? Ou bien une màj?
4.31 et 4.40 pas de souci
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Afficher "l'heure a sonnée" si correspondance il y

Message par nico »

@Spaceman

Voilà ce que tu demandes, j'ai légèrement modifié la procédure GetTime(...)

Code : Tout sélectionner

Enumeration
  #Window_0 : #StatusBar_Window_0 : #ListIcon_0
EndEnumeration

Enumeration #PB_Event_FirstCustomValue
  #EvenementHorloge
EndEnumeration

Define.l Event, EventWindow, EventGadget, EventType, EventMenu

Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 643, 30, 372, 288, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_0))
    EndIf
    ListIconGadget(#ListIcon_0, 20, 25, 335, 215, "N°",100, #PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    AddGadgetColumn(#ListIcon_0, 1, "Time", 100)
    AddGadgetColumn(#ListIcon_0, 2, "", 300)
    AddGadgetItem(#ListIcon_0, -1, "1" + Chr(10)+"22:43:25")
    AddGadgetItem(#ListIcon_0,  1, "2" + Chr(10)+"22:43:35")
    AddGadgetItem(#ListIcon_0,  2, "3" + Chr(10)+"22:44:25")
    AddGadgetItem(#ListIcon_0,  3, "4" + Chr(10)+"22:45:25")
    AddGadgetItem(#ListIcon_0,  4, "5" + Chr(10)+"22:46:25")
  EndIf
EndProcedure

Procedure GetTime_(Parameter)
  Repeat
    time=Date()
    x=CountGadgetItems(#ListIcon_0) 
    
    For n=0 To x-1
      Debug GetGadgetItemText(#ListIcon_0,n,1)
      hl = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),1,2))
      ml = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),4,2))
      sl = Val(Mid(GetGadgetItemText(#ListIcon_0,n,1),7,2))
      Resultat = Date(Year(time), Month(time), Day(time), hl, ml, sl)
      
      If Resultat <= time
        If GetGadgetItemText(#ListIcon_0,n,2) <> "L'heure a sonné"
          SetGadgetItemText(#ListIcon_0,n,"L'heure a sonné",2)
          PostEvent(#EvenementHorloge)
        EndIf
      Else
        SetGadgetItemText(#ListIcon_0,n,"Pas encore",2)
      EndIf
    Next
    
    Delay(1000)
  ForEver
EndProcedure

OpenWindow_Window_0()

CreateThread(@ GetTime_(),255)
Repeat
  Event = WaitWindowEvent()
  Select Event 
    Case #EvenementHorloge
      MessageRequester("AutoStart","Il est l'heure !");ce message doit d'afficher une seule fois
      
    Case #PB_Event_CloseWindow
      CloseWindow(#Window_0)
      End 
  EndSelect
ForEver
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Afficher "l'heure a sonnée" si correspondance il y

Message par Ar-S »

+1 pour le timer en se qui concerne les alarmes / chronos
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Afficher "l'heure a sonnée" si correspondance il y

Message par Mesa »

@dobro:
il y a pas mal de temps , je me suis fait un prg d'alerte...
Alors pourquoi tu ne le partages pas ? 8O
Le forum est fait pour ça non ? :roll:

Sauf erreur, le timergadget utilise déjà un thread.
Voici donc une solution sans thread et qui consomme quasi zéro de temps processeur.
Pour info, il ne faut pas utiliser un messagerequester dans ce cas là, voir explications dans le code.
J'ai aussi utilisé des fonctions auxquelles on ne pense jamais et qui sont bien utiles ici (SetGadgetData, SetGadgetItemData

Code : Tout sélectionner

Enumeration fenetre
  #Window_Principale : #Window_Alerte
EndEnumeration; pas la peine de créer des numéros de gadgets inutiles
Enumeration gadget
  #StatusBar_Window_0 : #ListIcon_0 : #TexteAlerte
EndEnumeration 
Enumeration timer; pas la peine de créer des numéros de timers inutiles
  #Timer
EndEnumeration
Enumeration #PB_Event_FirstCustomValue
  #EvenementHorloge
EndEnumeration

Global Compteur=0, Delai=800

Define.l Event, EventWindow, EventGadget, EventType, EventMenu
Declare Alerte(Parameter)
  
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_Principale, 643, 30, 372, 288, "Minuterie", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_Principale))
      AddStatusBarField(#PB_Ignore)
    EndIf
    ListIconGadget(#ListIcon_0, 20, 25, 335, 215, "N°",100, #PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
    AddGadgetColumn(#ListIcon_0, 1, "Time", 100)
    AddGadgetColumn(#ListIcon_0, 2, "", 300)
    DateEnCours=Date()
    tmpHeure=DateEnCours ; on garde, ça peut servir
    For i=0 To 4
      tmpHeure= AddDate(tmpHeure, #PB_Date_Minute, 1)
      tmpHeure$=FormatDate("%hh:%ii:%ss", tmpHeure)
      AddGadgetItem(#ListIcon_0, i, Str(i+1) + Chr(10)+tmpHeure$)
      SetGadgetItemData(#ListIcon_0, i, tmpHeure)
    Next i
  EndIf
  SetGadgetData(#ListIcon_0,GetGadgetItemData(#ListIcon_0, 0))
  
  AddWindowTimer(#Window_Principale,#Timer,Delai);
EndProcedure
Procedure OpenWindow_Alerte()
  If OpenWindow(#Window_Alerte, 0, 0, 200, 100, "Alerte", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_NoActivate|#PB_Window_Invisible )
    ; Avec un webgadget on peut afficher un GIF animé
    ; Avec un canvasgadget, on peut créer sa propre animation, pour attirer l'oeil
    TextGadget(#TexteAlerte, 0, 35, 200, 30, "Il est l'heure !", #PB_Text_Center)
  EndIf
   StickyWindow(#Window_Alerte, #True) 
EndProcedure
Procedure Alerte(Parameter)

  SetWindowData(#Window_Principale,GetWindowData(#Window_Principale)+Delai)

  progression=100*GetWindowData(#Window_Principale)/60000; ici je triche, je sais que le delta entre 2 dates est de 1min mais il faudrait le calculer
  StatusBarProgress(#StatusBar_Window_0, 0, progression)
  
  If 	Date()=GetGadgetData(#ListIcon_0)
    SetGadgetItemText(#ListIcon_0,Parameter,"L'heure a sonné",2) 
    
    Compteur=Compteur + 1
    SetGadgetData(#ListIcon_0,GetGadgetItemData(#ListIcon_0, Compteur))
    SetWindowData(#Window_Principale,0)
    ;     MessageRequester("AutoStart","Il est l'heure !")
    ; ne pas utiliser de requester car ils sont bloquant, ce qui ne convient pas ici
    ; car le timer doit poursuivre son compte même après l'affichage d'une alerte
    ; il faut donc créer son propre requester non bloquant avec une simple fenêtre
    ; Dans ce cas le gadget MDI est à essayer !
    
    HideWindow(#Window_Alerte,#False,#PB_Window_NoActivate |#PB_Window_ScreenCentered)
   
  EndIf

EndProcedure

OpenWindow_Window_0()
OpenWindow_Alerte()

Repeat
  Event = WaitWindowEvent()
  

  Select Event 
    Case #PB_Event_Timer
      If EventTimer()=#Timer
Alerte(Compteur)
    EndIf
    
  Case #PB_Event_CloseWindow
    If EventWindow() =#Window_Principale
      CloseWindow(#Window_Principale)
      End 
    Else
      HideWindow(#Window_Alerte,#True)
      EndIf
  EndSelect
ForEver
M.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Afficher "l'heure a sonnée" si correspondance il y

Message par Ollivier »

@mesa

je comprends ton effort et ton code est très bien, celui de nico aussi, celui de Brossden aussi. Seulement, après l'intervention de Brossden, je me suis bien pris la tête à rédiger une bonne doc explicative, pour faire comprendre ce que le code source était en capacité d'exécuter, et dont voici deux extraits :
Au démarrage, tu peux augmenter le nombre d'alarmes jusqu'à 256:

Code : Tout sélectionner

; Initialisation
Alarm\MaxQty = 256 ; 256 alarmes disponibles
AlarmResetAll(Alarm)
Cette intervention peut avoir lieu N'IMPORTE OU dans ton programme. Tu peux appeler
la procédure AlarmNewOne() de toutes les manière possibles:
AlarmNewOne(Alarm) ; Direct
CallFunctionFast(Alarm\NewOne, Alarm) ; Indirect
CreateThread(Alarm\NewOne, Alarm) ; Parallèle
Toutes les procédures peuvent être accessibles de cette manière si bien que ce
programme est compatible avec une compilation en DLL.
Voilà, c'est écrit noir sur blanc depuis huit ans. Ceux qui ne comprennent pas par inadvertance, ça n'est franchement pas grave.

Mais je viens de lire un message d'une personne capable de faire croire que le nombre "256" s'écrivait comme ceci : "2 ou 3".

Si c'était le cas, il avait huit années pour prouver la véracité de sa maladresse.

Ainsi, PAPIPP a bien raison, et sans avoir même à modifier la moindre virgule dans mes messages de 2009 ci-dessus. Ça se voit d'ailleurs. :o
On peut gérer logiciellement la sécurité des threads.

Bonne lecture
Répondre