Envoyer le message système WM_GESTURE à une application
Bonjour,
Je développe deux programmes: l'un sur un PC classique , l'autre sur tablette. (En vb.net et WinForm)
Les deux programmes communiquent par TCP/IP et UDP.
Le programme du PC envoi des copies d'écran à la tablette.
La tablette envoi des commandes au programme sur le PC.
Jusqu'ici j'utilisais des commandes souris ou molette:
tablette : mouse down / move / up -> codage en chaine -> envoi par UDP
PC : réception UDP -> décodage -> mouse_event
Vu que les commandes se font sur une tablette, je me suis intéressé à la "Windows Touch Gestures"
Il est assez facile d'intercepter les messages WM_GESTURE, de coder les valeurs et d'envoyer le tout au PC par UDP.
Sur le PC, je pensais qu'il serait simple de décoder le message et de l'envoyer au moyen d'un SendMessage ou PostMessage.
Ben non :calim2:
Code:
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
| Private Sub construit_et_envoi_message(ByVal comm() As String)
Dim fenPP As IntPtr = GetForegroundWindow() 'handle de la fenêtre au premier plan
Dim id As Integer = 0
GetWindowThreadProcessId(fenPP, id) ' id du process auquel la fenêtre appartient
Dim processus As Process = Process.GetProcessById(id) ' process recherché
affiche_log("appli: " & processus.ProcessName, False, 0)
Try
Dim gestruct As GESTUREINFO
gestruct.cbSize = Val(comm(3))
gestruct.dwFlags = Val(comm(4))
gestruct.dwID = Val(comm(5))
gestruct.hwndTarget = fenPP
Dim pt As POINTS
pt.x = Val(comm(7)) : pt.y = Val(comm(8))
gestruct.ptsLocation = pt
gestruct.dwInstanceID = Val(comm(9))
gestruct.dwSequenceID = Val(comm(10))
gestruct.ullArguments = Val(comm(11))
gestruct.cbExtraArgs = Val(comm(12))
Dim tmp_struct_ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(gestruct)) ' réserver une zone mémoire non managé
Marshal.StructureToPtr(gestruct, tmp_struct_ptr, True) ' copier les données de la structure
If tmp_struct_ptr <> 0 Then
Dim process_hdle As IntPtr = processus.Handle ' handle natif du process
Dim my_struct_ptr As IntPtr = VirtualAllocEx(process_hdle, IntPtr.Zero, CUInt(Marshal.SizeOf(GetType(GESTUREINFO))), AllocationType.Commit, MemoryProtection.ReadWrite) ' zone mémoire dans le thread de l'appli visée
If my_struct_ptr <> 0 Then
Dim result As IntPtr = WriteProcessMemory(process_hdle, my_struct_ptr, tmp_struct_ptr, Marshal.SizeOf(gestruct), IntPtr.Zero) ' copier le bloc non managé
If result <> 0 Then
Dim w_param As IntPtr = Val(comm(2))
affiche_log("processus.handle: " & processus.Handle.ToString, False, 0)
Dim mess As UInteger = Val(comm(1)) ' numéro du message &H119 dans le cas de WM_GESTURE
Dim sm_res As IntPtr = PostMessage(fenPP , mess, w_param, my_struct_ptr) ' envoyer le message
If sm_res = IntPtr.Zero Then
affiche_log("erreur: " & Marshal.GetLastWin32Error().ToString, False, 0) ' si sm_res = 0, rechercher le numéro d'erreur
Else
affiche_log("message envoyé ", False, 0)
End If
End If
End If
End If
Marshal.FreeHGlobal(tmp_struct_ptr)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub |
La routine n'est pas sélective : elle tente d'envoyer le message à la fenêtre qui se trouve au premier plan sur le bureau.
En entrée, elle reçoit un tableau de chaines contenant les valeurs des divers éléments de la structure d'une commande WM_GESTURE.
(affiche_log est une routine annexe remplissant une fenêtre d'infos)
Si le N° du message mess = WM_GESTURE (&H119) j'obtiens systématiquement une erreur "6" (ERROR_INVALID_HANDLE).
Si je met une valeur "non système" dans mess (100200 par ex), le message est bien envoyé sans erreur.
Je n'arrive pas à comprendre cette erreur.
help, help, help :arf: