2013-02-09 77 views
4

試圖澄清win32api對我來說。並舉了一個簡單的例子。獲取記事本窗口,移動鼠標來定位點擊並寫入字符串。但它不起作用。什麼問題?而且會有人可以澄清我的lParam參數嗎?這是幹什麼的?哪種類型?它看起來像什麼? :) 在此先感謝。Python win32api SendMesage

import win32api, win32con, win32gui, win32ui, win32service, os, time 



def f_click(pycwnd): 
     x=300 
     y=300 
     lParam = y <<15 | x 
     pycwnd.SendMessage(win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lParam); 
     pycwnd.SendMessage(win32con.WM_LBUTTONUP, 0, lParam); 

def get_whndl(): 
     whndl = win32gui.FindWindowEx(0, 0, None, 'NB.txt - Notepad') 
     return whndl 

def make_pycwnd(hwnd):  
     PyCWnd = win32ui.CreateWindowFromHandle(hwnd) 
     return PyCWnd 

def send_input_hax(pycwnd, msg): 
    f_click(pycwnd) 
    for c in msg: 
     if c == "\n": 
      pycwnd.SendMessage(win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) 
      pycwnd.SendMessage(win32con.WM_KEYUP, win32con.VK_RETURN, 0) 
     else: 
      pycwnd.SendMessage(win32con.WM_CHAR, ord(c), 0) 
    pycwnd.UpdateWindow() 

whndl = get_whndl() 
pycwnd = make_pycwnd(whndl) 
msg = "It works !\n" 
send_input_hax(pycwnd,msg) 

回答

7

記事本的主窗口還有另一個窗口,您需要發送消息給它。你可以看到這個「隱藏」窗口,微軟間諜++工具或者你可以得到所有子窗口,像這樣:

我們正在尋找
def callback(hwnd, hwnds): 
    if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd): 
     hwnds[win32gui.GetClassName(hwnd)] = hwnd 
    return True 

hwnds = {} 
win32gui.EnumChildWindows(whndl, callback, hwnds) 

窗口有「編輯」類的名字,它是唯一的啓用和可見的子窗口爲記事本。所以,你的代碼會以這種方式工作:

import win32api, win32con, win32gui, win32ui, win32service, os, time 


def f_click(pycwnd): 
    x=300 
    y=300 
    lParam = y <<15 | x 
    pycwnd.SendMessage(win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lParam); 
    pycwnd.SendMessage(win32con.WM_LBUTTONUP, 0, lParam); 

def get_whndl(): 
    whndl = win32gui.FindWindowEx(0, 0, None, 'NB.txt - Notepad') 
    return whndl 

def make_pycwnd(hwnd):  
    PyCWnd = win32ui.CreateWindowFromHandle(hwnd) 
    return PyCWnd 

def send_input_hax(pycwnd, msg): 
    f_click(pycwnd) 
    for c in msg: 
     if c == "\n": 
      pycwnd.SendMessage(win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) 
      pycwnd.SendMessage(win32con.WM_KEYUP, win32con.VK_RETURN, 0) 
     else: 
      pycwnd.SendMessage(win32con.WM_CHAR, ord(c), 0) 
    pycwnd.UpdateWindow() 

whndl = get_whndl() 

def callback(hwnd, hwnds): 
    if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd): 
     hwnds[win32gui.GetClassName(hwnd)] = hwnd 
    return True 
hwnds = {} 
win32gui.EnumChildWindows(whndl, callback, hwnds) 
whndl = hwnds['Edit'] 

pycwnd = make_pycwnd(whndl) 
msg = "It works !\n" 
send_input_hax(pycwnd,msg) 

lParam的是int和你在這裏看到的是技巧,可以讓你通過一個參數傳遞多個值。假設我們需要將兩位數字傳遞給只有一個參數的函數。我們可以將它們以雙位數字的形式發送,並將它分成功能。同樣的方式按位移位(< <)和按位或(|)操作也可逆式在您的情況:

>>> x = 300 
>>> y = 300 
>>> lParam = y << 15 | x 
>>> lParam & 0x7FFF # x 
0: 300 
>>> lParam >> 15 # y 
1: 300 

可以在WikipediaPython Wiki瞭解更多關於位運算。

+2

謝謝,您的解釋和維基爲我澄清,它現在可以工作。是的,記事本有另一個子窗口。但是我會對lParam發表評論。這是一個只有4個字節的數字,所以爲了得到正確的lParam值,我應該將整數(x = 300,y = 300)的座標轉換爲2個字節的數字(WORD),而不是按正確的順序連接它們(低位字爲x,高是y)。 Btw在C++中有宏MAKELPARAM(),所以你也可以通過使用ctypes模塊在python中調用它。 – user2046488 2013-02-10 14:08:06