This could be usefull adition to Autoit.
Look at
http://www.autohotkey.com/changelog/
http://www.autohotkey.com/docs/commands/RegisterCallback.htm
Edited by Zedna, 26 November 2007 - 01:36 AM.
Posted 23 June 2007 - 02:24 PM
Edited by Zedna, 26 November 2007 - 01:36 AM.
Posted 27 June 2007 - 10:04 AM
I noticed AutoHotkey added RegisterCallback(), which creates a machine-code address that when called, redirects the call to a function in the script.
This could be usefull adition to Autoit.
Look at
http://www.autohotkey.com/changelog/
http://www.autohotkey.com/docs/commands/RegisterCallback.htm
Posted 27 June 2007 - 02:30 PM
Awesome!!Second here.
On their forum I found tiny dll easily adaptable to use with GUIRegisterMsg (maybe something like was posted here, not found), but native dll-less feature is definitely preferable.
pid:=DllCall("GetCurrentProcessId","Uint") DetectHiddenWindows, On hwnd:=WinExist("ahk_pid " . pid) hHookModule := DllCall("LoadLibrary", "str", "callback\callback.dll") EnumWindowsProcStub:=DllCall("callback\callback.dll\callbackit", "UInt", 2,"UInt", hwnd, "UInt", 0x542, "UInt", 0) OnMessage(0x542, "EnumWindowsProc") GoSub doit OnExit Tidyup AppsKey & F11:: doit: out:= DllCall("EnumWindows","UInt",EnumWindowsProcStub,"UInt",0) EnumWindowsProc(wParam, lParam, msg, hwnd) { global out winid:=GetDeRefInteger(lParam) otherparam:=GetDeRefInteger(lParam+4) DetectHiddenWindows, On WinGetTitle, text, ahk_id %winid% WinGetClass, class, ahk_id %winid% out.="HWND: ". winid . "`tTitle: " . text . "`tClass: " . class . "`n" return 1 } ;Sleep 5000 MsgBox %out% return ;Tidyness Tidyup: DllCall("GlobalFree", "UInt", EnumWindowsProcStub) DllCall("FreeLibrary", "Uint", hHookModule) ExitApp GetDeRefInteger(pSource, pIsSigned = false, pSize = 4) ; pSource is an integer pointer to a raw/binary integer ; The caller should pass true for pSigned to interpret the result as signed vs. unsigned. ; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int). { Loop %pSize% ; Build the integer by adding up its bytes. result += *(pSource + A_Index-1) << 8*(A_Index-1) if (!pIsSigned OR pSize > 4 OR result < 0x80000000) return result ; Signed vs. unsigned doesn't matter in these cases. ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart: return -(0xFFFFFFFF - result + 1) }
Posted 27 June 2007 - 05:12 PM
Here it is (a bit simplified).Awesome!!
Here is the link to that post.
Can somebody experienced translate this EnumWindows.ahk example using callback.dll to EnumWindows.au3 please?
Global $out $hwnd = GUICreate("") $WM_AUTOIT_CALLBACK = DllCall("user32", "int", "RegisterWindowMessage") $WM_AUTOIT_CALLBACK = $WM_AUTOIT_CALLBACK[0] $hHookModule = DllCall("kernel32", "int", "LoadLibrary", "str", "callback.dll") $hHookModule = $hHookModule[0] $EnumWindowsProcStub = DllCall("callback.dll", "int", "callbackit", "uint", 2,"uint", $hwnd, "uint", $WM_AUTOIT_CALLBACK, "uint", 0) $EnumWindowsProcStub = $EnumWindowsProcStub[0] GUIRegisterMsg($WM_AUTOIT_CALLBACK, "EnumWindowsProc") DllCall("user32", "int", "EnumWindows","uint", $EnumWindowsProcStub, "uint", 0) Func EnumWindowsProc($hWnd, $msg, $wParam, $lParam) $struct = DllStructCreate("int;int", $lParam) $out &= "Title: " & WinGetTitle(HWND(DllStructGetData($struct, 1))) & @CRLF Return 1 EndFunc MsgBox (0, "Windows", $out) Func OnAutoitExit() DllCall("kernel32", "int", "GlobalFree", "uint", $EnumWindowsProcStub) DllCall("kernel32", "int", "FreeLibrary", "Uint", $hHookModule) EndFunc
Posted 27 June 2007 - 06:32 PM
#include <A3LMemory.au3> Global $hGUI, $hHook, $iMessage, $pStub $hGUI = GUICreate("") $iMessage = _API_RegisterWindowMessage("AutoItCallback") $hHook = _API_LoadLibrary("CallBack.dll") $pStub = DllCall("CallBack.dll", "int", "callbackit", "uint", 2, "uint", $hGUI, "uint", $iMessage, "uint", 0) $pStub = $pStub[0] GUIRegisterMsg($iMessage, "EnumWindowsProc") DllCall("User32.dll", "int", "EnumWindows", "uint", $pStub, "uint", 0) Func EnumWindowsProc($hWnd, $msg, $wParam, $lParam) Local $tStruct, $sText $tStruct = DllStructCreate("int;int", $lParam) $sText = WinGetTitle(HWND(DllStructGetData($tStruct, 1))) if $sText <> "" then _Lib_ConsoleWrite($sText) Return 1 EndFunc Func OnAutoitExit() _Mem_GlobalFree ($pStub) _API_FreeLibrary($hHook) EndFunc
Posted 27 June 2007 - 07:23 PM
Posted 27 June 2007 - 08:13 PM
Posted 27 June 2007 - 08:30 PM
mmm it could be the solution for the listview sort
if anyone can do it
Posted 27 June 2007 - 08:41 PM
Posted 27 June 2007 - 09:17 PM
#include <A3LMemory.au3> Global $hHook, $iMessage, $pStub Func _RegisterCallBack($hWnd, $FunctioName $iMessage = _API_RegisterWindowMessage("AutoItCallback") $hHook = _API_LoadLibrary("CallBack.dll") $pStub = DllCall("CallBack.dll", "int", "callbackit", "uint", 2, "uint", $hWnd, "uint", $iMessage, "uint", 0) $pStub = $pStub[0] GUIRegisterMsg($iMessage, $FunctioName) Return $pStub EndFunc Func OnAutoitExit() _Mem_GlobalFree ($pStub) _API_FreeLibrary($hHook) EndFunc
Posted 28 June 2007 - 01:24 AM
Global $g_hDll_CallBack = DllOpen("Callback.dll") Func _DllCallBackAlloc($nParameters, $hWnd, $msg, $wParam = 0) Local $hStub If $g_hDll_CallBack < 0 Then Return SetError(1, 0, 0) $hStub = DllCall($g_hDll_CallBack, "ptr", "callbackit", "uint", $nParameters, "hwnd", $hWnd, "uint", $msg, "ptr", $wParam) If @error Then Return SetError(2, 0, 0) If $hStub[0] = 0 Then Return SetError(2, 0, 0) Return $hStub[0] EndFunc ;==>_DllCallBackAlloc Func _DllCallBackFree(ByRef $hStub) Local $aTmp If $hStub > 0 Then $aTmp = DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $hStub) If @error Then Return SetError(1, 0, False) If $aTmp[0] = $hStub Then Return SetError(2, 0, False) If $aTmp[0] = 0 Then $hStub = 0 Return True EndIf Return False EndIf Return True EndFunc ;==>_DllCallBackFree ;--------------------------- Global Const $WM_USER = 0x400 Global $hWnd_dummy = GUICreate(""), $sOut GUIRegisterMsg($WM_USER + 1, "_EnumWindowStationProc") Func _EnumWindowStationProc($hWnd, $msg, $wParam, $lParam) $Param = DllStructCreate("ptr;ptr", $lParam) $station = DllStructCreate("char[256]", DllStructGetData($Param, 1)) $sOut &= DllStructGetData($station, 1) & @CRLF Return 1 EndFunc ;==>_EnumWindowStationProc $hStub_EnumWindowStationProc = _DllCallBackAlloc(2, $hWnd_dummy, $WM_USER + 1) DllCall("user32.dll", "int", "EnumWindowStations", "ptr", $hStub_EnumWindowStationProc, "long", 0) _DllCallBackFree($hStub_EnumWindowStationProc) ConsoleWrite($sOut & @CRLF)
0015B4B8 E8 00000000 CALL 0015B4BD 0015B4BD 58 POP EAX 0015B4BE 8D90 2B000000 LEA EDX,DWORD PTR DS:[EAX+2B] 0015B4C4 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] 0015B4C8 FF32 PUSH DWORD PTR DS:[EDX] 0015B4CA 50 PUSH EAX 0015B4CB FF72 0C PUSH DWORD PTR DS:[EDX+C] 0015B4CE FF72 08 PUSH DWORD PTR DS:[EDX+8] 0015B4D1 FF72 04 PUSH DWORD PTR DS:[EDX+4] 0015B4D4 FF15 85103001 CALL DWORD PTR DS:[1301085] ; SendMessageA 0015B4DA 5A POP EDX 0015B4DB 59 POP ECX 0015B4DC 8D2494 LEA ESP,DWORD PTR SS:[ESP+EDX*4] 0015B4DF FFE1 JMP ECX 0015B4E1 90 NOP
0015B4B8 E8 00000000 CALL 0015B4BD 0015B4BD 58 POP EAX 0015B4BE 8D90 2B000000 LEA EDX,DWORD PTR DS:[EAX+2B] 0015B4C4 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] 0015B4C8 FF32 PUSH DWORD PTR DS:[EDX] 0015B4CA 50 PUSH EAX 0015B4CB FF72 0C PUSH DWORD PTR DS:[EDX+C] 0015B4CE FF72 08 PUSH DWORD PTR DS:[EDX+8] 0015B4D1 FF72 04 PUSH DWORD PTR DS:[EDX+4] 0015B4D4 FF15 85103001 CALL DWORD PTR DS:[1301085] ; SendMessageA 0015B4DA 5A POP EDX 0015B4DB 59 POP ECX 0015B4DC FFE1 JMP ECX
Posted 30 June 2007 - 07:48 PM
#cs $sStub = "" _ & "E800000000" _ ;~ $ ==> > E8 00000000 CALL 0015B4BD & "58" _ ;~ $+5 > 58 POP EAX & "8D902B000000" _ ;~ $+6 > 8D90 2B000000 LEA EDX,DWORD PTR DS:[EAX+2B] & "8D442404" _ ;~ $+C > 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] & "FF32" _ ;~ $+10 > FF32 PUSH DWORD PTR DS:[EDX] & "50" _ ;~ $+12 > 50 PUSH EAX ; lparam & "FF720C" _ ;~ $+13 > FF72 0C PUSH DWORD PTR DS:[EDX+C] ; wparam $+3c & "FF7208" _ ;~ $+16 > FF72 08 PUSH DWORD PTR DS:[EDX+8] ; msg $+38 & "FF7204" _ ;~ $+19 > FF72 04 PUSH DWORD PTR DS:[EDX+4] ; hwnd $+34 & "E8!!!!!!!!90" _ ;~ $+1C > FF15 85103001 CALL DWORD PTR DS:[1301085] ; Call Sendmessage & "5A" _ ;~ $+22 > 5A POP EDX & "59" _ ;~ $+23 > 59 POP ECX & "8D2494" _ ;~ $+24 > 8D2494 LEA ESP,DWORD PTR SS:[ESP+EDX*4] ; Adjust stack by $+30 (stdcall only) & "FFE1" _ ;~ $+27 > FFE1 JMP ECX & "90" ;~ $+29 > 90 NOP ;~ $+2A > 000000000000 ; 6 bytes nothing ;~ $+30 > 02000000 ; nParameters ;~ $+34 > D6080100 ; hwnd ;~ $+38 > 01040000 ; msg ;~ $+3C > 00000000 ; wparam ; stdcall : E800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8!!!!!!!!905A598D2494FFE190 ; cdecl : E800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8!!!!!!!!905A59909090FFE190 ; 0x1D (29.) 0x04 0x09 ; 0x56 (86.) #ce $WM_USER = 0x400 $hWnd_dummy = GUICreate("") $sOut = "" $hGlobal = DllCall("kernel32.dll","ptr","GlobalAlloc","uint",0,"dword",96) $hUser32 = DllCall("kernel32.dll","ptr","LoadLibrary","str","user32.dll") $pSendMessage = DllCall("kernel32.dll","ptr","GetProcAddress","ptr",$hUser32[0],"str","SendMessageA") $pRelSendMessage = $pSendMessage[0] - ($hGlobal[0] + 0x21) $vStub = DllStructCreate("ubyte[29];" _ ; 1 Stub Part 1 & "ptr;" _ ; 2 Address of SendMessage relative to $+21 (pTo - $+21) & "ubyte[9];" _ ; 3 Stub Part 2 & "byte[6];" _ ; 4 6 bytes nothing & "long;" _ ; 5 nParams & "hwnd;" _ ; 6 hwnd & "uint;" _ ; 7 msg & "uint;",$hGlobal[0]) ; 8 wparam DllStructSetData($vStub,1,Binary("0xE800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8")) DllStructSetData($vStub,2,$pRelSendMessage) DllStructSetData($vStub,3,Binary("0x905A598D2494FFE190")) DllStructSetData($vStub,4,Binary("0x000000000000")) DllStructSetData($vStub,5,2) DllStructSetData($vStub,6,$hWnd_dummy) DllStructSetData($vStub,7,$WM_USER+1) DllStructSetData($vStub,8,0) GUIRegisterMsg($WM_USER + 1, "_EnumWindowStationProc") Func _EnumWindowStationProc($hWnd, $msg, $wParam, $lParam) $Param = DllStructCreate("ptr;ptr", $lParam) $station = DllStructCreate("char[256]", DllStructGetData($Param, 1)) $sOut &= DllStructGetData($station, 1) & @CRLF Return 1 EndFunc ;==>_EnumWindowStationProc DllCall("user32.dll", "int", "EnumWindowStations", "ptr", $hGlobal[0], "long", 0) ConsoleWrite($sOut & @CRLF) DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $hGlobal[0])
Posted 01 July 2007 - 03:05 AM
#region - Win32EnumsStub ; ============================================================================ ; ; ============================================================================ Global $_CreateCallBackStubCounter = 0 Func _CreateCallBackStub() #cs $sStub = "" _ & "E800000000" _ ;~ $ ==> > E8 00000000 CALL 0015B4BD & "58" _ ;~ $+5 > 58 POP EAX & "8D902B000000" _ ;~ $+6 > 8D90 2B000000 LEA EDX,DWORD PTR DS:[EAX+2B] & "8D442404" _ ;~ $+C > 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] & "FF32" _ ;~ $+10 > FF32 PUSH DWORD PTR DS:[EDX] & "50" _ ;~ $+12 > 50 PUSH EAX ; lparam & "FF720C" _ ;~ $+13 > FF72 0C PUSH DWORD PTR DS:[EDX+C] ; wparam $+3c & "FF7208" _ ;~ $+16 > FF72 08 PUSH DWORD PTR DS:[EDX+8] ; msg $+38 & "FF7204" _ ;~ $+19 > FF72 04 PUSH DWORD PTR DS:[EDX+4] ; hwnd $+34 & "E8!!!!!!!!90" _ ;~ $+1C > FF15 85103001 CALL DWORD PTR DS:[1301085] ; Call Sendmessage & "5A" _ ;~ $+22 > 5A POP EDX & "59" _ ;~ $+23 > 59 POP ECX & "8D2494" _ ;~ $+24 > 8D2494 LEA ESP,DWORD PTR SS:[ESP+EDX*4] ; Adjust stack by $+30 (stdcall only) & "FFE1" _ ;~ $+27 > FFE1 JMP ECX & "90" ;~ $+29 > 90 NOP ;~ $+2A > 000000000000 ; 6 bytes nothing ;~ $+30 > 02000000 ; nParameters ;~ $+34 > D6080100 ; hwnd ;~ $+38 > 01040000 ; msg ;~ $+3C > 00000000 ; wparam ; stdcall : E800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8!!!!!!!!905A598D2494FFE190 ; cdecl : E800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8!!!!!!!!905A59909090FFE190 ; 0x1D (29.) 0x04 0x09 ; 0x56 (86.) #ce $_CreateCallBackStubCounter += 1 $WM_USER = 0x400 ; TODO: Can we check that the message $WM_USER + $ID is not used allready? $hWnd_dummy = GUICreate("") ;TODO: Check if user has a window allready and use that or make sure we switch back to current window when done here? $hGlobal = DllCall("kernel32.dll","ptr","GlobalAlloc","uint",0,"dword",96) $hUser32 = DllCall("kernel32.dll","ptr","LoadLibrary","str","user32.dll") $pSendMessage = DllCall("kernel32.dll","ptr","GetProcAddress","ptr",$hUser32[0],"str","SendMessageA") $pRelSendMessage = $pSendMessage[0] - ($hGlobal[0] + 0x21) $vStub = DllStructCreate("ubyte[29];" _ ; 1 Stub Part 1 & "ptr;" _ ; 2 Address of SendMessage relative to $+21 (pTo - $+21) & "ubyte[9];" _ ; 3 Stub Part 2 & "byte[6];" _ ; 4 6 bytes nothing & "long;" _ ; 5 nParams & "hwnd;" _ ; 6 hwnd & "uint;" _ ; 7 msg & "uint;",$hGlobal[0]) ; 8 wparam DllStructSetData($vStub,1,Binary("0xE800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8")) DllStructSetData($vStub,2,$pRelSendMessage) DllStructSetData($vStub,3,Binary("0x905A598D2494FFE190")) DllStructSetData($vStub,4,Binary("0x000000000000")) DllStructSetData($vStub,5,2) DllStructSetData($vStub,6,$hWnd_dummy) DllStructSetData($vStub,7,$WM_USER + $_CreateCallBackStubCounter) ;$WM_USER+$ID) DllStructSetData($vStub,8,0) Local $r[2] $r[0] = $WM_USER + $_CreateCallBackStubCounter $r[1] = $hGlobal[0] return $r EndFunc #endregion Global $cb1, $cb2, $cb3 ;Has to be global to be able to free data. ; Used by *proc samples so placed in the midle of the code #region - Win32EnumProcs Func _EnumWindowStationsProc($hWnd, $msg, $wParam, $lParam) Local $station, $sOut $Param = DllStructCreate("ptr;ptr", $lParam) $station = DllStructCreate("char[256]", DllStructGetData($Param, 1)) $sOut = DllStructGetData($station, 1) & @CRLF ConsoleWrite("_EnumWindowStationsProc: $sOut:=" & $sOut & @CRLF) Return 1 EndFunc ;==>_EnumWindowStationsProc Func _EnumWindowsProc($hWnd, $msg, $wParam, $lParam) Local $tStruct, $sOut $tStruct = DllStructCreate("int;int", $lParam) $sOut = WinGetTitle(HWND(DllStructGetData($tStruct, 1))) if $sOut <> "" then ; NOTE: Calling external global variable DllCall("user32.dll", "int", "EnumChildWindows", "hwnd", HWND(DllStructGetData($tStruct, 1)), "ptr", $cb3[1], "long", 0 ) ConsoleWrite("_EnumWindowsProc: $hWnd:=" & DllStructGetData($tStruct, 1) & ", $lParam:=" & DllStructGetData($tStruct, 2) & ", $sOut:=" & $sOut & @CRLF) EndIf Return 1 EndFunc Func _EnumChildWindowsProc($hWnd, $msg, $wParam, $lParam) Local $tStruct, $sOut $tStruct = DllStructCreate("int;int", $lParam) ConsoleWrite("_EnumChildWindowsProc: $hWnd:=" & HWND(DllStructGetData($tStruct, 1)) & ", $lParm:=" & HWND(DllStructGetData($tStruct, 2)) & @CRLF ) Return 1 EndFunc #endregion - Win32EnumProcs Func Main() HotKeySet("{ESC}", "Terminate") ; Create stub, Register message, call the api $cb1 = _CreateCallBackStub() GUIRegisterMsg($cb1[0], "_EnumWindowStationsProc") DllCall("user32.dll", "int", "EnumWindowStations", "ptr", $cb1[1], "long", 0) ; ; Create stub, Register message, call the api ; Used by $cb2 To enumerate childwindows $cb3 = _CreateCallBackStub() GUIRegisterMsg($cb3[0], "_EnumChildWindowsProc") ; ; Create stub, Register message, call the api $cb2 = _CreateCallBackStub() GUIRegisterMsg($cb2[0], "_EnumWindowsProc") DllCall("user32.dll", "int", "EnumWindows", "ptr", $cb2[1], "long", 0) ; The normal application loop While 1 Switch GuiGetMsg() Case -3 ExitLoop Case 0 Sleep(100) EndSwitch WEnd ;ConsoleWrite($sOut & @CRLF) Terminate() EndFunc Func Terminate() ; Make sure we clean up the callback stubs. ConsoleWrite("TERMINATE: Cleaning up" & @CRLF) If $cb1[1] <> 0 Then DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $cb1[1]) If $cb2[1] <> 0 Then DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $cb2[1]) If IsArray($cb3) Then If ($cb3[1] <> 0) Then DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $cb3[1]) EndIf ConsoleWrite("TERMINATE: Cleaning up done" & @CRLF) Exit EndFunc ; ======================================== Main()
Posted 01 July 2007 - 06:35 AM
Global $gp_DllCallBack_SendMessage = 0 Global $gh_DllCallBack_hUser32 = 0 Global $gi_DllCallBack_StubCount = 0 ;=============================================================================== ; ; Function Name: _DllCallBackAlloc ; Description: Allocates memory on global heap and creates a procedure ; which forwards a pointer to its arguments to a Window ; Parameter(s): $nParameters - number of parameters ; $hWnd - handle of receiving window ; $msg - Window Message ; $wParam, Optional - wParam to pass to the handler procedure ; $fCedecl, Optional - use cdecl calling convention (default is stdcall) ; Requirement(s): ; Return Value(s): Pointer to created stub or NULL on error ; @error Value(s): 1 = Error allocating memory from global heap ; 2 = Error Loading User32.dll ; 3 = Failed to get the address of SendMessage ; ; Author(s): ; ;=============================================================================== ; Func _DllCallBackAlloc($nParameters, $hWnd, $msg, $wParam = 0, $fcdecl = False) Local $hGlobal, $hUser32, $pSendMessage_RelAddr, $vStub $hGlobal = DllCall("kernel32.dll", "ptr", "GlobalAlloc", "uint", 0, "dword", 86) ; 86 = Size of stub If @error Then Return SetError(1, 0, 0) If $hGlobal[0] = 0 Then Return SetError(1, 0, 0) $hGlobal = $hGlobal[0] If $gp_DllCallBack_SendMessage = 0 Then $hUser32 = DllCall("kernel32.dll", "ptr", "LoadLibrary", "str", "user32.dll") If @error Then Return SetError(2, 0, 0) If $hUser32[0] = 0 Then SetError(2, 0, 0) $gh_DllCallBack_hUser32 = $hUser32[0] $pSendMessage = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", $gh_DllCallBack_hUser32, "str", "SendMessageA") If @error Then Return SetError(3, 0, 0) If $pSendMessage = 0 Then Return SetError(3, 0, 0) $gp_DllCallBack_SendMessage = $pSendMessage[0] EndIf $pSendMessage_RelAddr = $gp_DllCallBack_SendMessage - ($hGlobal + 0x21) $vStub = DllStructCreate("ubyte[29];" _ ; 1 Stub Part 1 & "ptr;" _ ; 2 Address of SendMessage relative to $+21 (pTo - $+21) & "ubyte[9];" _ ; 3 Stub Part 2 & "byte[6];" _ ; 4 6 bytes nothing & "long;" _ ; 5 nParams & "hwnd;" _ ; 6 hwnd & "uint;" _ ; 7 msg & "uint;", $hGlobal) ; 8 wparam #cs Stub Part 1 $ ==> > E8 00000000 CALL 0015B4BD $+5 > 58 POP EAX $+6 > 8D90 2B000000 LEA EDX,DWORD PTR DS:[EAX+2B] $+C > 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] $+10 > FF32 PUSH DWORD PTR DS:[EDX] $+12 > 50 PUSH EAX $+13 > FF72 0C PUSH DWORD PTR DS:[EDX+C] $+16 > FF72 08 PUSH DWORD PTR DS:[EDX+8] $+19 > FF72 04 PUSH DWORD PTR DS:[EDX+4] $+1C > E8 !!!!!!!! CALL USER32.SendMessageA ; $pSendMessage_RelAddr #ce DllStructSetData($vStub, 1, Binary("0xE800000000588D902B0000008D442404FF3250FF720CFF7208FF7204E8")) DllStructSetData($vStub, 2, $pSendMessage_RelAddr) If $fcdecl Then #cs Stub Part 2 - cdecl $+21 > 90 NOP $+22 > 5A POP EDX $+23 > 59 POP ECX $+24 > 90 NOP $+25 > 90 NOP $+26 > 90 NOP $+27 > FFE1 JMP ECX $+29 > 90 NOP #ce DllStructSetData($vStub, 3, Binary("0x905A59909090FFE190")) Else #cs Stub Part 2 - stdcall $+21 > 90 NOP $+22 > 5A POP EDX $+23 > 59 POP ECX $+24 > 8D2494 LEA ESP,DWORD PTR SS:[ESP+EDX*4] $+27 > FFE1 JMP ECX $+29 > 90 NOP #ce DllStructSetData($vStub, 3, Binary("0x905A598D2494FFE190")) EndIf ;~ $+2A > 000000000000 DllStructSetData($vStub, 4, Binary("0x000000000000")) ;~ $+30 > 00000000 DllStructSetData($vStub, 5, $nParameters) ;~ $+34 > 00000000 DllStructSetData($vStub, 6, $hWnd) ;~ $+38 > 00000000 DllStructSetData($vStub, 7, $msg) ;~ $+3C > 00000000 DllStructSetData($vStub, 8, $wParam) $gi_DllCallBack_StubCount += 1 Return $hGlobal EndFunc ;==>_DllCallBackAlloc ;=============================================================================== ; ; Function Name: _DllCallBackFree ; Description: Frees memory from global heap allocated by _DllCallBackAlloc ; Parameter(s): $hStub - Pointer to stub ; Requirement(s): ; Return Value(s): On Success: True ; On Failure: False ; @error Value(s): 1 - Error freeing memory ; 2 - Error freeing User32.dll ; Author(s): ; ;=============================================================================== ; Func _DllCallBackFree(ByRef $hStub) Local $aTmp If $hStub > 0 Then $aTmp = DllCall("kernel32.dll", "ptr", "GlobalFree", "ptr", $hStub) If @error Then Return SetError(1, 0, False) If $aTmp[0] = $hStub Then Return SetError(1, 0, False) If $aTmp[0] = 0 Then $hStub = 0 $gi_DllCallBack_StubCount -= 1 If $gi_DllCallBack_StubCount < 1 Then $gi_DllCallBack_StubCount = 0 $aTmp = DllCall("kernel32.dll", "int", "FreeLibrary", "ptr", $gh_DllCallBack_hUser32) If @error Then Return SetError(2, 0, False) If $aTmp[0] = 0 Then Return SetError(2, 0, False) $gh_DllCallBack_hUser32 = 0 EndIf Return True EndIf Return False EndIf Return True EndFunc ;==>_DllCallBackFree
Posted 01 July 2007 - 03:05 PM
Posted 01 July 2007 - 10:06 PM
Impressive, piccaso! Though it still preferable have this ability inbuilt, with this solution looks not utterly need!
Posted 04 July 2007 - 07:21 AM
Revorked my code a bit to make it work with your UDF's as a sample. Nicely done @picaso, even if it newer becomes official..i dont know if it ever gets official but here is it in udf form...
#region - Win32EnumProcs Global $cb3 ;Has to be global to be able to free data. ; Used by *proc samples so placed in the midle of the code Func _EnumWindowStationsProc($hWnd, $msg, $wParam, $lParam) Local $station, $sOut $Param = DllStructCreate("ptr;ptr", $lParam) $station = DllStructCreate("char[256]", DllStructGetData($Param, 1)) $sOut = DllStructGetData($station, 1) & @CRLF ConsoleWrite("_EnumWindowStationsProc: $sOut:=" & $sOut & @CRLF) Return 1 EndFunc ;==>_EnumWindowStationsProc Func _EnumWindowsProc($hWnd, $msg, $wParam, $lParam) Local $tStruct, $sOut $tStruct = DllStructCreate("int;int", $lParam) $sOut = WinGetTitle(HWND(DllStructGetData($tStruct, 1))) ; NOTE: Calling external global variable Assert($cb3 <> 0) Assert(HWND(DllStructGetData($tStruct, 1)) <> 0 ) DllCall("user32.dll", "int", "EnumChildWindows", "hwnd", HWND(DllStructGetData($tStruct, 1)), "ptr", $cb3, "long", 0 ) AssertNoErr() ConsoleWrite("_EnumWindowsProc: $hWnd:=" & DllStructGetData($tStruct, 1) & ", $lParam:=" & DllStructGetData($tStruct, 2) & ", $sOut:=" & $sOut & @CRLF) Return 1 EndFunc Func _EnumChildWindowsProc($hWnd, $msg, $wParam, $lParam) Local $tStruct, $sOut $tStruct = DllStructCreate("int;int", $lParam) ConsoleWrite("_EnumChildWindowsProc: $hWnd:=" & HWND(DllStructGetData($tStruct, 1)) & ", $lParm:=" & HWND(DllStructGetData($tStruct, 2)) & @CRLF ) Return 1 EndFunc #endregion - Win32EnumProcs Func Main2() HotKeySet("{ESC}", "Terminate2") Local $cb1, $cb2 Local $hWndDumy = GUICreate("") Local $WM_USER = 0x400 ; Get stub pointer, Register message, call the api $cb1 = _DllCallBackAlloc( 2, $hWndDumy, $WM_USER +1) If AssertNoErr() Then GUIRegisterMsg($WM_USER +1, "_EnumWindowStationsProc") DllCall("user32.dll", "int", "EnumWindowStations", "ptr", $cb1, "long", 0) ; ; Get stub pointer, Register message, call the api ; Used by $cb2 To enumerate childwindows $cb3 = _DllCallBackAlloc( 2,$hWndDumy, $WM_USER +3) dbg("$cb3:=" & $cb3) AssertNoErr() GUIRegisterMsg($WM_USER +3, "_EnumChildWindowsProc") AssertNoErr() ; ; Get stub pointer, Register message, call the api Local $cb2 = _DllCallBackAlloc( 2, $hWndDumy, $WM_USER +2) AssertNoErr() GUIRegisterMsg($WM_USER +2, "_EnumWindowsProc") AssertNoErr() DllCall("user32.dll", "int", "EnumWindows", "ptr", $cb2, "long", 0) AssertNoErr() ; The normal application loop Do Switch GuiGetMsg() Case -3 ExitLoop Case 0 Sleep(100) Case $WM_User + 1, $WM_User + 2, $WM_User + 3 ConsoleWrite("Unexpected??: $WM_User + [1-3]" & @CRLF) EndSwitch Until $gTerminate2 EndIf ; Clean up. NOTE: This is on the global heap so it is imperative to clean up! _DllCallBackFree($cb1) _DllCallBackFree($cb3) _DllCallBackFree($cb2) EndFunc Global $gTerminate2 = false Func Terminate2() $gTerminate2 = True EndFuncFunc Assert($bool, $line=@ScriptLineNumber, $err=@error, $ext=@extended) If NOT $bool then ConsoleWrite("(" & $line & ") := (" & $err & ")(" & $ext &") Assert failure: " & @CRLF) return $bool EndFunc Func AssertNoErr($line=@ScriptLineNumber, $err=@error, $ext=@extended) If $err <> 0 then ConsoleWrite("(" & $line & ") := (" & $err & ")(" & $ext &") AssertNoErr" & @CRLF) return ($err = 0) EndFunc Global $gTrace = True Func Trace($msg="", $line=@ScriptLineNumber, $err=@error, $ext=@extended) If $gTrace then ConsoleWrite("(" & $line & ") := (" & $err & ")(" & $ext &") TRACE: " & $msg & @CRLF) EndFunc Global $gDbg = True Func dbg($msg="", $line=@ScriptLineNumber, $err=@error, $ext=@extended) If $gDbg then ConsoleWrite("(" & $line & ") := (" & $err & ")(" & $ext &") TRACE: " & $msg & @CRLF) EndFunc ; ======================================== Main2()
Posted 04 July 2007 - 05:59 PM
Now you're probably wondering if there is any difference between the local and global functions themselves. Well, the answer is no, they are now the same. In fact, they are interchangeable. Memory allocated via a call to LocalAlloc can be reallocated with GlobalReAlloc and then locked by LocalLock. The following table lists the global and local functions now available in Win32.
... and so on.Other memory management routines such as GlobalAlloc, GlobalLock, GlobalFree, malloc, free, new, and delete, have all been changed to use VirtualAlloc and VirtualFree at a low level.
Posted 08 July 2007 - 12:49 AM
#include "DllCallBack.au3" ; Create Stub $hStub_EnumWindows = _DllCallBack ("_EnumWindowsProc", "hwnd;ptr") ; Call EnumWindows DllCall("user32.dll", "int", "EnumWindows", "ptr", $hStub_EnumWindows, "long", 0) ; Callback Procedure Func _EnumWindowsProc($hWnd, $lParam) $hWnd = HWnd($hWnd) ConsoleWrite($hWnd & " -> " & WinGetTitle($hWnd) & @CRLF) Return 1 EndFunc ;==>_EnumWindowsProc ; Free Stub _DllCallBack_Free ($hStub_EnumWindows)
Edited by piccaso, 08 August 2007 - 11:45 PM.
0 members, 0 guests, 0 anonymous users