Problème avec hWnd d'un contrôle (+ passage d'un code de VB6 en VB.NET): [Résolu]

Messages postés
41
Date d'inscription
lundi 19 décembre 2005
Statut
Membre
Dernière intervention
25 novembre 2008
- - Dernière réponse : Kevin.Ory
Messages postés
843
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
7 janvier 2009
- 5 juil. 2008 à 16:03
Bonjour à tous, j'aimerais votre aide pour le passage d'un script VB6, vers le VB.NET, en effet j'ai un petit problème de hWnd, qui n'est pas un membre de System.Forms.ListBox :

Voici le code que j'ai par ailleurs trouvé sur le site :

<li>OptionExplicit</li><li></li><li></li><li></li><li>Private Type POINTAPI
</li><li>X AsLong</li><li>Y AsLong</li><li>End Type
</li><li></li><li>PrivateDeclareFunction GetCursorPos Lib "user32" (lpPoint As POINTAPI) AsLong</li><li>PrivateDeclareFunction ScreenToClient Lib "user32" (ByVal hWnd AsLong, lpPoint As POINTAPI) AsLong</li><li>PrivateDeclareFunction SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd AsLong, ByVal wMsg AsLong, ByVal wParam AsLong, lParam AsLong) AsLong</li><li></li><li>PrivateConst LB_ITEMFROMPOINT = &H1A9
</li><li></li><li>PrivateSub Form_Load()
</li><li>Dim indice AsInteger</li><li></li><li>For indice = 1 To 10
</li><li>List1.AddItem "Item n° " & indice
</li><li>Next</li><li></li><li>EndSub</li><li></li><li>PrivateSub List1_MouseMove(Button AsInteger, Shift AsInteger, X AsSingle, Y AsSingle)
</li><li>Dim p As POINTAPI
</li><li>Dim indice AsLong</li><li></li><li>' Récupère la position de la souris</li><li>Call GetCursorPos(p)
</li><li></li><li>Call ScreenToClient(List1.hWnd, p)
</li><li></li><li>' Récupère l'indice de l'élément survolé (grace à l'envoi de LB_ITEMFROMPOINT via SendMessage)</li><li>indice = SendMessage(List1.hWnd, LB_ITEMFROMPOINT, 0&, ByVal ((p.X And &HFF) Or (&H10000 * (p.Y And &HFF))))
</li><li>If indice >0 Then</li><li>indice indice And &HFF
</li><li>List1.ToolTipText = "Ceci est l'item n°" & indice
</li><li>EndIf</li><li>EndSub</li>
J'ai réussis à régler le problème de:
Private Type POINTAPI (...) End Type
En remplacant par Private Structure POINTAPI (...) End Structure
Ainsi que le List1.AddItem par List1.Items.Add

Mais il reste d'autres erreurs que je ne sais pas corriger :
ces erreurs sont :  List1.hWnd qui n'existe pas pour un ListBox.

Ici : ByVal
((p.X And &HFF) Or (&H10000 * (p.Y And &HFF))) le ByVal est souligné, avec pour erreur "expression attendue"

Et la dernière erreure : List1.ToolTipText où ToolTipText n'existe pas en tant que membre d'un ListBox.

Merci d'avance pour votre aide.
Afficher la suite 

9 réponses

Meilleure réponse
Messages postés
843
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
7 janvier 2009
5
3
Merci
Grâce à toi je viens de trouver une nouvelle fonction de la ListBox : IndexFromPoint.
Elle permet donc de remplacer l'appel à l'api SendMessage pour récupérer l'item sous le curseur, ma boucle précédement cité devient donc inutile.

Pour ce qui est du ToolTipText, effectivement la ListBox .NET n'intègre pas de ToolTip. Mais pas grave, suffit de rajouter un ToolTip (de la barre d'outils à gauche) sur ta Form.

Voici le code :

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For i As Integer = 1 To 100
        Me.ListBox1.Items.Add(i)
    Next
End Sub

Private Sub ListBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseMove
    Dim index As Integer = ListBox1.IndexFromPoint(e.Location)
    Me.ToolTip1.SetToolTip(ListBox1, "Ceci est l'item " & index + 1)
End Sub

----------------------------------------------------------------
"Je ne sais pas trop comment je dois déclarer la variable "e" de e.Location"
Tu ne dois pas la déclarer, e est l'argument des évènements (MouseMove dans notre cas)
Private Sub ListBoxCommandes_MouseMove(ByVal Button AsInteger, ByVal Shift AsInteger, ByVal X AsSingle, ByVal Y AsSingle)
n'existe plus en VB.NET, ça devient:
Private Sub ListBox1_MouseMove(ByVal sender As
Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles
ListBox1.MouseMove
"J'ai un problème avec la strucutre : "Return i" avec pour erreur que l'instruction Return ne peut pas renvoyer de valeur"
Oui moi j'ai mis un return car je fesais cette boucle dans une fonction qui devait me renvoyer l'index. ça ne s'applique donc pas dans ton cas.


Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 210 internautes nous ont dit merci ce mois-ci

Commenter la réponse de Kevin.Ory
Messages postés
13298
Date d'inscription
lundi 13 décembre 2004
Statut
Modérateur
Dernière intervention
3 février 2018
27
0
Merci
salut,

<li>PrivateDeclareFunction GetCursorPos Lib "user32" (lpPoint As POINTAPI) AsInteger
</li><li>PrivateDeclareFunction ScreenToClient Lib "user32" (ByVal hWnd As IntPTR, lpPoint As POINTAPI) AsInteger</li><li>PrivateDeclareFunction SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPTR, ByVal wMsg As Integer, ByVal wParam As Integer, lParam AsInteger) As Integer</li>
à toi d'adapter le reste (variables etc...) en conséquence
++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp  
Commenter la réponse de PCPT
Messages postés
41
Date d'inscription
lundi 19 décembre 2005
Statut
Membre
Dernière intervention
25 novembre 2008
0
Merci
Merci de l'aide, j'ai bien effectué les modifications montré en rouge, mais j'ai toujours les mêmes erreurs sur le fin du code :





"List1.hWnd qui n'existe pas pour un ListBox.







Ici : ByVal



((p.X And &HFF) Or (&H10000 * (p.Y And &HFF))) le ByVal est souligné, avec pour erreur "expression attendue"

Et la dernière erreure : List1.ToolTipText où ToolTipText n'existe pas en tant que membre d'un ListBox."







Ces dernières modifications devrait normalement les régler ?

Merci encore pour l'aide :)
Commenter la réponse de cs_benji78
Messages postés
843
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
7 janvier 2009
5
0
Merci
Salut,

<strike>Private Type POINTAPI
    X AsLong
    Y AsLong
End Type
</strike>=> Point<strike>
</strike>
<strike>Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
=</strike>> Cursor.Position

<strike>Private </strike><strike>Declare Function ScreenToClient Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
</strike>=> PointToClient

<strike>List1.hWnd</strike>
=> List1.Handle

<strike>Dim p As POINTAPI</strike>
<strike>Call GetCursorPos(p)
Call ScreenToClient(List1.hWnd, p)</strike>
=> e.Location
<strike>
indice = SendMessage(List1.hWnd, LB_ITEMFROMPOINT, 0&, ByVal ((p.X And &HFF) Or (&H10000 * (p.Y </strike><strike>And &HFF))))
</strike>=> Moi j'ai fais (c'est plus long, mais plus .NET) :
    For i As Integer = 0 To List1.Items.Count - 1
        If List1.GetItemRectangle(i).Contains(e.Location) Then Return i
    Next
Mais il est vrai que cette fonction manque dans la ListBox .NET. Ta solution est meilleur niveau perf, surtout si il y a bcp d'items.

Pour le ByVal, je n'en ai jamais vu dans le code. C'est dans la déclaration qu'il faut le mettre:
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Commenter la réponse de Kevin.Ory
Messages postés
41
Date d'inscription
lundi 19 décembre 2005
Statut
Membre
Dernière intervention
25 novembre 2008
0
Merci
Salut, Kevin.Ory, je suis vraiment un débutant, et je n'ai pas vraiment compris comment utiliser se que tu m'as indiqué, j'ai essayé de remplacer au mieux, avec se que tu m'as conseillé, voici donc le code que j'ai :

Private

DeclareAnsiFunction Cursor Lib"user32" (ByVal lpPoint As System.Drawing.Point) AsIntegerPrivateDeclareFunction ScreenToClient Lib"user32" (ByVal hWnd As IntPtr, ByVal lpPoint As Point) AsInteger

PrivateDeclareFunction SendMessage Lib"user32"Alias"SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg AsInteger, ByVal wParam AsInteger, ByVal lParam AsInteger) AsInteger

PrivateConst LB_ITEMFROMPOINT = &H1A9

PrivateSub Form_Load()

Dim indice AsInteger

For indice = 1 To 30

ListBoxCommandes.Items.Add("Item n° " & indice)

Next

EndSub

PrivateSub ListBoxCommandes_MouseMove(ByVal Button AsInteger, ByVal Shift AsInteger, ByVal X AsSingle, ByVal Y AsSingle)

Dim indice AsLong

e.Location()

For i AsInteger = 0 To ListBoxCommandes.Items.Count - 1

If ListBoxCommandes.GetItemRectangle(i).Contains(e.Location) ThenReturn i

Next

If indice >= 0 Then

indice = indice And &HFF

ListBoxCommandes.ToolTipText = "Ceci est l'item n°" & indice

EndIf

EndSub

Et voila les problème qu ej'ai :
Je ne sais pas trop comment je dois déclarer la variable "e" de e.Location
J'ai un problème avec la strucutre : "Return i" avec pour erreur que l'instruction Return ne peut pas renvoyer de valeur
Et enfin J'ai toujours le problème "ListBoxCommandes.ToolTipText " qui n'existe pas pour une ListBox.

Merci de ton aide.
Commenter la réponse de cs_benji78
Messages postés
41
Date d'inscription
lundi 19 décembre 2005
Statut
Membre
Dernière intervention
25 novembre 2008
0
Merci
Merci beaucoup de ton aide :), et tes explications je pense avoir appris pas mal de choses aujourd'hui grâce à toi.

Ça marche impeccable.

Sinon c'est annexe, puisque mon problème est résolu, mais j'ai vu sur certaines applications windows et notemment Visual Studio, que lorsque dans une liste, un item à une taille (texte) dépassant les dimensions horizontales du cadre du contrôle.
On obtient quelque chose de ce genre :

Si tu ne sais pas ce n'est pas grave puisque je peux maintenant me débrouiller avec l'info-bulles que tu m'as appris à créer.
Merci encore.
Commenter la réponse de cs_benji78
Messages postés
843
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
7 janvier 2009
5
0
Merci
Certains contrôles ont une propriété AutoToolTip. A True, elle permet d'afficher un ToolTipText lorsque le texte n'est pas entièrement visible.
Mais il faut que le contrôle intègre cette fonctionnalité, sinon tu ne pourra pas le faire facilement.
Commenter la réponse de Kevin.Ory
Messages postés
41
Date d'inscription
lundi 19 décembre 2005
Statut
Membre
Dernière intervention
25 novembre 2008
0
Merci
Donc à priori, c'est plutôt galère pour mon cas de ListBox ^^.
Merci, des infos :).
Commenter la réponse de cs_benji78
Messages postés
843
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
7 janvier 2009
5
0
Merci
Non en fait ce n'est pas si compliqué:

Private Sub ListBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseMove
    ' Index de l'item sous le curseur
    Dim index As Integer = ListBox1.IndexFromPoint(e.Location)
    ' Text de l'item sous le curseur
    Dim text As String = ListBox1.Items(index)
    ' Graphics de la ListBox. Permet de dessiner et de mesurer la taille d'un texte
    Dim graphics As Graphics = ListBox1.CreateGraphics
    ' Longueur du texte en pixels
    Dim width As Integer = graphics.MeasureString(text, Me.Font).Width
    If width > ListBox1.Width Then
        ' Si la longueur du texte est plus grande que la largeur de la ListBox, on affiche:
        Me.ToolTip1.SetToolTip(ListBox1, text)
    Else
        ' Sinon, on affiche pas:
        Me.ToolTip1.SetToolTip(ListBox1, "")
    End If
End Sub

Et voilà
Commenter la réponse de Kevin.Ory