2012-10-13 83 views
4

我正在嘗試使Teamviewer像一塊軟件一樣有趣,它允許一個人查看另一個人的屏幕並單擊以及所有這些。無論如何,我已經完成了大部分套接字工作,但我不知道如何讓鼠標點擊正常工作。下面是我在網上找到了編程移動鼠標代碼:在C#中移動鼠標(座標單位)

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); 
    } 
} 

現在我想移動使用moveTo方法鼠標,但它需要的任何運動瘋狂的高數字。無論如何,我可以匹配座標移動到屏幕上的位置像素?對不起,如果這看起來像一個明顯的問題,但我已經GOOGLE了近一個小時,我找不到什麼單位正在使用鼠標x和y位置的討論,所以我不能設置任何類型的公式來匹配一個面板上的點擊以點擊用戶的屏幕。

+3

['Cursor.Position'](http://msdn.microsoft.com/en-us/library/system.windows.forms.cursor.position.aspx)看起來很有前景。 – chris

回答

5

Microsoft's documentation

如果指定MOUSEEVENTF_ABSOLUTE值,dx和dy含有0和65535之間的歸一化的 絕對座標。程序 將這些座標映射到顯示錶面上。座標 (0,0)映射到顯示錶面的左上角, (65535,65535)映射到右下角。

你可以用它來輸入轉換成像素爲需要的值,比如:

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); 

請記住,這可能不是多個監視器正確。另請注意,文檔中提到:

此功能已被取代。改爲使用SendInput

附錄:作爲pointed by J3soon上述公式可能不是最好的。基於research done for AutoHokey內部下面的代碼工作得更好:

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

參考見AutoHotkey source code


如果我在你的位置,我會使用Cursor.Position。下面的代碼按預期方式工作:

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

是的,它把鼠標指針的座標(200,200)的屏幕的像素[測試在LinqPad]。

附錄:我看看System.Windows.Forms.Cursor.Position在內部使用什麼 - 至少在Windows上使用Mono。這是致電SetCursorPos。沒有奇怪的座標轉換需要。

+0

'inputXinPixels * 65536/SCREEN_WIDTH + 1'在我的情況下效果更好,它也用於[AutoHotKey](https://github.com/Lexikos/AutoHotkey_L/blob/58842fb2956fe082bc11476316d4590b0e2ee8a8/source/keyboard_mouse.cpp#L2545)。 – J3soon