2013-04-06 16 views
5

Voglio ottenere l'handle di ogni nuova finestra di dialogo che si apre da un'applicazione specifica.
Capisco che dovrei impostare un hook con SetWinEventHook che è in user32.dll in Windows, ma non so come farlo in Python. Mi daresti un esempio?Come usare winapi SetWinEventHook in python?

+0

si potrebbe trovare il [pyHook] (http://sourceforge.net/apps/mediawiki/ pyhook/index.php? title = Main_Page) python wrapper utile. – martineau

+0

è utile solo per eventi mouse e tastiera e la logica principale è nascosta in un file .pyd :( – kissgyorgy

+1

PyHook è open-source, quindi puoi guardare il codice sorgente per un esempio, ce ne sono altri là fuori, come [ pyconsole] (http://code.google.com/p/pyconsole/source/browse/trunk/pyconsole.py?r=5) puoi anche guardare, basta usare [Google] (https://www.google .com/search? hl = it & 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 =). A meno che tu non scriva o usi un modulo di estensione C, tu Probabilmente avremo bisogno di conoscere e utilizzare molti dei moduli incorporati 'win32xxx' e' ctypes.windll.user32'. – martineau

risposta

7

Ecco un esempio molto semplice che stampa alla console il testo finestra per ogni finestra di dialogo che si apre:

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

bello e pulito! Grazie! Un'ultima domanda: cosa succede se non lo faccio? UnhookWinEvent' (ad esempio, la mia app si arresta in modo anomalo o qualcosa del genere) – kissgyorgy

+1

Il sistema lo pulisce per te.Se hai bisogno che l'hook sia attivo per l'intera durata del processo, non è necessario preoccuparsi di chiamare 'UnhookWinEvent' o' CoUninitialize'. –

+0

Grazie mille! Risposta molto soddisfacente! – kissgyorgy