# DllCall, SetTimer, WM_TIMER and GUIRegisterMsg

## Recommended Posts

Hi

I'm having two problems with the code below:

1.) According to the online MSDN documentation of SetTimer the parameter "uElapse" is of type UINT. However, when I pass that value to DllCall as an "uint" parameter DllCall will fail. If I pass it as "int" it works. Is this a problem with the MSDN documentation or with DllCall?

2.) According to the same documentation, if a WM_TIMER message is received, the wParam parameter/value should contain the value of nIDEvent (in my example: 50). However, if you run the code you can see, that is does not contain that value! Is this again a problem of the online documentation or something with GuiRegisterMsg??

Tested with 3.2.0.1!

#include <GUIConstants.au3>

Global Const $WM_TIMER = 0x0113 Global$nID = 50
Global $msg,$retval

Global $gui = GUICreate("test") GUISetState () GUIRegisterMsg($WM_TIMER,"_TimerFunc")

$retval = DLLCall("user32.dll","int_ptr","SetTimer","hwnd",$gui,"int_ptr",$nID,"int",2000,"ptr",0) ; <<== THIS WORKS ;$retval = DLLCall("user32.dll","int_ptr","SetTimer","hwnd",$gui,"int_ptr",$nID,"uint",2000,"ptr",0); <<== here ERROR
if @error then _error("DllCall failed")

do
until GUIGetMsg() = $GUI_EVENT_CLOSE$retval = DLLCall("user32.dll","int","KillTimer","hwnd",$gui,"int_ptr",$nID)

Func _TimerFunc($hWndGUI,$MsgID, $WParam,$LParam)
MsgBox(0,"TIMER","MsgID : " & $MsgID & " wParam: " &$WParam & " lParam: " & $LParam) EndFunc Func _error($msg)
MsgBox(0,"ERROR", $msg) exit EndFunc Thanks Kurt Edited by /dev/null __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites I think this is what you want: $retval = DllCall("User32.dll", "int", "SetTimer", "hwnd", $GUI, "int",$nID, "int", 2000, "int", 0)

Auto3Lib: A library of over 1200 functions for AutoIt

##### Share on other sites

I think this is what you want:

$retval = DllCall("User32.dll", "int", "SetTimer", "hwnd",$GUI, "int", $nID, "int", 2000, "int", 0) PaulIA, interesting... Using "int" instead of "int_ptr" for nIDEvent, solves half of the problem (although MSDN suggests to use UINT_PTR). Now, wParam contains the value of Event ID (nIDEvent). However, the "problem" with DllCall is still there if I use "uint" instead of "int" for uElapse. Any idea if this is a documentation error in MSDN or a problem with DllCall? Looking at the defintion in the file winuser.h (Dev-C++) show the same definition for SetTimer WINUSERAPI UINT WINAPI SetTimer(HWND,UINT,UINT,TIMERPROC); So, I'm still not sure if this is a problem with DllCall or something else. EDIT: Dumb error. There is simply NO "uint" for DllCall. I mistook the parameters of DllStructCreate and DllCall... Thanks Kurt Edited by /dev/null __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites If you use the beta uint should work. I did a coherency matching between dllcall param and dllstructcreate ones. #### Share this post ##### Link to post ##### Share on other sites If you use the beta uint should work. I did a coherency matching between dllcall param and dllstructcreate ones. AutoIT "crashes" when I use "uint" with 3.2.1.13. >Running:(3.2.1.13):C:\Program Files\AutoIt3\beta\autoit3.exe "C:\temp\autoit\37318.au3" !>AutoIT3.exe ended.rc:-1073741819 >Exit code: -1073741819 Time: 3.945 Test Code: #include <GUIConstants.au3> MsgBox(0,"",@AutoItVersion) Global Const$WM_TIMER = 0x0113
Global $nID = 50 Global$msg, $retval Global$gui = GUICreate("test")
GUISetState ()
GUIRegisterMsg($WM_TIMER,"_TimerFunc")$retval = DLLCall("user32.dll","uint","SetTimer","hwnd",$gui,"uint",$nID,"uint",2000,"ptr",0); <<== here ERROR
if @error then _error("DllCall failed")

do
until GUIGetMsg() = $GUI_EVENT_CLOSE$retval = DLLCall("user32.dll","int","KillTimer","hwnd",$gui,"int_ptr",$nID)

Func _TimerFunc($hWndGUI,$MsgID, $WParam,$LParam)
MsgBox(0,"TIMER","MsgID : " & $MsgID & " wParam: " &$WParam & " lParam: " & $LParam) EndFunc Func _error($msg)
MsgBox(0,"ERROR", $msg) exit EndFunc [autoit] Cheers Kurt __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites After replyng I did a test a found the same thing. But I don't know how to correct. the Problem come from a bad conversion of a uint to an int64. I need Valik assistance case tuint: *pvTemp = CastToInt64<unsigned __int32>(lparg->uintVal); #### Share this post ##### Link to post ##### Share on other sites After replyng I did a test a found the same thing. But I don't know how to correct. the Problem come from a bad conversion of a uint to an int64. I need Valik assistance case tuint: *pvTemp = CastToInt64<unsigned __int32>(lparg->uintVal); why is it cast to int64?? In DllStructCreate there is "uint" AND "uint64". Maybe just replace CastToInt64 with CastToInt ?? Cheers Kurt __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc ); How come you are not using the "int_ptr" or does exist "uint_ptr" ? Lar. using a "*_ptr" is wrong here anyway. Seems to be a bug in the MSDN documentation. If you pass in a pointer, later in the "callback" function for WM_TIMER, wParam will contain the address of the variable and not its value, so you cannot check if the timer that was triggered is the correct one. That was my first "error" ... Cheers Kurt __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites Well, it can't be cast to 32-bit because AutoIt doesn't store things unsigned internally. That means an unsigned number will be turned int a signed number. However, by storing it in a 64-bit number, quite obvious the sign bit isn't touched. As to why it crashes, that's a very good question. #### Share this post ##### Link to post ##### Share on other sites why is it cast to int64?? In DllStructCreate there is "uint" AND "uint64". Maybe just replace CastToInt64 with CastToInt ?? Cheers Kurt It is the process of returning the value, so it is intended to not loose precision if the leftmost bit is one as 0x80000000. not to confuse with negative number so a conversion to 64bit integer is done. #### Share this post ##### Link to post ##### Share on other sites It is the process of returning the value, so it is intended to not loose precision if the leftmost bit is one as 0x80000000. not to confuse with negative number so a conversion to 64bit integer is done. O.K. I see... __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites By the way, regarding UINT_PTR, DO NOT MAKE ASSUMPTIONS. UINT_PTR is NOT unsigned int *. It's either a 64-bit or 32-bit unsigned int. The <TYPE>_PTR types are used when you need to be 64-bit compatible since the correctly sized type will be chosen by the compiler depending on whether the application is being built as 32-bit or 64-bit. #### Share this post ##### Link to post ##### Share on other sites As to why it crashes, that's a very good question. O.K., do I have to open a bug report, or are looking anyway?? Cheers Kurt __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites No, it's fixed already. #### Share this post ##### Link to post ##### Share on other sites No, it's fixed already. Nice! What has been the problem? Thanks Kurt Edited by /dev/null __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf * #### Share this post ##### Link to post ##### Share on other sites CastToInt64() expects an address but JP was giving it a variable, not the address of the variable. JP, I've fixed the uint/ushort code in DllCall(). I also added a comment near CastToInt64() mentioning that the parameter must be an address. If you know of any other places where you used a variable instead of the address of that variable with a call to CastToInt64(), please change accordingly. #### Share this post ##### Link to post ##### Share on other sites CastToInt64() expects an address but JP was giving it a variable, not the address of the variable. JP, I've fixed the uint/ushort code in DllCall(). I also added a comment near CastToInt64() mentioning that the parameter must be an address. If you know of any other places where you used a variable instead of the address of that variable with a call to CastToInt64(), please change accordingly. Thanks Valik, I have to admit that the casting in not my cup of tea ... #### Share this post ##### Link to post ##### Share on other sites By the way, regarding UINT_PTR, DO NOT MAKE ASSUMPTIONS. UINT_PTR is NOT unsigned int *. It's either a 64-bit or 32-bit unsigned int. The <TYPE>_PTR types are used when you need to be 64-bit compatible since the correctly sized type will be chosen by the compiler depending on whether the application is being built as 32-bit or 64-bit. Is it intended if you as for a Int_ptr, on return the variable contain the int value. Same for short_ptr. That a difference with DLLStruct at least in thr way to pass and retrieve value. #### Share this post ##### Link to post ##### Share on other sites I don't understand what your concern is. Example? #### Share this post ##### Link to post ##### Share on other sites I don't understand what your concern is. Example? Func _ProcessGetExitCode($h_Process)
Local $aRet = DllCall("kernel32.dll", "int", "GetExitCodeProcess", "hwnd",$h_Process, "long_ptr", 0)
If @error Then Return SetError(@error, @extended, 0x7FFFFFFF)
SetExtended($aRet[0]) Return$aRet[2]
EndFunc   ;==>_ProcessGetExitCode

I retrieve this code which look a little bit strange for returning in a "long_ptr" which is not defined. Very different from dllStruct... which really need to a real pointer pointing to a long.

I understand my confusion. I was thinking the variable was set. It is better that the return is done in the array return by DllCall.

Forget about my silly remark. I didn't understand that the value pointed by an internal allocated pointer was returned.

perhaps the doc is not too clear on this special mechanism.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...