2010-06-03 19 views
5

ı ki, bir fare belirli x'in tıklayın simüle etmek istediğiniz bir pencere var diyelim tıklayın simüle y koordinatı. Ben zaten hwnd var ama emin değilim lParam nasıl inşa edilir. Düğmelerde vb. 'u tıklatmak için geçmişte SendMessage kullandım, ancak onların hwnd'lerini biliyordum. Herhangi bir yardım büyük takdir edilecektir. Ben de yardımcı olamıyorum ama merak ediyorum, bu konuda doğru yoldan gidiyorum. Son hedefim, skype ana penceresindeki belirli bir kullanıcısını tıklıyor (örneğin). Tüm ana pencerenin çocuklarını bulmak için EnumChildWindows kullandım, ancak doğru olanı bulamadım. Yani , koordinatları kullanarak üzerine 'tıklamaya' çalışacağımı düşündüm.piton win32

cevap

7

Sen ctypes düşük seviyeli pencereler API sayesinde kullanabilirsiniz. Aşağıdaki örneğe bakın (bir şey uyarlanan ben bunu test etmedi ama ok olmalıdır)

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) 

Güncelleme: Ben aşağıdaki kodu test etmedi ama bir şey yazmaya yardımcı olması gerektiğine inanıyoruz Çocuk pozisyonunu al. Sonra doğru pozisyona tıklamayı deneyebilirsiniz.

CHILD= None 

def the_callback(child_hwnd, regex): 
    '''Pass to win32gui.EnumWindows() to check all the opened windows''' 
    if re.match(regex, win32gui.GetWindowText(child_hwnd)): 
     CHILD= child_hwnd 

win32gui.EnumChildWindows(hwnd, the_callback, regex) 


if CHILD: 
    (x_tl, y_tl, x_br, y_br) = win32gui.GetWindowRect(CHILD) 
+0

hi teşekkürler. btw, ana pencerenin ve çocuk pencerelerinin birçoğunun da hwnds ile olduğunu söyleyebilmenizi sağlar ... tüm bu çocukların karşısına belirli bir metin içeriği için nasıl bakabilirim? ve doğru olanı tanımlayın, böylece bu metne tıklayabilirim (link)? ... – nabizan

+0

@nabizan: güncellemeye bakın. Umarım yanlış olursa – luc

+0

hmmm bana yardımcı olur * .GetWindowText sadece pencerenin başlığını döndürür. bu benim için yeni bir şey ve ben bunu nasıl çalıştığını tam olarak bilmiyorum ama o zaman bazı karmaşık app (örneğin photoshop) ana hwnd ve çocukların pencerelerin demet (onlar bir başlık yok) olsun bir pencere açmak düşünüyorum ilk başta, belirli bir alt pencere, örneğin rasgele oluşturulmuş bağlantılarla çalışmayı bulmanız gerekiyor ve bundan sonra tıklatabilirsiniz ... Buradaki doğru yolun kör olup olmadığını bilmiyorum – nabizan

8

Bunun sizin için iyi olduğunu düşünüyorum, bunu doğrudan kullanabilir veya python programınıza aktarabilirsiniz. Hızlı cevap için

"""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

teşekkürler güzel görünüyor – nabizan

+0

Bu tamamen harika! Teşekkürler. – IronManMark20