2010-06-03 20 views
5

Angenommen, ich habe ein Fenster, für das ich einen Mausklick an einer bestimmten x, y-Koordinate simulieren möchte. Ich habe bereits die hwnd, aber ich bin mir nicht sicher wie das lParam zu konstruieren. Ich habe SendMessage in der Vergangenheit verwendet, um auf Schaltflächen usw. auf zu klicken, aber ich kannte ihre hwnds. Jede Hilfe würde sehr geschätzt werden. Ich kann auch nicht helfen, aber frage mich, ob Ich gehe über den richtigen Weg. Mein Endziel ist das Klicken auf einen bestimmten Benutzer im Skype-Hauptfenster (zum Beispiel). Ich habe EnumChildWindows verwendet, um alle untergeordneten Fenster des Hauptfensters zu finden, konnte aber nicht das richtige finden. So dachte ich würde versuchen, mit Koordinaten darauf zu klicken.python win32 simulieren klicken

Antwort

7

Sie können die Low-Level-Windows-API dank Ctypes verwenden. Sehen Sie ein Beispiel unten (angepasst von etwas, das ich es nicht getestet, aber es sollte in Ordnung sein)

import ctypes 
MOUSEEVENTF_MOVE = 0x0001 # mouse move 
MOUSEEVENTF_ABSOLUTE = 0x8000 # absolute move 
MOUSEEVENTF_MOVEABS = MOUSEEVENTF_MOVE + MOUSEEVENTF_ABSOLUTE 

MOUSEEVENTF_LEFTDOWN = 0x0002 # left button down 
MOUSEEVENTF_LEFTUP = 0x0004 # left button up 
MOUSEEVENTF_CLICK = MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP 

def click(x, y): 
    #move first 
    x = 65536L * x/ctypes.windll.user32.GetSystemMetrics(0) + 1 
    y = 65536L * y/ctypes.windll.user32.GetSystemMetrics(1) + 1 
    ctypes.windll.user32.mouse_event(MOUSEEVENTF_MOVEABS, x, y, 0, 0) 

    #then click 
    ctypes.windll.user32.mouse_event(MOUSEEVENTF_CLICK, 0, 0, 0, 0) 

Update: teste ich nicht den Code unten, aber ich denke, dass es Ihnen etwas schreiben helfen soll Holen Sie sich die Kinderposition. Dann können Sie versuchen, an der richtigen Stelle zu klicken.

+0

hallo danke für schnelle antwort. btw lässt uns sagen, dass Sie das Hauptfenster und die Fenster seiner Kinderfenster auch mit ihren Hwnds haben ... Wissen Sie, wie ich nach einem bestimmten Textinhalt suchen könnte? und den richtigen identifizieren, damit ich auf diesen Text (Link) klicken kann? ... – nabizan

+0

@nabizan: sehe mein Update. Ich hoffe, es hilft – luc

+0

hmmm korrigiert mich, wenn ich falsch bin, aber * .GetWindowText gibt nur Titel des Fensters zurück. das ist etwas neues für mich und ich weiß nicht, wie genau es funktioniert, aber ich denke, dass, wenn Sie ein Fenster von einer komplexen App (zB Photoshop) öffnen Sie Haupt-HWND und Haufen Kinderfenster (sie haben keinen Titel) so müssen Sie zuerst das eine spezifische Kindfenster finden, das zum Beispiel mit einigen zufällig generierten Verbindungen funktioniert und danach können Sie es klicken ... ich weiß nicht, ob es der richtige Weg ist, hier blind zu gehen – nabizan

8

Ich denke, das ist gut für Sie, können Sie direkt verwenden oder importieren Sie dies zu Ihrem Python-Programm.

"""mousemacro.py defines the following functions: 

click() -- calls left mouse click 
hold() -- presses and holds left mouse button 
release() -- releases left mouse button 

rightclick() -- calls right mouse click 
righthold() -- calls right mouse hold 
rightrelease() -- calls right mouse release 

middleclick() -- calls middle mouse click 
middlehold() -- calls middle mouse hold 
middlerelease() -- calls middle mouse release 

move(x,y) -- moves mouse to x/y coordinates (in pixels) 
getpos() -- returns mouse x/y coordinates (in pixels) 
slide(x,y) -- slides mouse to x/y coodinates (in pixels) 
       also supports optional speed='slow', speed='fast' 
""" 

from ctypes import* 
from ctypes.wintypes import * 
from time import sleep 
import win32ui 

__all__ = ['click', 'hold', 'release', 'rightclick', 'righthold', 'rightrelease', 'middleclick', 'middlehold', 'middlerelease', 'move', 'slide', 'getpos'] 

# START SENDINPUT TYPE DECLARATIONS 
PUL = POINTER(c_ulong) 

class KeyBdInput(Structure): 
    _fields_ = [("wVk", c_ushort), 
      ("wScan", c_ushort), 
      ("dwFlags", c_ulong), 
      ("time", c_ulong), 
      ("dwExtraInfo", PUL)] 

class HardwareInput(Structure): 
    _fields_ = [("uMsg", c_ulong), 
      ("wParamL", c_short), 
      ("wParamH", c_ushort)] 

class MouseInput(Structure): 
    _fields_ = [("dx", c_long), 
      ("dy", c_long), 
      ("mouseData", c_ulong), 
      ("dwFlags", c_ulong), 
      ("time",c_ulong), 
      ("dwExtraInfo", PUL)] 

class Input_I(Union): 
    _fields_ = [("ki", KeyBdInput), 
       ("mi", MouseInput), 
       ("hi", HardwareInput)] 

class Input(Structure): 
    _fields_ = [("type", c_ulong), 
      ("ii", Input_I)] 

class POINT(Structure): 
    _fields_ = [("x", c_ulong), 
      ("y", c_ulong)] 
# END SENDINPUT TYPE DECLARATIONS 

    # LEFTDOWN = 0x00000002, 
    # LEFTUP  = 0x00000004, 
    # MIDDLEDOWN = 0x00000020, 
    # MIDDLEUP = 0x00000040, 
    # MOVE  = 0x00000001, 
    # ABSOLUTE = 0x00008000, 
    # RIGHTDOWN = 0x00000008, 
    # RIGHTUP = 0x00000010 

MIDDLEDOWN = 0x00000020 
MIDDLEUP = 0x00000040 
MOVE  = 0x00000001 
ABSOLUTE = 0x00008000 
RIGHTDOWN = 0x00000008 
RIGHTUP = 0x00000010 


FInputs = Input * 2 
extra = c_ulong(0) 

click = Input_I() 
click.mi = MouseInput(0, 0, 0, 2, 0, pointer(extra)) 
release = Input_I() 
release.mi = MouseInput(0, 0, 0, 4, 0, pointer(extra)) 

x = FInputs((0, click), (0, release)) 
#user32.SendInput(2, pointer(x), sizeof(x[0])) CLICK & RELEASE 

x2 = FInputs((0, click)) 
#user32.SendInput(2, pointer(x2), sizeof(x2[0])) CLICK & HOLD 

x3 = FInputs((0, release)) 
#user32.SendInput(2, pointer(x3), sizeof(x3[0])) RELEASE HOLD 


def move(x,y): 
    windll.user32.SetCursorPos(x,y) 

def getpos(): 
    global pt 
    pt = POINT() 
    windll.user32.GetCursorPos(byref(pt)) 
    return pt.x, pt.y 

def slide(a,b,speed=0): 
    while True: 
     if speed == 'slow': 
      sleep(0.005) 
      Tspeed = 2 
     if speed == 'fast': 
      sleep(0.001) 
      Tspeed = 5 
     if speed == 0: 
      sleep(0.001) 
      Tspeed = 3 

     x = getpos()[0] 
     y = getpos()[1] 
     if abs(x-a) < 5: 
      if abs(y-b) < 5: 
       break 

     if a < x: 
      x -= Tspeed 
     if a > x: 
      x += Tspeed 
     if b < y: 
      y -= Tspeed 
     if b > y: 
      y += Tspeed 
     move(x,y) 


def click(): 
    windll.user32.SendInput(2,pointer(x),sizeof(x[0])) 

def hold(): 
    windll.user32.SendInput(2, pointer(x2), sizeof(x2[0])) 

def release(): 
    windll.user32.SendInput(2, pointer(x3), sizeof(x3[0])) 


def rightclick(): 
    windll.user32.mouse_event(RIGHTDOWN,0,0,0,0) 
    windll.user32.mouse_event(RIGHTUP,0,0,0,0) 

def righthold(): 
    windll.user32.mouse_event(RIGHTDOWN,0,0,0,0) 

def rightrelease(): 
    windll.user32.mouse_event(RIGHTUP,0,0,0,0) 


def middleclick(): 
    windll.user32.mouse_event(MIDDLEDOWN,0,0,0,0) 
    windll.user32.mouse_event(MIDDLEUP,0,0,0,0) 

def middlehold(): 
    windll.user32.mouse_event(MIDDLEDOWN,0,0,0,0) 

def middlerelease(): 
    windll.user32.mouse_event(MIDDLEUP,0,0,0,0) 

if __name__ == '__main__': 
    while 1: 
     move(10,1) 
+0

danke es sieht gut aus – nabizan

+0

Das ist total genial! Vielen Dank. – IronManMark20