2013-04-06 15 views
5

Chcę uzyskać uchwyt każdego nowego okna dialogowego, które wyskakuje z określonej aplikacji.
Rozumiem, że powinienem ustawić hak z SetWinEventHook, który jest w user32.dll w oknach, ale nie wiem jak to zrobić w pythonie. Dałbyś mi przykład?Jak korzystać z Winapi SetWinEventHook w python?

+0

Można wybrać [pyHook] (http://sourceforge.net/apps/mediawiki/ pyhook/index.php? title = Main_Page) użyteczne narzędzie Python. – martineau

+0

jest to użyteczne tylko dla zdarzeń myszy i klawiatury, a główna logika jest ukryta w pliku .pyd :( – kissgyorgy

+1

PyHook jest open-source, więc możesz spojrzeć na przykładowy kod źródłowy. pyconsole] (http://code.google.com/p/pyconsole/source/browse/trunk/pyconsole.py?r=5) możesz również obejrzeć, po prostu użyj [Google] (https://www.google .com/search? hl = en & as_q = python & as_epq = SetWinEventHook & as_oq = & as_eq = & as_nlo = & as_nhi = & lr = & cr = & as_qdr = all & as_sitesearch = & as_occt = any & safe = images & tbs = & as_filetype = & as_rights =). Jeśli nie piszesz lub nie używasz modułu rozszerzenia C, "prawdopodobnie będzie potrzebować poznać i używać kilku wbudowanych modułów' win32xxx' i 'ctypes.windll.user32'. – martineau

Odpowiedz

7

Oto bardzo prosty przykład, który wypisuje na konsoli tekst dla każdego okna dialogowego który jest otwarty:

import sys 
import time 
import ctypes 
import ctypes.wintypes 

EVENT_SYSTEM_DIALOGSTART = 0x0010 
WINEVENT_OUTOFCONTEXT = 0x0000 

user32 = ctypes.windll.user32 
ole32 = ctypes.windll.ole32 

ole32.CoInitialize(0) 

WinEventProcType = ctypes.WINFUNCTYPE(
    None, 
    ctypes.wintypes.HANDLE, 
    ctypes.wintypes.DWORD, 
    ctypes.wintypes.HWND, 
    ctypes.wintypes.LONG, 
    ctypes.wintypes.LONG, 
    ctypes.wintypes.DWORD, 
    ctypes.wintypes.DWORD 
) 

def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime): 
    length = user32.GetWindowTextLengthA(hwnd) 
    buff = ctypes.create_string_buffer(length + 1) 
    user32.GetWindowTextA(hwnd, buff, length + 1) 
    print buff.value 

WinEventProc = WinEventProcType(callback) 

user32.SetWinEventHook.restype = ctypes.wintypes.HANDLE 
hook = user32.SetWinEventHook(
    EVENT_SYSTEM_DIALOGSTART, 
    EVENT_SYSTEM_DIALOGSTART, 
    0, 
    WinEventProc, 
    0, 
    0, 
    WINEVENT_OUTOFCONTEXT 
) 
if hook == 0: 
    print 'SetWinEventHook failed' 
    sys.exit(1) 

msg = ctypes.wintypes.MSG() 
while user32.GetMessageW(ctypes.byref(msg), 0, 0, 0) != 0: 
    user32.TranslateMessageW(msg) 
    user32.DispatchMessageW(msg) 

user32.UnhookWinEvent(hook) 
ole32.CoUninitialize() 
+0

fajne i czyste! Dziękuję! Ostatnie pytanie: co się stanie, jeśli nie będę? UnhookWinEvent' (na przykład moje awarie aplikacji lub coś podobnego) – kissgyorgy

+1

System wyczyści to za Ciebie .Jeśli potrzebujesz haka do aktywności przez cały czas trwania procesu, nie musisz zawracać sobie głowy wywołaniem "UnhookWinEvent" lub "CoUninitialize". –

+0

Dziękuję bardzo! Bardzo satysfakcjonująca odpowiedź! – kissgyorgy