Les CALLBACKS ...............célebres inconnues

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Les CALLBACKS ...............célebres inconnues

Message par Kwai chang caine »

Bonjour la famille

Je trouve que en general dans nos forum on ne parle pas beaucoup des CALLBACKS.

Et pourtant elles jouent un role essentiel dans la plupart de vos codes, donc par l'autruchement des miens, puisque je vous les copie :oops:

D'ailleur à ce propos, je tiens à nouveau et pour la Xieme fois vous remercier de vos aides nombreuses et rapide. Je ne me lasse pas de le faire, et j'aime bien vous remercier pour rien car vous le méritez bien.

Bon, cirage de pompe bien mérité donc passé :D, j'aimerais savoir si on peut en faire autant qu'un curé peut en bénir :D
C'est à dire "en poussant le bouchon un peu loin maurice" créer une procedure callback et un appel par gadget.

Ou bien ceci est dangereux et peut perturber notre meilleur ami, j'ai nommé "POLINK"

Si au passage, quelqu'un connait un TUTO sur cette merveille, et par miracle en français, un lien serait le "bienvenue chez moi".

Encore merci pour tout
Bonne journée
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Tu peux utiliser autant de callback que tu veux, il n'y a rien de miraculeux derrière, c'est comme appeler une fonction mais au lieu de l'appeler via son nom, tu l'appels via son adresse (sur fonction, justement).
A noter que cela n'est pas lié aux gadget.
Pour les tutos, google, comme d'hab.
"Qui baise trop bouffe un poil." P. Desproges
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Merci de ta reponse KARLKOX 8)

J'ai cru un instant que j'etais le seul a voir mon POST dans le forum :D

Donc pas de limite, impecable.
C'est quand meme un peu plus puissant qu'une procedure car ça interviens avant qu'un evenement ne s'effectue, c'est pas ça ???

Donc d'apres toi, si je fais un windowevent #Mouse_MOVE c'est exactement comme si je met dans la callback case #WM_MouseMove ou bien une sera toujour executée avant l'autre ????
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Comme je te l'ai dit, les callbacks ne sont pas propre aux évenements, elles n'ont d'ailleurs rien à voir, elles sont justes indispensables car c'est le mécanisme interne de windows qui "oblige" de passer ainsi pour trapper les évenements :

- windows "oblige" le programmeur à définir une fonction callback,
- windows récupère l'adresse de fonction,
- pour toutes les applis tournant en mode gui, envoye tous les évenements qu'il traite,
- windows appelle cette fonction avec les params de l'évenement en cours,
- dans cette fonction de rappel tu appels callwindowproc pour dire à windows de continuer à traiter les messages suivant <-- d'où la fonction de rappel. (windows callback)
"Qui baise trop bouffe un poil." P. Desproges
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

C'est quand meme un peu plus puissant qu'une procedure car ça interviens avant qu'un evenement ne s'effectue, c'est pas ça ???
En fait le callback te permet d'intercepter l'évènement avant qu'elle n'arrive dans la boucle d'évènement de la fenêtre.

Mais quel est l'intérêt puisque de toute façon le message arrivera dans notre boucle d'évènement?

Eh bien la boucle d'évènement de Pure ne permet pas de recevoir tous les messages, si tu envoie un message par la commande Sendmessage_(..), tu ne la recevras pas alors qu'avec un callback tu es sûr de récupérer tous les évènements et ça reste plus facile de travailler avec un callback.
Donc d'apres toi, si je fais un windowevent #Mouse_MOVE c'est exactement comme si je met dans la callback case #WM_MouseMove ou bien une sera toujour executée avant l'autre ????
Oui c'est pareil; ce sera toujours le callback qui recevra le message en premier; en traitant ce message et en renvoyant un procedurereturn 0, tu cloture le traitement du message et ta boucle ne le recevras pas sinon le message seras traité deux fois, suivant les besoins ça peut être l'un ou l'autre.

J'ai découvert un de tes posts précédent ayant pour titre" Callback <--> Subclassing"
J'ai toujours pensé qu'un setwindowcalback effectuait un subclassing mais je peux me tromper, mais bon dans ce cas là ça revient au même.

Pure basic ne permet de subclasser que des fenêtres, mais ce qui est intéressant c'est surtout de pouvoir subclasser les controles (gadget).
Car un controle, c'est une fenêtre qui a elle aussi une boucle d'évènement et qui régit son comportement et à la différence d'une fenêtre tu n'as pas accès à celle-ci d'où l'intérêt du subclassing pour modifier le comportement d'un controle.

Regarde cet exemple, je subclasse le StringGadget 0 pour que lorsque je tape Enter je passe au gadget suivant:

Code : Tout sélectionner

Procedure NouvelleProc( hWnd, Msg,  wParam, lParam)
  ;Ici on récupère l'adresse d'origine de la procédure grâce à la
  ;chaine qui l'identifie: "OriginProc" et le handle de la fenêtre
  ;voir la fonction SetProp.
  OriginProc.l= GetProp_(hWnd, "OriginProc")
  Select Msg
    Case #wm_char
      If wParam=$0D
        ;Simulation de la touche Tab
        keybd_event_($09, 0, 0, 0)
        keybd_event_($09, 0, #KEYEVENTF_KEYUP, 0)
        ProcedureReturn 0
      EndIf
  EndSelect
  ;On renvoie tous les autres évènements à la procédure d'origine.
  ProcedureReturn CallWindowProc_(OriginProc,hWnd,Msg,wParam,lParam)
EndProcedure   

If OpenWindow(0,0,0,322,275,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"StringGadget Flags") And CreateGadgetList(WindowID(0))
  StringGadget(0,8, 10,306,20,"Normal StringGadget...")
  StringGadget(1,8, 35,306,20,"1234567",#PB_String_Numeric)
  StringGadget(2,8, 60,306,20,"Readonly StringGadget",#PB_String_ReadOnly)
 
  ;Avec cette fonction, on récupère l'adresse d'origine de la procédure
  ;pour ensuite la restituer, une fois le traitement terminé.
  OriginProc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @NouvelleProc())
 
  ;Cette fonction est très utile car elle permet d'associer une nouvelle donnée
  ;à n'importe quelles fenêtres crées en utlisant une chaine de caractère pour
  ;l'identification; ça évite d'utiliser une valeur globale.
  ;Ici on associe la valeur OriginProc identifiée par la chaine "OriginProc"
  ;au StringGadget
  SetProp_(GadgetID(0), "OriginProc", OriginProc)
 
  Repeat
    EventID = WaitWindowEvent()
    Select EventID
      Case  #PB_EventGadget
        Select EventGadgetID()
          Case 0
            Debug "Normal StringGadget"
           
        EndSelect
       
      Case #WM_CLOSE
        ;Supprimer avant fermeture du programme la donnée associée à la fenêtre.
        RemoveProp_(GadgetID(0),"OriginProc")
        Quit=1
       
    EndSelect
   
  Until Quit=1
EndIf
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Je commence à entrevoir une led au fin fond du brouillard :D

En fait, ça me fait toujours un peu peur de les utiliser, quand on voit la puissance ....

Et j'avais peur qu'elles se melange les pinceaux :D

Car lorsque vous partagez vos génials codes, y'en a souvent, et donc il faut mettre parfois es "CASE" des callback de chacun de vos codes ensembles, et moi je suis pour l'amour et pas la guerre, et j'ai toujours peur, comme je comprend pas toujours tout, voir meme que je comprend toujours pas tout, donc peur qu'elles se genent.

Mais apparement d'apres vos dires mes craintes sont infondées.

Merci de vos explications sur cette merveille 8)

Je vous souhaite une bonne nuit
poshu
Messages : 1138
Inscription : sam. 31/juil./2004 22:32

Message par poshu »

Mince, ton exemple de subclassing m'aide pas mal, merci Nico.
kerkael
Messages : 97
Inscription : mer. 03/sept./2008 21:08

Message par kerkael »

Bon, j'ai pas tout compris.

Au fait, en version courante, 4.20, le code ne passe pas.
OpenWindow attend le titre avant les options :

Code : Tout sélectionner

If OpenWindow(0,0,0,322,275,"StringGadget Flags",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
#PB_EventGadget s'appelle maintenant

Code : Tout sélectionner

Case  #PB_Event_Gadget
et Select EventGadgetID() doit être remplacé par

Code : Tout sélectionner

Select EventGadget()
.

Je sais pas quoi faire de des callback ...
Répondre