Page 1 sur 1

Re: [R] Récupérer sélection dans divers Edit

Posté : jeu. 04 févr. 2021 16:31
par GMH
Bonjour,

Je souhaite récupérer un mot sélectionné dans l'un ou l'autre édit de ma fenêtre.

Lorsque j'entre un mot dans l'édit 1 et que je le sélectionne, tout se passe bien, la sélection est bien récupérée.
Lorsque j'entre un mot dans l'édit 2 et que je le sélectionne, la sélection n'est pas récupérée.

Après avoir sélectionné puis récupéré un mot dans l'édit 1, et qu'à la suite je tente de récupérer un mot de l'édit 2, c'est toujours la sélection de l'édit 1 qui est récupérée alors que le mot n'est plus sélectionné.

Voyez-vous où mon code pèche ?

Je vous remercie de votre aide.
Opt("GUIOnEventMode", 1)  ; Passe en mode événement
   Global $maGui = GUICreate("test sélection", 600, 300, -1, -1)
   GuiSetOnEvent(-3, "_Close", $maGui)
   Global $edit1 = GUICtrlCreateEdit("",20,20,500,50)
   Global $edit2 = GUICtrlCreateEdit("",20,90,500,50)
   GUICtrlCreateButton("Test", 100, 160, 60, 20)
   GUICtrlSetOnEvent(-1,"resultat")
GUISetState(@SW_SHOW)
While 1
   Sleep(1000)
WEnd

Func resultat()
   Local $selection = ""
   $selection = ControlCommand("", "", $edit1, "GetSelected", "") ; récupère la sélection de $edit1
   If ($selection == "") Then $selection = ControlCommand("", "", $edit2, "GetSelected", "") ; récupère la sélection de $edit2
   If ($selection <> "") Then
      MsgBox(0,"","Le mot sélectionné est : " & $selection)
   Else
      MsgBox(48,"Attention !","Sélectionnez le mot à rechercher !")
   EndIf
EndFunc

Func _Close()
   Exit
EndFunc

Re: [..] Récupérer sélection dans divers Edit

Posté : jeu. 04 févr. 2021 16:57
par TommyDDR
Vous êtes dans un cas un peu compliqué à comprendre sans debugger car il fait intervenir 2 règles peu explicites :

1) ControlCommand avec un GetSelected retournera 0 (Int32, pas String) si rien n'a été trouvé.
2) Comparer un Int32 avec un String avec le symbole "=" implique une conversion implicite du String en Int (la plupart du temps il sera = à 0)
3) Comparer un Int32 avec un String avec le symbole "==" retournera toujours false (== -> comparaison sensible à la case et sensible au type)

Donc votre GetSelected vous renvoie un Int32 de valeur 0
Vous testez si le Int32 est égal au String vide avec "==" donc false -> on ne va pas vérifier le 2eme edit et on a toujours Int32 : 0 dans $selection
Vous testez si le Int32 contenant 0 est différent de la chaine vide avec "<>" non sensible au type ni à la case donc le string est converti en 0, comme ils sont égaux, on n'entre pas dans le if et on va dans le else -> hop, votre message d'erreur.

Si vous avez un comportement de la sorte la prochaine fois, essayez de debugger en suivant le cheminement inverse :
Vous avez le message, donc on est dans le else de -> $selection <> "", donc $selection est égal à la chaine vide.
Ça veut dire que le GetSelected à retourné une chaine vide, ce qui est étrange car quelque chose était sélectionné, donc la ligne n'a pas du être exécutée
Si elle n'a pas été exécutée c'est que la condition d'exécution n'a pas été remplie donc à la sortie du 1er ControlCommand, on avait bien un retour
La conclusion c'est que c'est étrange, du coup vous mettez un ConsoleWrite($selection & @CRLF) juste après le 1er appel à ControlCommand pour voir ce qui est réellement rangé dans la variable, et... TADA, vous voyez un "0".

(Si vous voulez allez plus loin, vous faites un ConsoleWrite(VarGetType($selection) & @CRLF) et vous verrez que le type est un Int32 et vos nouvelles connaissances vous feront vous dire "Hum, il y a une conversion implicite !")

Pour corriger votre problème :
Passez le "==" en "=" ou forcez la conversion du Int en String ou utilisez IsInt :
If ($selection = "") Then $selection = ControlCommand("", "", $edit2, "GetSelected", "")
If (String($selection) == "") Then $selection = ControlCommand("", "", $edit2, "GetSelected", "")
If (IsInt($selection)) Then $selection = ControlCommand("", "", $edit2, "GetSelected", "")
De mon point de vue, la 3ème solution est la meilleure.

Re: [..] Récupérer sélection dans divers Edit

Posté : jeu. 04 févr. 2021 17:33
par GMH
Grand merci pour votre longue réponse.
Je pensais que le contenu de la variable $selection était un string, puisque je sélectionnais une chaîne de caractères. Etonnant ce zéro !

J'ai corrigé comme ci-dessous. Tout va très bien sauf si je commence par tester une sélection dans l'édit 1 puis, si à la suite, je teste une sélection dans l'édit 2. Comme résultat au deuxième test, j'obtiens encore et toujours la première sélection opérée dans l'édit 1.

Code : Tout sélectionner

Opt("GUIOnEventMode", 1)  ; Passe en mode événement
	Global $maGui = GUICreate("test sélection", 600, 300, -1, -1)
	GuiSetOnEvent(-3, "_Close", $maGui)
	Global $edit1 = GUICtrlCreateEdit("",20,20,500,50)
	Global $edit2 = GUICtrlCreateEdit("",20,90,500,50)
	GUICtrlCreateButton("Test", 100, 160, 60, 20)
	GUICtrlSetOnEvent(-1,"resultat")
GUISetState(@SW_SHOW)
While 1
	Sleep(1000)
WEnd

Func resultat()
	Local $selection = 0
	$selection = ControlCommand("", "", $edit1, "GetSelected", "") ; récupère la sélection de $edit1
	If (IsInt($selection)) Then $selection = ControlCommand("", "", $edit2, "GetSelected", "")  ; récupère la sélection de $edit2
	If (IsInt($selection)) Then
		MsgBox(48,"Attention !","Sélectionnez le mot à rechercher !")
	Else
		MsgBox(0,"","Le mot sélectionné est : " & $selection)
	EndIf
EndFunc

Func _Close()
   Exit
EndFunc

Re: [..] Récupérer sélection dans divers Edit

Posté : jeu. 04 févr. 2021 22:06
par mikell
Ah mais ça c'est juste parce qu'il faut faire du ménage :mrgreen:
Enfin, réinitialiser, quoi

#include <EditConstants.au3>

Opt("GUIOnEventMode", 1)  ; Passe en mode événement
   Global $maGui = GUICreate("test sélection", 600, 300, -1, -1)
   GuiSetOnEvent(-3, "_Close", $maGui)
   Global $edit1 = GUICtrlCreateEdit("",20,20,500,50)
   Global $edit2 = GUICtrlCreateEdit("",20,90,500,50)
   GUICtrlCreateButton("Test", 100, 160, 60, 20)
   GUICtrlSetOnEvent(-1,"resultat")
GUISetState(@SW_SHOW)
While 1
   Sleep(1000)
WEnd

Func resultat()
   Local $selection = ""
   $selection = ControlCommand("", "", $edit1, "GetSelected", "") ; récupère la sélection de $edit1
   If $selection = "" Then $selection = ControlCommand("", "", $edit2, "GetSelected", "")  ; récupère la sélection de $edit2
   If $selection = "" Then
      MsgBox(48,"Attention !","Sélectionnez le mot à rechercher !")
   Else
      MsgBox(0,"","Le mot sélectionné est : " & $selection)
      GUICtrlSendMsg($edit1, $EM_SETSEL, 0, 0)
      GUICtrlSendMsg($edit2, $EM_SETSEL, 0, 0)
   EndIf
EndFunc

Func _Close()
   Exit
EndFunc

Re: [R] Récupérer sélection dans divers Edit

Posté : ven. 05 févr. 2021 08:32
par GMH
Bonjour et merci à tous deux.
J'ai encore beaucoup appris. En particulier les commentaires concernant les signes = et ==, et les fonctions :

Code : Tout sélectionner

VarGetType()
et

Code : Tout sélectionner

GUICtrlSendMsg($..., $EM_SETSEL,...)
Je note que le code :

Code : Tout sélectionner

If (IsInt($selection))
ne fonctionne plus et doit être remplacé par la solution =.

Re: Re: [R] Récupérer sélection dans divers Edit

Posté : ven. 05 févr. 2021 14:33
par TommyDDR
Merci à vous pour avoir fourni un code testable ! :)
(Et pour utiliser le mode évènementiel ! :wink: )