IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Comment connaître la forme RÉELLE du curseur souris ?


Sujet :

VB.NET

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations forums :
    Inscription : Mars 2011
    Messages : 105
    Points : 153
    Points
    153
    Par défaut Comment connaître la forme RÉELLE du curseur souris ?
    Bonjour,
    Dans mon programme j'envoi à une tablette des copies d'écran d'un PC distant.
    Comme je ne sais pas capturer la souris je le simule en incrustant un curseur dans la copie.
    Le Hic c'est que c'est toujours une flèche ou un sablier (avec Cursor.Current).
    Je souhaiterai connaître la vrai forme du curseur à l'instant de la capture (flèche, curseur text, double flèche sur un bords de fenêtre, etc...).

    J'ai également essayé en passant par les API:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     Dim hdc1 As IntPtr = gfx.GetHdc ' pointeur dessin
     Dim hdc2 As IntPtr = GetDC(0) ' pointeur écran
     Dim Pcur As IntPtr = GetCursor() ' pointeur souris
     BitBlt(hdc1, 0, 0, bmpc1.Width, bmpc1.Height, hdc2, 0, 0, 13369376)  ' copie zone écran
     DrawIcon(hdc1, Cursor.Position.X, Cursor.Position.Y, Pcur) ' dessin curseur
     gfx.ReleaseHdc(hdc1)
     ReleaseDC(0, hdc2)
    Mais toujours le sablier....

  2. #2
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Développeur VBA/C#/VB.Net/Power Platform
    Inscrit en
    Juillet 2007
    Messages
    14 595
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur VBA/C#/VB.Net/Power Platform
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 595
    Points : 34 271
    Points
    34 271
    Cycle de vie d'un bon programme :
    1/ ça fonctionne 2/ ça s'optimise 3/ ça se refactorise

    Pas de question technique par MP, je ne réponds pas

    Mes ouvrages :
    Apprendre à programmer avec Access 2016, Access 2019 et 2021

    Apprendre à programmer avec VBA Excel
    Prise en main de Dynamics 365 Business Central

    Pensez à consulter la FAQ Excel et la FAQ Access

    Derniers tutos
    Excel et les paramètres régionaux
    Les fichiers Excel binaires : xlsb,

    Autres tutos

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations forums :
    Inscription : Mars 2011
    Messages : 105
    Points : 153
    Points
    153
    Par défaut
    Merci pour ta réponse mais ce n'est malheureusement pas ça.
    Ton lien indique comment définir le curseur en xaml. (en code, il est d'ailleurs bien précisé d'utiliser la class "Cursors").
    Ce que je cherche c'est connaître la forme du curseur à un instant t (typiquement au moment de la capture de l'écran).

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    Il faut appeler l'API GetCursorInfo en spécifiant le paramètre cbSize de la structure CURSORINFO au préalable...

    code exemple .vb :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    Imports System.Runtime.InteropServices
    Imports System.Drawing.Imaging
     
    Public Class Form1
        Const CURSOR_SHOWING As Int32 = &H1
     
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            ' ici tu peux tester en changeant du curseur
            Me.Cursor = Cursors.Hand
            PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
     
            PictureBox1.Image = CaptureScreen(True)
        End Sub
     
     
     
     
        Public Shared Function CaptureScreen(CaptureMouse As Boolean) As Bitmap
            Dim result As Bitmap = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format24bppRgb)
            Try
                Using g As Graphics = Graphics.FromImage(result)
                    g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy)
                    If (CaptureMouse) Then
                        Dim pci As CURSORINFO
                        pci.cbSize = Marshal.SizeOf(GetType(CURSORINFO))
                        If (GetCursorInfo(pci)) Then
                            If (pci.flags = CURSOR_SHOWING) Then
                                DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor)
                                g.ReleaseHdc()
                            End If
                        End If
                    End If
     
     
     
     
                End Using
     
            Catch ex As Exception
                result = Nothing
            End Try
     
            Return result
     
        End Function
     
     
     
        <DllImport("user32.dll")>
        Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
        End Function
        <DllImport("user32.dll")>
        Shared Function DrawIcon(hDC As IntPtr, X As Int32, Y As Int32, hIcon As IntPtr) As Boolean
        End Function
        <StructLayout(LayoutKind.Sequential)>
        Structure CURSORINFO
            Public cbSize As Int32
            Public flags As Int32
            Public hCursor As IntPtr
            Public ptScreenPos As POINTAPI
        End Structure
     
        <StructLayout(LayoutKind.Sequential)>
        Structure POINTAPI
            Public x As Int32
            Public y As Int32
        End Structure
     
     
    End Class


    bon code...

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations forums :
    Inscription : Mars 2011
    Messages : 105
    Points : 153
    Points
    153
    Par défaut
    Merci pour le code.
    Je le testerai dans la journée.

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations forums :
    Inscription : Mars 2011
    Messages : 105
    Points : 153
    Points
    153
    Par défaut
    Bon, je viens de tester ton code.
    Coté forme du curseur, c'est tout bon: On a la forme du curseur au moment de la capture écran.
    Toutefois, seul la flèche (arrow), la flèche avec le point d'interrogation (help) et partiellement la main (hand) sont positionnés correctement.
    Toutes les autres formes sont dessinées décalées vers le bas et vers la droite.

    J'ai modifié ton code pour faire la capture écran en appuyant sur la barre d'espace et l'appui sur le bouton change cycliquement la forme du curseur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    Imports System.Runtime.InteropServices
    Imports System.Drawing.Imaging
     
    Public Class Form1
        Const CURSOR_SHOWING As Int32 = &H1
        Dim curseurs() As Cursor = {Cursors.Arrow, Cursors.Cross, _
                                     Cursors.Hand, Cursors.Help, _
                                     Cursors.HSplit, Cursors.IBeam, Cursors.No, _
                                     Cursors.NoMove2D, Cursors.NoMoveHoriz, Cursors.NoMoveVert, _
                                     Cursors.PanEast, Cursors.PanNE, Cursors.PanNorth, _
                                     Cursors.PanNW, Cursors.PanSE, Cursors.PanSouth, _
                                     Cursors.PanSW, Cursors.PanWest, Cursors.SizeAll, _
                                     Cursors.SizeNESW, Cursors.SizeNS, Cursors.SizeNWSE, _
                                     Cursors.SizeWE, Cursors.UpArrow, Cursors.VSplit, Cursors.WaitCursor}
        Dim curseurIndex As Integer = 0
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            ' ici tu peux tester en changeant du curseur
            curseurIndex += 1
            If curseurIndex > 25 Then
                curseurIndex = 0
            End If
            Me.Cursor = curseurs(curseurIndex)
        End Sub
     
        Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
            If e.KeyCode = Keys.Space Then
                PictureBox1.SizeMode = PictureBoxSizeMode.Zoom
                PictureBox1.Image = CaptureScreen(True)
                e.SuppressKeyPress = True
            End If
        End Sub
     
        Public Shared Function CaptureScreen(ByVal CaptureMouse As Boolean) As Bitmap
            Dim result As Bitmap = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format24bppRgb)
            Try
                Using g As Graphics = Graphics.FromImage(result)
                    g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy)
                    If (CaptureMouse) Then
                        Dim pci As CURSORINFO
                        pci.cbSize = Marshal.SizeOf(GetType(CURSORINFO))
     
                        If (GetCursorInfo(pci)) Then
                            If (pci.flags = CURSOR_SHOWING) Then
                                DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor)
                                g.ReleaseHdc()
                            End If
                        End If
                    End If
                End Using
            Catch ex As Exception
                result = Nothing
            End Try
     
            Return result
     
        End Function
     
     
     
        <DllImport("user32.dll")>
        Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
        End Function
        <DllImport("user32.dll")>
        Shared Function DrawIcon(ByVal hDC As IntPtr, ByVal X As Int32, ByVal Y As Int32, ByVal hIcon As IntPtr) As Boolean
        End Function
        <StructLayout(LayoutKind.Sequential)>
        Structure CURSORINFO
            Public cbSize As Int32
            Public flags As Int32
            Public hCursor As IntPtr
            Public ptScreenPos As POINTAPI
        End Structure
     
        <StructLayout(LayoutKind.Sequential)>
        Structure POINTAPI
            Public x As Int32
            Public y As Int32
        End Structure
     
     
     
    End Class
    Je ne comprend pas ce décalage...

  7. #7
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations forums :
    Inscription : Mars 2011
    Messages : 105
    Points : 153
    Points
    153
    Par défaut
    Bon, il semble que "pci.ptScreenPos.x" et "pci.ptScreenPos.y" soit les coin gauche + hotspot.x et coin supérieur + hotspot.y...
    Il faut utiliser en plus GetIconInfo() pour avoir les valeurs des hotspots et faire une soustraction.

    Edit:

    Le code ci-dessous affiche la bonne forme de la souris à la bonne position.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    Imports System.Runtime.InteropServices
    Imports System.Drawing.Imaging
     
    Public Class Form1
        Const CURSOR_SHOWING As Int32 = &H1
     
        Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
            If e.KeyCode = Keys.Space Then
                PictureBox1.SizeMode = PictureBoxSizeMode.Zoom
                PictureBox1.Image = CaptureScreen(True)
                e.SuppressKeyPress = True
            End If
        End Sub
     
        Public Shared Function CaptureScreen(ByVal CaptureMouse As Boolean) As Bitmap
            Dim result As Bitmap = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format24bppRgb)
            Try
                Using g As Graphics = Graphics.FromImage(result)
                    g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy)
                    If (CaptureMouse) Then
                        Dim pci As CURSORINFO
                        pci.cbSize = Marshal.SizeOf(GetType(CURSORINFO))
                        If (GetCursorInfo(pci)) Then
                            If (pci.flags = CURSOR_SHOWING) Then
                                Dim piinfo As ICONINFO
                                If GetIconInfo(pci.hCursor, piinfo) Then
                                    DrawIcon(g.GetHdc(), pci.ptScreenPos.x - piinfo.xHotspot, pci.ptScreenPos.y - piinfo.yHotspot, pci.hCursor)
                                    If CBool(piinfo.hbmMask) Then DeleteObject(piinfo.hbmMask) ' la fonction GetIconInfo créé deux objets color et mask qu'il faut supprimer (pinvoke)
                                    If CBool(piinfo.hbmColor) Then DeleteObject(piinfo.hbmColor)
                                End If
                                g.ReleaseHdc()
                            End If
                        End If
                    End If
                End Using
            Catch ex As Exception
                result = Nothing
            End Try
     
            Return result
     
        End Function
     
     
     
        <DllImport("user32.dll")>
        Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
        End Function
        <DllImport("user32.dll")>
        Shared Function DrawIcon(ByVal hDC As IntPtr, ByVal X As Int32, ByVal Y As Int32, ByVal hIcon As IntPtr) As Boolean
        End Function
        <DllImport("user32.dll", EntryPoint:="GetIconInfo")> _
        Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
        End Function
        <DllImport("gdi32.dll")> _
        Shared Function DeleteObject(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
        <StructLayout(LayoutKind.Sequential)>
        Structure CURSORINFO
            Public cbSize As Int32
            Public flags As Int32
            Public hCursor As IntPtr
            Public ptScreenPos As POINTAPI
        End Structure
     
        <StructLayout(LayoutKind.Sequential)>
        Structure POINTAPI
            Public x As Int32
            Public y As Int32
        End Structure
     
        <StructLayout(LayoutKind.Sequential)> _
        Structure ICONINFO
            Public fIcon As Boolean
            Public xHotspot As Int32
            Public yHotspot As Int32
            Public hbmMask As IntPtr
            Public hbmColor As IntPtr
        End Structure
     
     
    End Class

  8. #8
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    Effectivement il faut une couche API Window de plus ...

    Mais le class shared Cursor de .Net Framework permet de :
    1/ connaitre la position : Cursor.Position restitue la position TopLeft
    2/ la "forme" : Cursor.Size
    3/ en bonus : Cursor.HotSpot qui différé d'un Cursor à l'autre

    4/ de le dessiner :Cursor.Draw(gr,rect)
    et donc de dessiner par là meme le rectangle englobant de Cursor

    Abondance de biens ne nuit pas...dit l'adage
    bon code...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment connaître l'état du curseur de la souris ?
    Par thenaoh dans le forum Windows
    Réponses: 6
    Dernier message: 23/09/2010, 19h35
  2. Réponses: 6
    Dernier message: 22/08/2010, 01h44
  3. Comment connaître l'état du curseur de la souris ?
    Par thenaoh dans le forum Windows
    Réponses: 14
    Dernier message: 15/06/2010, 11h11
  4. Réponses: 3
    Dernier message: 20/10/2005, 20h24
  5. [Hook] Comment connaître la Form à partir d'un TPoint ?
    Par remixtech dans le forum API, COM et SDKs
    Réponses: 19
    Dernier message: 06/02/2005, 01h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo