2012-10-13 11 views
4

J'essaie de faire de Teamviewer un logiciel amusant, qui permet à une personne de voir l'écran d'une autre personne et de cliquer sur tout ça. Quoi qu'il en soit, j'ai la plupart des choses de socket, mais je ne sais pas comment faire pour que les clics de la souris fonctionnent correctement. Voici le code que je trouve en ligne pour déplacer la souris programme:Déplacer la souris en C# (unités de coordonnées)

public static class VirtualMouse 
{ 
    // import the necessary API function so .NET can 
    // marshall parameters appropriately 
    [DllImport("user32.dll")] 
    static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo); 

    // constants for the mouse_input() API function 
    private const int MOUSEEVENTF_MOVE = 0x0001; 
    private const int MOUSEEVENTF_LEFTDOWN = 0x0002; 
    private const int MOUSEEVENTF_LEFTUP = 0x0004; 
    private const int MOUSEEVENTF_RIGHTDOWN = 0x0008; 
    private const int MOUSEEVENTF_RIGHTUP = 0x0010; 
    private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; 
    private const int MOUSEEVENTF_MIDDLEUP = 0x0040; 
    private const int MOUSEEVENTF_ABSOLUTE = 0x8000; 


    // simulates movement of the mouse. parameters specify changes 
    // in relative position. positive values indicate movement 
    // right or down 
    public static void Move(int xDelta, int yDelta) 
    { 
     mouse_event(MOUSEEVENTF_MOVE, xDelta, yDelta, 0, 0); 
    } 


    // simulates movement of the mouse. parameters specify an 
    // absolute location, with the top left corner being the 
    // origin 
    public static void MoveTo(int x, int y) 
    { 
     mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x, y, 0, 0); 
    } 


    // simulates a click-and-release action of the left mouse 
    // button at its current position 
    public static void LeftClick() 
    { 
     mouse_event(MOUSEEVENTF_LEFTDOWN, Control.MousePosition.X, Control.MousePosition.Y, 0, 0); 
     mouse_event(MOUSEEVENTF_LEFTUP, Control.MousePosition.X, Control.MousePosition.Y, 0, 0); 
    } 
} 

Maintenant, je veux déplacer la souris en utilisant la méthode MoveTo, mais il nécessite un nombre élevé fous pour tout mouvement. Y at-il de toute façon que je peux faire correspondre les coordonnées pour déplacer ici à la position sur l'écran en pixels? Désolé si cela semble une question évidente, mais j'ai googlé pendant près d'une heure et je ne peux trouver aucune discussion sur les unités qui sont utilisées pour la position de la souris x et y, donc je ne peux pas mettre en place une sorte de formule pour faire correspondre les clics sur un panneau à des clics sur l'écran de l'utilisateur.

+3

['Cursor.Position'] (http://msdn.microsoft.com/en-us/library/system.windows.forms.cursor.position.aspx) semble prometteur. – chris

Répondre

5

De Microsoft's documentation:

Si la valeur MOUSEEVENTF_ABSOLUTE est spécifiée, dx et dy contiennent coordonnées absolues normalisées entre 0 et 65535. La procédure événementielle mappe ces coordonnées sur la surface d'affichage. Coordonner (0,0) des cartes sur le coin supérieur gauche de la surface d'affichage, (65535,65535) des cartes sur le coin inférieur droit.

Vous pouvez l'utiliser pour convertir l'entrée en pixels à la valeur souhaitée, comme ceci:

var inputXinPixels = 200; 
var inputYinPixels = 200; 
var screenBounds = System.Windows.Forms.Screen.PrimaryScreen.Bounds; 
var outputX = inputXinPixels * 65535/screenBounds.Width; 
var outputY = inputYinPixels * 65535/screenBounds.Height; 
MoveTo(outputX, outputY); 

S'il vous plaît garder à l'esprit que cela peut ne pas être correct pour plusieurs moniteurs. Notez également que la documentation indique:

Cette fonction a été annulée. Utilisez SendInput à la place.

Addendum: Comme pointed by J3soon la formule ci-dessus pourrait ne pas être le meilleur. Sur la base de research done for AutoHokey le le code suivant interne fonctionne mieux:

var outputX = (inputXinPixels * 65536/screenBounds.Width) + 1; 
var outputY = (inputYinPixels * 65536/screenBounds.Height) + 1; 

Voir AutoHotkey source code pour référence.


Si j'étais dans votre position, j'utiliserais Cursor.Position. Le code suivant fonctionne comme prévu:

System.Windows.Forms.Cursor.Position = new System.Drawing.Point(200, 200); 

Oui, il place le pointeur de la souris dans les coordonnées (200, 200) pixels de l'écran [testé sur LINQPad].

Addendum: J'ai regardé ce que System.Windows.Forms.Cursor.Position utilise en interne - Au moins sous Windows. C'est un appel au SetCursorPos. Pas de conversion de coordonnées bizarre nécessaire.

+0

'inputXinPixels * 65536/SCREEN_WIDTH + 1' fonctionne mieux dans mon cas, qui est également utilisé dans [AutoHotKey] (https://github.com/Lexikos/AutoHotkey_L/blob/58842fb2956fe082bc11476316d4590b0e2ee8a8/source/keyboard_mouse.cpp#L2545). – J3soon

Questions connexes