Retour de procedure multi-variables

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

Retour de procedure multi-variables

Message par Ulix »

Boujour a tous,

Je désirerais vous faire pars d'une de mes astuces (j'espéres que personne ne la connait, sinon c'est a l'eau).
Comment en retour d'un procédure obtenir plusieurs données de différents type sans utilisé de structure ni pointeur(trop facile, heuuuu, pas sûr), ni utilisé de variable globale ?

Essayez ce code, et dit moi ce que vous en pensé :lol:

Code : Tout sélectionner


Enumeration
  #Fenetre
  #Cadre1:#Texte1:  #Button1
  #Cadre2:#Texte2:#Editor:  #Button2
EndEnumeration
 
 Procedure.s ProcedureTartanpion(Rang.b)
 ;Le but de cette procedure pour l'exemple est de renvoyer a partir du numéro de rang, 
 ;des données (ici de différent type) en une seule fois.
  
 ;traitement quelconque
 Select Rang
 			Case 1	 :	Enregistrement.l=5654		:Nom$="Zébulon"		:Age.b=45	:Taille.f=182.567
			Case 2	 :	Enregistrement.l=523058	:Nom$="Margotte"	:Age.b=21	:Taille.f=122.081
 			Case 3	 :	Enregistrement.l=1			:Nom$="Emboise"	:Age.b=18	:Taille.f=4.789
			Case 4	 :	Enregistrement.l=23446567:Nom$="Azalé"		:Age.b=78	:Taille.f=123422.081
 			Case 5	 :	Enregistrement.l=78341169:Nom$="Polux"		:Age.b=6	:Taille.f=0.864
EndSelect
;Comment renvoyer, dans cette exemple le numero d'enregistrement, le nom, l'age et la taille ????
;Tous cela en une seule fois, sans utilisé de structure avec un pointeur . D'autant plus que s'il y a beaucoup 
;de procedure cela risque de faire beaucoup de structure avec leurs pointeurs. Pas facile a gérer !
;Il reste la possibilité de déclarer toutes les variables en globales. C'est vite la zone. Beaucoup de variables
;ne sont utilisé que pour une procédure, ce qui augmente le nombre de variables globale inutilement.

;Voici la solution que j'utile, j'ai utilisé pour cette exemple des variable de tous type
;Le principe c'est de former une chaine de caractére de long fixe (selon vos besoin, ici 40 ) pour chacune des variables
;puis des les regroupé en une seule qui sera renvoyer par la fonction

Texte$=LSet(StrU(Enregistrement, #Long), 	40) 	;	pour le numero d'enregistrement
Texte$+LSet(Nom$, 	40)									;	pour le nom
Texte$+LSet(Str(Age), 	40)								;	pour l'age
Texte$+LSet(StrF(Taille),	40)							;	pour la taille
	
ProcedureReturn Texte$ 		;     	renvoi de la valeur


 EndProcedure

Titre$="Une astuce a Ulix"
If OpenWindow(#Fenetre, 216, 0, 583, 283,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , Titre$)
    If CreateGadgetList(WindowID())
      Frame3DGadget(#Cadre1, 5, 10, 570, 115, "Avant la procedure")
      TextGadget(#Texte1, 25, 35, 400, 70, "", #PB_Text_Border)
      
      ButtonGadget(#Button1, 440, 55, 115, 50, "Appel procedure",#PB_Button_MultiLine)
     
      Frame3DGadget(#Cadre2, 5, 150, 570, 125, "Retour de procedure") 
      ButtonGadget(#Button2,  35, 190, 115, 50, "Ferme")
      TextGadget(#Texte2, 30, 185, 130, 30, "")
      EditorGadget(#Editor, 215, 175, 300, 80)
   EndIf
  EndIf
 
 
 Texte$="Comment recevoir en retour d'une procédure plusieurs valeurs de type différente"+Chr(10)
 Texte$+"Tous cela en une seule fois, sans utilisé de structure, ni pointeur (pas facile a gérer)"+Chr(10)
 Texte$+"Il reste la possibilité de déclarer toutes les variables en globales. -  C'est vite la zone."+Chr(10)
 Texte$+"Beaucoup de variables ne sont utilisé que pour une procédure, ce qui augmente le"+Chr(10)
 Texte$+"nombre de variables globale inutilement. Essayé Appel procedure pour voir le retour"
 
 
 SetGadgetText(#Texte1, Texte$)
 Valeur.b=0 ; variable locale
 
 Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget ; Evenement gadget
          Select EventGadgetID(); retourne le numero du gadget
          		Case  #Button2 : CloseWindow(#Fenetre):End
          		Case  #Button1
		          		
		          		Valeur+1 : SetGadgetText(#Button1, "Appel procedure  Valeur demandé "+Str(valeur))
		          		If valeur>5:valeur=1:EndIf
		          		
		          		Retour$=ProcedureTartanpion(valeur); ici appelle de la procedure
										          		
		          										If Retour$="" ;	vide
		          										 			;TraitementQuelconque() ;message or ProcedureReturn
		          										
										          		Else ; il y a quelque chose
										          					;De retour de la procédure il suffit de la redécomposés 
					          										;la chaine de Retour$ en ces variables d'origines
										          					;il suffit de respecté l'ordre (des variables) le type des variables 
					          										;la position (dans Mid() ) et la longueur ( ici 40 )
					          										UnEnregistrement.l	=	Val(RTrim(Mid(Retour$,1,40)))
										          					UnNom$	=	RTrim(Mid(Retour$,41,40))
					          										UnAge.b	=	Val(RTrim(Mid(Retour$,81,40)))
										          					UneTaille.f	=ValF(RTrim(Mid(Retour$,121,40)))
					          										;Noté que les variables reste locale (dans cette exemple) pour le code 
										          					;qui appelle la procédure, et sont locale aussi pour la procédure appellé
					          										;La liste des variables ainsi renvoyer n'est limité comme que par la taille de retour$
					          										
										          					;affichage pour l'exemple
					          										ClearGadgetItemList(#Editor)
										          					AddGadgetItem(#Editor, -1, "Numéro d'enregistrement : "+Str(UnEnregistrement))
																	AddGadgetItem(#Editor, -1, "Nom de la personne : "+UnNom$)
																	AddGadgetItem(#Editor, -1, "Age de la personne  : "+Str(UnAge))
																	AddGadgetItem(#Editor, -1, "Taile de la personne : "+StrF(UneTaille))

										          		EndIf ; fin test de retour
		           		          		
          EndSelect
          
Case #PB_EventCloseWindow
          CloseWindow(#Fenetre)
EndSelect
ForEver 
End

nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Renvoyer une chaine contenant les valeurs, ça déjà été évoqué mais avec un délimitateur.

Je préfère les pointeurs avec les structures.
Avec cette méthode, on doit pouvoir envoyer un nombre illimité de données non définies avec des types non définies à l'avance, le must quoi.
LeCyb
Messages : 273
Inscription : dim. 26/déc./2004 20:49

Message par LeCyb »

Je préfère les pointeurs c'est plus clair et y'a moins d'instructions.

Mais on va dire que ton idée a le mérite d'exister :D
Vive le thread-safe !
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

Message par Ulix »

Tant pis, :( c'est a l'eau, brrrrr elle est pas trés chaude !

Mais je continue a nager... :wink:

a+
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Moi aussi je préfère les pointeurs et passer des adresses en paramètres, etc...

Bonne idée qd mm, mais si le principe du délimiteur est à privilégier (je pense) :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Répondre