Page 1 sur 1
[R] Appui sur une touche pour lancer une fonction
Posté : mer. 10 juil. 2013 21:03
par aulus
Bonjour,
Je souhaite que l'appui sur la touche DEL du clavier supprime une ligne d'un ListView, en lançant la fonction adéquate.
J'ai essayé la fonction HotKeySet("{DEL}", "fonctionDel") . Elle fonctionne très bien, ... même trop bien ! L'appui sur la touche DEL lance la fonction quelle que soit la GUI dans laquelle je me trouve. Elle conduit donc à des catastrophes !
J'ai essayé le code suivant, adaptation de l'exemple de l'aide à la fonction _IsPressed :
Code : Tout sélectionner
#include <Misc.au3>
Local $hDLL = DllOpen("user32.dll")
While 1
If _IsPressed("2E", $hDLL) Then
fonctionDel()
ExitLoop
EndIf
WEnd
DllClose($hDLL)
Avec ce code, le programme plante à l'ouverture du ListView.
Que faire ?
Je vous remercie.
Re: [..] appui sur une touche pour lancer une fonction
Posté : mer. 10 juil. 2013 21:09
par mikell
Dans la fonction du Hotkeyset il faudrait introduire des restrictions et vérifications
Sinon tu peux aussi essayer d'adapter à partir de ça
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
GUICreate("test", 100, 50)
Local $btn = GUICtrlCreateButton(".", 150, 10)
Local $AccelKeys[1][2] = [["{DEL}", $btn]]
GUISetAccelerators($AccelKeys)
GUISetState()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $btn
MsgBox(0, "", "Suppr")
Case $msg = $GUI_EVENT_CLOSE
Exit
EndSelect
Wend
Re: [..] Appui sur une touche pour lancer une fonction
Posté : mer. 10 juil. 2013 21:57
par aulus
Bonsoir Mikell, et merci.
Ma GUI affiche une suite de pseudo-pages aux contrôles affichés puis cachés selon les besoins d'appels à diverses fonctions, et le code que vous avez proposé étend la fonction sur toutes les pseudos-pages de la GUI. Ce qui fait qu'il ne colle pas. Je voudrais en effet limiter l'utilisation de la touche DEL à la page affichant le listView.
Je réfléchis aux conditions accompagnant la fonction HotKeySet... C'est peut-être bien de cette manière que le problème peut être résolu.
Re: [..] Appui sur une touche pour lancer une fonction
Posté : mer. 10 juil. 2013 22:42
par mikell
Tu n'es pas obligé de placer le Hotkeyset en tête de script, tu peux l'enregistrer lors de la sélection d'un item de la listview et le désenregistrer quand la listview perd le focus ^^
Re: [..] Appui sur une touche pour lancer une fonction
Posté : mer. 10 juil. 2013 23:35
par Manox
Salut,
Si tu as besoin de l'hotkey juste pour la suppression d'un item dans une listview, tu peux passer par ce bout de code qu'il le fait très bien sans les utiliser.
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
Global $hListView
_Main()
Func _Main()
Local $GUI, $hImage
$GUI = GUICreate("(UDF Created) ListView Create", 400, 300)
$hListView = _GUICtrlListView_Create($GUI, "", 2, 2, 394, 268)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
; Load images
$hImage = _GUIImageList_Create()
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0xFF0000, 16, 16))
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0x00FF00, 16, 16))
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0x0000FF, 16, 16))
_GUICtrlListView_SetImageList($hListView, $hImage, 1)
; Add columns
_GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)
_GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100)
_GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)
; Add items
_GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
_GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1)
_GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2)
_GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
_GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1)
_GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)
; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()
EndFunc ;==>_Main
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
$hWndListView = $hListView
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $LVN_KEYDOWN
$tInfo = DllStructCreate($tagNMLVKEYDOWN, $ilParam)
Local $flags = DllStructGetData($tInfo, "Flags")
Switch $flags
Case 339
$iDeleteItem = MsgBox(36, "Supression", "Voulez-vous vraiment supprimer cette entrée ?")
If $iDeleteItem = 6 Then
_GUICtrlListView_DeleteItem($hListView, _GUICtrlListView_GetSelectedIndices($hListView))
EndIf
EndSwitch
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
J'ai du le faire pour un de mes projets il y a quelques jours, là pour le coup j'ai repris l'exemple de création d'un LV dans l'helpFile.
En espérant que ça puisse aider.
Re: [..] Appui sur une touche pour lancer une fonction
Posté : jeu. 11 juil. 2013 07:18
par aulus
Merci Mikell pour la précision que vous venez d'ajouter. On désenregistre comment ? Peut-être : HotKeySet("{DEL}", "") ?
Merci Manox pour ce code qui marche à merveille. Je vais le tester à l'intérieur de mon code.
Re: [..] Appui sur une touche pour lancer une fonction
Posté : jeu. 11 juil. 2013 07:48
par Manox
Pour le "unset" un HotKeySet("{DEL}") suffit il me semble.
Re: [..] Appui sur une touche pour lancer une fonction
Posté : jeu. 11 juil. 2013 21:10
par aulus
Le code de Manox ne fonctionne pas lorsque je l'inclus dans mon code. Je pense que c'est dû à la différence de fonction de création de ListView choisie :
- Le code de Manox utilise la fonction de creation _GUICtrlListView_Create
- Mon code utilise la fonction GUICtrlCreateListView
Le désenregistrement du HotKeySet est bien HotKeySet("{DEL}") . J'ai bien tenté d'en semer en tête de toute les fonctions pour lesquelles le HotKeySet("DEL") n'est pas nécessaire, mais au moment où j'écris, je n'ai pas encore réussi. Encore quelques heures de travail...
Re: [..] Appui sur une touche pour lancer une fonction
Posté : jeu. 11 juil. 2013 21:49
par mikell
Le code de Manox doit fonctionner avec toutes les listviews, il est prévu pour ça
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
$GUI = GUICreate("test", 400, 300)
$hListView = GuiCtrlCreateListview(" ", 2, 2, 394, 268)
For $i = 1 to 10
GuiCtrlCreateListviewItem($i, $hListView)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
$hWndListView = $hListView
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $LVN_KEYDOWN
$tInfo = DllStructCreate($tagNMLVKEYDOWN, $ilParam)
Local $flags = DllStructGetData($tInfo, "Flags")
Switch $flags
Case 339
$iDeleteItem = MsgBox(36, "Supression", "Voulez-vous vraiment supprimer cette entrée ?")
If $iDeleteItem = 6 Then
_GUICtrlListView_DeleteItem($hListView, _GUICtrlListView_GetSelectedIndices($hListView))
EndIf
EndSwitch
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Il faut bien faire attention que le nom des variables est bon dans le WM_NOTIFY
Re: [..] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 10:58
par aulus
Voilà, j'y suis parvenu. Je m'étais emmêlé les pinceaux en ajoutant le Case $LVN_KEYDOWN au Case $LVN_COLUMNCLICK qui existait déjà dans mon Func WM_NOTIFY() et en ne modifiant pas les variables locales (comme vous l'aviez subodoré Mikell).
Merci Manox pour ce beau code efficace, et merci Mikell pour vos idées et conseils.
Je crois comprendre que le code 339 correspond à la touche DEL. Où peut-on trouver un tableau définissant les codes pour les autres touches (ENTER / INSER) ?
Re: [..] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 17:06
par Manox
Très bonne question je sais pas si il existe une table avec ces infos... a voir donc !
En attendant, voici une manière de trouver ces "codes"
rajoute ceci à la case $LVN_KEYDOWN
► Afficher le texte
Code : Tout sélectionner
Case $LVN_KEYDOWN ; A key has been pressed
$tInfo = DllStructCreate($tagNMLVKEYDOWN, $ilParam)
_DebugPrint("$LVN_KEYDOWN" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
"-->IDFrom:" & @TAB & $iIDFrom & @LF & _
"-->Code:" & @TAB & $iCode & @LF & _
"-->VKey:" & @TAB & DllStructGetData($tInfo, "VKey") & @LF & _
"-->Flags:" & @TAB & DllStructGetData($tInfo, "Flags"))
il faut ensuite rajouter cette fonction a ton code :
► Afficher le texte
Code : Tout sélectionner
Func _DebugPrint($s_text, $line = @ScriptLineNumber)
ConsoleWrite( _
"!===========================================================" & @LF & _
"+======================================================" & @LF & _
"-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
"+======================================================" & @LF)
EndFunc ;==>_DebugPrint
ceci t'affichera les codes Vkey et Flags pour certaines touches (malheureusement ça n'inclut pas le "enter"

)
Edit: tiré du helpfile je précise ^^
Re: [..] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 18:26
par aulus
Merci pour ce bon petit code.
En effet ENTER n'a pas droit à son code Flags.
Flags pour quelques autres touches :
INSER : 338
BACKSPACE : 14
BARRE D'ESPACEMENT : 57
CTRL : 29 (gauche) et 285 (droit)
ALT : 8248
Re: [R] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 19:59
par mikell
Cela dit c'est peut-être un meilleur plan de travailler directement avec les virtualkey codes, parce que toutes les valeurs figurent dans l'aide pour _IsPressed et tu les trouves partout sur internet
(au passage, une simple msgbox c'est pas mal non plus

)
Code : Tout sélectionner
Case $LVN_KEYDOWN
$tInfo = DllStructCreate($tagNMLVKEYDOWN, $ilParam)
Local $flags = DllStructGetData($tInfo, "Flags")
Local $vkey = DllStructGetData($tInfo, "VKey")
;msgbox(0,"", $flags &@crlf& $vkey)
Switch $vkey
Case 0x2e ; 339 ; DEL
; etc
Re: [R] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 20:26
par aulus
Bonsoir Mikell,
Effectivement ENTER a son code, mais... c''est la seule touche qui ne produit aucune action !
Autre question : comment sélectionner un item d'une ListView ? J'ai essayé tout ce que j'ai pu trouver (enfin je le crois) dans l'aide _GUICtrlListView sans résultat :
Code : Tout sélectionner
_GUICtrlListView_ClickItem($myList, 1)
_GUICtrlListView_SetItemState($myList, 1, $LVIS_FOCUSED, $LVIS_FOCUSED)
_GUICtrlListView_SetItemFocused($myList, 1)
_GUICtrlListView_SetHotItem($myList, 1)
GUICtrlSetState($myList, $GUI_CHECKED)
Re: [R] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 21:32
par Manox
@Mikell, en effet c'est bien mieux !
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Par contre, je préfère nettement passer un consoleWrite, pas besoin de cliquer ok pour chaque touche testée (dans ce contexte bien sur) et le code reste dans la console après coup
@aulus
As-tu essayé ceci ? :
Re: [R] Appui sur une touche pour lancer une fonction
Posté : ven. 12 juil. 2013 21:56
par mikell
Avec toutes ces udf on a une fâcheuse tendance à oublier les fonctions intégrées ^^
Je recommande un coup d'oeil à la fonction ControlListView qui est aussi efficace (souvent) et beaucoup plus légère (toujours)
Re: [R] Appui sur une touche pour lancer une fonction
Posté : sam. 13 juil. 2013 08:19
par aulus
Bonjour,
Les fonctions :
Code : Tout sélectionner
_GUICtrlListView_SetItemSelected()
ControlListView ( "", "", $myList, "Select",2,2)
... signalent l'item indexé par un surlignage de couleur claire mais l'item n'est pas sélectionné (mémorisé) pour être envoyé à une fonction (auquel cas, le surlignage prend la couleur bleu foncé). C'est ce qui fait que ces fonctions, qui paraissent pourtant les plus adéquates, ne m'ont pas paru adaptées à ce que je souhaitais.
Merci Manox pour le lien vers le tableau de codes.
Et il reste ce satané ENTER qui ne veut rien entendre...
Re: [R] Appui sur une touche pour lancer une fonction
Posté : sam. 13 juil. 2013 16:11
par mikell
A priori ce n'est pas l'item qui doit être envoyé à la fonction c'est son contenu, donc il faut le sélectionner puis le lire avec un GuiCtrlRead ou un GetText
Et la touche enter est réservée dans les listviews : pour tester, presse enter tout en ayant le bouton gauche de la souris pressé
Re: [R] Appui sur une touche pour lancer une fonction
Posté : sam. 13 juil. 2013 17:08
par aulus
Oui, il s'agit bien du contenu de l'item.
Quant à la touche ENTER, j'en fais donc mon deuil...
Merci encore pour toutes les réponses.
Re: [R] Appui sur une touche pour lancer une fonction
Posté : sam. 13 juil. 2013 17:15
par mikell
Pour info, les touches TAB et ESC aussi, et je déconseille les flèches haut et bas