Hola
Casi tenía este tema resuelto, gracias a una UDF que casi tengo terminada.
Detecta los tooltips de tipo tooltips_class32 y obtiene datos de los tooltips mediante varias funciones, como el texto, título, tamaño, posición...
Pero falla en una cosa. Resulta, que si hacemos un script con el siguiente código:
Código: Seleccionar todo
tooltip("mostrando tooltip de prueba", 125, 95, "Tooltip de prueba", 0, 1)
Exit
Como según la ayuda de Tooltip() el tooltip se mantiene visible durante la ejecución del script, o hasta que se elimine con:
y en el código anterior el programa se cierra nada más lanzar el tooltip, parece que con WinList("[class:tooltips_class32]") no se puede capturar el tooltip ni con un timer que se ejecute cada 0 milisegundos.
Así pues, como dijo Chefito, además esto tiene que sobrecargar mucho la cpu, me he puesto a mirar como capturar los mensajes de Windows, para capturar los mensajes que tengan que ver con tooltips.
La única forma que he visto de hacer esto, es con hooks. Así pues, tirando del código de Chefito que crea ganchos de teclado y comprueba las teclas pulsadas, que hay en varios post y leyendo la documentación de SetWindowsHooksEx en la msdn, he hecho un script que crea un gancho para capturar los mensajes que Windows envía a las aplicaciones (a las ventanas, según la msdn).
No se que habrá mal, pero no funciona bien. Al cerrar el programa con Escape, aparece un error de Windows de prevención de ejecución de datos; al darle a cerrar en ese mensaje, aparece el informe de errores de rundll32.exe un montón de veces... Parece, que sí recibe bien los códigos de mensajes que se van generando, pero no termina de ir.
Pongo el código, a ver si sabeis por qué puede ser que falle:
Código: Seleccionar todo
#Include <WinAPI.au3>
Global $WMsgProcRegister
Global $HMod
Global $WMsgHook
Global $Kernel32DLL
Global $User32DLL
HotKeySet("{esc}", "Esc_Function")
$Kernel32DLL=DllOpen("Kernel32.dll")
$User32DLL=DllOpen("User32.dll")
If ($Kernel32DLL==-1 Or $User32DLL==-1) Then
Msgbox(0, "", "Error al iniciar dlls")
Exit
EndIf
If WinMessagesHooksStart()==0 Then
Msgbox(0, "", "Error al iniciar la captura de mensajes de Windows")
Exit
Else
Msgbox(0, "", "Capturando mensajes de Windows."&@CRLF&"Pulsar escape para cerrar el programa.")
EndIf
Func WinMessagesHooksStart()
MsgProcRegister=DllCallbackRegister("_WMsgProc", "long", "int;wparam;lparam")
If $WMsgProcRegister==0 Then Return 0
$HMod=DllCall($Kernel32DLL, "hwnd", "GetModuleHandle", "ptr", 0)
If (Not IsArray($HMod) Or @Error<>0) Then Return 0
$WMsgHook=DllCall($User32DLL, "hwnd", "SetWindowsHookEx", "int", $WH_CALLWNDPROC, "ptr", DllCallbackGetPtr($WMsgProcRegister), "hwnd", $HMod[0], "dword", 0)
If (Not IsArray($WMsgHook) Or @Error<>0) Then Return 0
Return 1
EndFunc
Func WinMessagesHooksQuit()
If IsArray($WMsgHook) Then
$WMsgHook=DllCall($User32DLL, "int", "UnhookWindowsHookEx", "hwnd", $WMsgHook[0])
If @Error<>0 Then Return 0
Else
Return 0
EndIf
DllCallbackFree($WMsgProcRegister)
Return 1
EndFunc
Func _WMsgProc($NCode, $WParam, $LParam)
Local $WMsgHookStruct, $Msg_Code
Local $Aditional_Param_0_Code, $Aditional_Param_1_Code
Local $Hwnd_Message
$WMsgHookStruct=DllStructCreate("lparam;wparam;uint;hwnd", $LParam)
If ($WMsgHookStruct==0 And @Error<>0) Then Return _WinAPI_CallNextHookEx($WMsgHook, $NCode, $WParam, $LParam)
$Aditional_Param_0_Code=DllStructGetData($WMsgHookStruct, 1)
If ($Aditional_Param_0_Code==0 And @Error<>0) Then Return _WinAPI_CallNextHookEx($WMsgHook, $NCode, $WParam, $LParam)
$Aditional_Param_1_Code=DllStructGetData($WMsgHookStruct, 2)
If ($Aditional_Param_1_Code==0 And @Error<>0) Then Return _WinAPI_CallNextHookEx($WMsgHook, $NCode, $WParam, $LParam)
$Msg_Code=DllStructGetData($WMsgHookStruct, 3)
If ($Msg_Code==0 And @Error<>0) Then Return _WinAPI_CallNextHookEx($WMsgHook, $NCode, $WParam, $LParam)
$Hwnd_Message=DllStructGetData($WMsgHookStruct, 4)
If ($Hwnd_Message==0 And @Error<>0) Then Return _WinAPI_CallNextHookEx($WMsgHook, $NCode, $WParam, $LParam)
ConsoleWrite($Msg_Code)
Return _WinAPI_CallNextHookEx($WMsgHook, $NCode, $WParam, $LParam)
EndFunc
Func Esc_Function()
WinMessagesHooksQuit()
Exit
EndFunc
While 1
Sleep(10)
Wend
De paso, a ver si sabéis decirme si es esta la forma que hay de capturar los mensajes de Windows. Con GetMessage() vi en la msdn que solo se pueden capturar mensajes en el mismo hilo que se ejecuta el programa que llama a la api, y no he visto más formas de hacerlo (deberían de capturarse los mensajes de todo el sistema) para poder capturar todos los tooltips.
Acias,
Salu2!