JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013
-
19 janv. 2007 à 22:18
JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013
-
21 janv. 2007 à 18:36
Bonsoir à tous,
Voilà, premiers pas en VB2005, et déjà dans la m...élasse! (VB2005 Express)
Sous VB6, j'utilisais l'API SendMessage pour faire une recherche dans une Combobox:
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Sub Combo1_KeyPress(KeyAscii As Integer)
Dim CB As Long
Dim FindString As String
Const CB_ERR = (-1)
Const CB_FINDSTRING = &H14C
If KeyAscii < 32 Or KeyAscii > 127 Then Exit Sub
If CB <> CB_ERR Then
Combo1.ListIndex = CB
Combo1.SelStart = Len(FindString)
Combo1.SelLength = Len(Combo1.Text) - Combo1.SelStart
End If
KeyAscii = 0
End Sub
Avec l'outil "upgrade vb6 code", j'ai obtenu la sub suivante:
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As String) As Integer
(j'ai changé le "lParam as Any" en "lParam as string")
Private Sub Combo1_KeyPress(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.KeyPressEventArgs) Handles Combo1.KeyPress
Dim KeyAscii As Short = Asc(eventArgs.KeyChar)
Dim CB As Integer
Dim FindString As String
Const CB_ERR As Short = (-1)
Const CB_FINDSTRING As Short = &H14C
If KeyAscii < 32 Or KeyAscii > 127 Then GoTo EventExitSub
FindString = VB.Left(Combo1.Text, Combo1.SelectionStart) & Chr(KeyAscii)
CB = SendMessage(Combo1.Handle.ToInt32, CB_FINDSTRING, -1, FindString)
If CB <> CB_ERR Then
Combo1.SelectedIndex = CB
Combo1.SelectionStart = Len(FindString)
Combo1.SelectionLength = Len(Combo1.Text) - Combo1.SelectionStart
End If
KeyAscii = 0
EventExitSub:
eventArgs.KeyChar = Chr(KeyAscii)
If KeyAscii = 0 Then
eventArgs.Handled = True
End If
End Sub
Ce code ne fonctionnant pas, j'ai essayé de le réécrire toute seule, comme une grande, ce qui m'a donné ceci: (pas bcp de différences avec le précédent)
Private Sub Combo1_KeyPress(ByVal eventSender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Combo1.KeyPress
Dim CB As integer
Dim FindString As String
Const CB_ERR As Short = (-1)
Const CB_FINDSTRING As Short = &H14C
If Microsoft.VisualBasic.AscW(e.KeyChar) < 32 Or Microsoft.VisualBasic.AscW(e.KeyChar) > 127 Then Exit Sub
FindString = VB.Left(Combo1.Text, Combo1.SelectionStart) & icrosoft.VisualBasic.AscW(e.KeyChar)
CB = SendMessage(Combo1.Handle.ToInt32, CB_FINDSTRING, -1, FindString)
If CB <> CB_ERR Then
Combo1.SelectedIndex = CB
Combo1.SelectionStart = Len(FindString)
Combo1.SelectionLength = Len(Combo1.Text) - Combo1.SelectionStart
End If
e.Handled = True
End Sub
Sous VB6, dès que je tapais par ex. "t", le premier élément de la liste commencant par un "t" était sélectionné; si je tapais ensuite "u", le premier élément commencant par "tu" était sélectionné, et ainsi de suite. Ici, rien n'est sélectionné.
Quelqu'un aurait-il la gentillesse de bien vouloir me dire ou je me suis trompée
Merci
Jessica
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 20 janv. 2007 à 00:18
Mmh c'est vrai, voyons cela...
Premier problème (dans l'ordre dont tu m'en parles) :
En fait le Combo a déjà un système qui fait quelque chose de semblable, mais juste avec une lettre, donc même sans code, lorsqu'on appuie sur une touche, il sélectionne l'objet commencant par cette lettre (une seule lettre, pas ce qui nous convient) pour désactiver cette fonctionnalité qui perturbe notre recherche, il faut simplement indiquer dans les évènements de touches, que l'info est traitée et que le controle ne doit plus s'en charger (cfr e.Handled = True dans les code plus bas)
Second problème :
Oui pour vérifier que ce que l'utilisateur a rentré est une lettre, on peut utiliser e.KeyCode.ToString.Lenght = 1, si c'est faux, c'est que c'est autre chose, que tu peux traiter comme tu le veux dans le Select Case plus bas (voir code).
Troisième problème :
Pour ouvrir la liste, tu fais simplement Combo1.DroppedDown = True, j'ai pas vraiment compris quand tu voulais qu'il s'ouvre, moi je trouve que ça donne bien de l'ouvrir quand on tappe dedans, arrange comme tu veux...
Private Sub Combo1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Combo1.KeyDown
Dim i As Integer
If Not Combo1.DroppedDown Then Combo1.DroppedDown = True
If e.KeyCode.ToString.Length = 1 Then
Combo1.Tag = Combo1.Tag & e.KeyCode.ToString 'J'utilise Tag pour stocker l'info de recherche
i = Combo1.FindString(Combo1.Tag)
If i = -1 Then 'S'il a rien trouvé, on remet les infos de recherches à 0
Combo1.Tag = ""
Else
Combo1.SelectedIndex = i
End If
Else
Select Case e.KeyCode
Case Keys.Up
Combo1.SelectedIndex = Math.Max(0, Combo1.SelectedIndex - 1)
Case Keys.Down
Combo1.SelectedIndex = Math.Min(Combo1.Items.Count - 1, Combo1.SelectedIndex + 1)
'Ici définit ce que tu veux pour chaque touche...
End Select
End If
e.Handled = True
End Sub
Private Sub Combo1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Combo1.KeyPress
e.Handled = True
End Sub
Private Sub Combo1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Combo1.KeyUp
e.Handled = True
End Sub
Private Sub Combo1_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo1.Validated
Combo1.Tag = ""
End Sub
Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
Dim i, j As Object
Dim a As String
Randomize()
For i = 0 To 10000
a = ""
For j = 0 To 8
a = a & Chr(Int(Rnd(1) * 26 + 65))
Next
Combo1.Items.Add(a)
Next
Combo1.Items.Add("RECHERCHE")
End Sub, ----
(Coloration syntaxique automatique par Kenji)
JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013 21 janv. 2007 à 18:36
Bonsoir Julien,
Tu as raison, je suis restée sous VB, tant pis pour l'API; c'est vrai que l'appel de l'API est 2 fois plus rapide, mais c'est vrai aussi que pour voir la différence, il faut faire plusieurs centaines d'appels successifs !!
J'ai un peu modifié la source que tu m'as gentiment donnée. J'ai fait passer la gestion des touches dans le KeyPress, et je n'ai pas utilisé le Tag: je l'utilise déjà pour autre chose. Ta source est devenue ceci :
Private Sub Combo1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Combo1.KeyPress
Dim iPos As Integer, sString As String
If VB.AscW(e.KeyChar) < 32 Or VB.AscW(e.KeyChar) > 127 Then Exit Sub
If Not Combo1.DroppedDown Then Combo1.DroppedDown = True
sString = VB.Left(Combo1.Text, Combo1.SelectionStart) & e.KeyChar
iPos = Combo1.FindString(sString)
If iPos <> -1 Then
Combo1.SelectedIndex = iPos
Combo1.SelectionStart = Len(sString)
Combo1.SelectionLength = Len(Combo1.Text) - Combo1.SelectionStart
End If
e.Handled = True
End Sub
Quoi qu'il en soit, je te remercie vivement.
Passe une bonne soirée
Jessica
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 19 janv. 2007 à 22:47
Une femme qui code ! (Oui lol j'ai du vérifier le pseudo quand j'ai lu "toute seule")
Claaasse, (prologin, concours d'algo l'an passé : sur 100 participants, que des hommes, quelle déception ).
Sur ce, .Net te simplifie grandement la vie, plus besoin de message, cette fonctionnalité est accessible directement depuis une méthode de ComboBox :
Private Sub ComboBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
ComboBox1.Tag &= e.KeyCode.ToString 'J'utilise Tag pour stocker l'info de recherche
Dim i As Integer = ComboBox1.FindString(ComboBox1.Tag)
If i = -1 Then 'S'il a rien trouvé, on remet les infos de recherches à 0
ComboBox1.Tag = ""
Else
ComboBox1.SelectedIndex = i
End If
End Sub
Private Sub ComboBox1_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.Validated
ComboBox1.Tag = ""
End Sub, ----
(Coloration syntaxique automatique par Kenji)
JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013 19 janv. 2007 à 23:38
Bonsoir Julien,
Heureuse de constater que tu n'es pas macho (ou si peu), et que tu n'as visiblement rien contre le fait qu'une femme puisse coder - lol
Ceci étant dit, je crois que quelque chose ne va pas dans le code que tu m'as fourni:
Private Sub Combo1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Combo1.KeyDown
Combo1.Tag &= e.KeyCode.ToString 'J'utilise Tag pour stocker l'info de recherche
Dim i As Integer = Combo1.FindString(Combo1.Tag)
If i = -1 Then 'S'il a rien trouvé, on remet les infos de recherches à 0
Combo1.Tag = ""
Else
Combo1.SelectedIndex = i
End If
End Sub
Private Sub Combo1_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Combo1.Validated
Combo1.Tag = ""
End Sub
Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
Dim i, j As Object
Dim a As String
For i = 0 To 10000
a = ""
For j = 0 To 8
a = a & Chr(Int(Rnd(1) * 26 + 65))
Next
Combo1.Items.Add(a)
Next
Combo1.Items.Add("RECHERCHE")
End Sub
- En plus l'item qu'il a trouvé, il affiche la dernière lettre frappée en 1ère position
- Problème si j'utilise la flèche "haut": il passe directement dans les "U..."
- Lors de la 1ére frappe, si le texte est blanc, mon appel à l'API ouvrait la dropdown list (CONST CB_SHOWDROPDOWN=&H14F
Je t'ai donné tout mon code pour que tu puisses le vérifier par toi-même (je sais que pour un mec, c'est difficile de croire ce qu'une nana raconte !!! )
Merci quand même de m'avoir répondu
Amitiés
Jessica
Vous n’avez pas trouvé la réponse que vous recherchez ?
JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013 20 janv. 2007 à 00:50
Re,
C'est déjà bcp mieux, mais c'est pas encore aussi bien que ce que je faisais avec mon SendMessage, dans lequel je gérais les SelStart et SelLenght. (Hé oui, difficile à satisfaire, une femme !!). Si tu as encore VB6, essaie le 1er code que j'ai mis dans mon 1er post: tu verras
Je vais essayer d'effectuer certaines modifs ce week-end. Je te tiens au courant.
En tout cas, un tout grand merci pour ta gentillesse
Amitiés
Jessica
JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013 20 janv. 2007 à 00:56
Re,
Je viens de me relire: je suis désolée pour le "c'est déjà beaucoup mieux" : j'y connais rien (en tout cas en VB2005), et c'est comme si je jugeais ton travail. J'espère que tu ne l'as pas mal pris.
Bonne nuit
Jessica
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 20 janv. 2007 à 07:19
Non non, pas de problèmes :p
Pour les SelStart et SelLenght, ça c'est à toi de faire comme tu veux, elles ont juste changé de nom et s'appellent maintenant SelectionStart et SelectionLenght, je pars maintenant pour jouer à un mariage, et je ne saurais plus t'aider avant demain soir.
Bonne chance !
<hr size="2" width="100%" />Julien.
JessicaR44
Messages postés116Date d'inscriptionmardi 8 août 2006StatutMembreDernière intervention29 septembre 2013 20 janv. 2007 à 21:19
Bonsoir à tous,
Bonsoir Julien,
OK, j'ai trouvé ce qui avait foiré avec l'utilisation de l'API SendMessage avec VB2005. Je me suis focalisée sur la sub KeyPress, alors que l'erreur était autre part, à savoir, dans la déclaration de la fonction :
Il s'agissait d'un code VB6, qui a été converti par VB2005
Sous VB6, il y avait
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
VB2005 en a fait
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" _
(ByVal hWnd As Integer, ByVal wMsg As Integer, _
ByVal wParam As Integer, ByRef lParam As String) As Integer
Ici, j'ai changé le "lParam as Any" en "lParam as string" (comme me le conseillait VB), mais je n'ai pas fait attention au "Byref" qu'il avait ajouté!
Tout est rentré dans l'ordre lorsque j'ai déclaré "ByVal lParam As String".
J'ai fait quelques essais, et la recherche via l'appel de l'API est +/- 2 fois plus rapide.
Ma question maintenant est donc de savoir si techniquement, il est préférable d'utiliser la méthode de combobox de VB2005 ou l'appel de l'API ? Perso, je préférerais l'Api, mais bon ... j'attends vos suggestions
Merci d'avance
Jessica
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 21 janv. 2007 à 17:50
Perso je dirais la méthode de la combobox tout simplement parce que ça m'étonnerais que le traitement du message soit autre qu'un simple appel à cette fonction... Fais simplement ce que tu préfère... Je crois pas qu'un autre te répondras parce que personne d'autre que moi n'a suivi la discussion. (On répond souvent aux messages qui ont été écris les 3-4 dernières heures et à ceux qu'on a commencé et dont on reçoit les mails, donc je pense pas qu'un autre passera par ici )