Dan_555 Posted October 11 Posted October 11 There seems to be some sort of comparison bug between the 32bit and 64bit versions of AutoIt. The problem ocurred when i tried to detect the mouse wheel movement in a compiled 64bit version of a script. (Mouse wheel down was not recognized) I have managed to identify the problem. If the 0xff880000 is used, the 64bit comparison does not match it. but if i add 1 or 2 zeros in front of the 0xFF88 (as in 0x0ff88...) it starts working. Try this program. In 32 bit it works ok, but in 64 bit only one case is accepted. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsNotifsConstants.au3> Global $MW, $MWO, $nc=0xFF880000 , $n=0 GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") $a=GUICreate($nc & " / " & $n,250,100) $b1=GUICtrlCreateButton (" ",0,0,100,30) $b2=GUICtrlCreateButton ("Switch",0,60,100,20) GUISetState() While 1 $nmsg=GUIGetMsg() if $nmsg=-3 then Exit if $nmsg=$b2 Then $n=Mod($n+1,2) if $n=1 then $nc=0x00FF880000 if $n=0 then $nc=0xFF880000 WinSetTitle ($a,"",$nc & " / " & $n) EndIf if $mw<>$mwo then $mwo=$mw GUICtrlSetData ($b1,$mw) EndIf Sleep (10) WEnd Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) GUICtrlSetData ($b2,$wParam) Switch $wParam Case $NC ;mouse wheel up $MW = $MW + 1 Return 0 Case 0x00780000 $MW = $MW - 1 Return 0 Case Else EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_Mousewheel Some of my script sourcecode , Gdi+ Canvas
argumentum Posted October 11 Posted October 11 expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.18.0 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> Global $nmsg, $MW = 0, $MWO = 0, $n = 0 GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel") Global $a = GUICreate("Wheel Test", 250, 100) Global $b1 = GUICtrlCreateButton(" ", 0, 0, 100, 30) Global $b2 = GUICtrlCreateButton("Switch", 0, 60, 100, 20) GUISetState() While 1 $nmsg = GUIGetMsg() If $nmsg = -3 Then Exit If $nmsg = $b2 Then $n = Mod($n + 1, 2) WinSetTitle($a, "", "Mode: " & $n) EndIf If $MW <> $MWO Then $MWO = $MW GUICtrlSetData($b1, $MW) EndIf Sleep(10) WEnd Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam ; Extract the high-order word of wParam (Wheel Delta) Local $iDelta = _WinAPI_HiWord($wParam) ; Convert unsigned 16-bit word to a signed integer (-120 or 120) If $iDelta > 32767 Then $iDelta -= 65536 GUICtrlSetData($b2, $iDelta) If $iDelta > 0 Then ; Wheel Up $MW = $MW + 1 Return 0 ElseIf $iDelta < 0 Then ; Wheel Down $MW = $MW - 1 Return 0 EndIf Return $GUI_RUNDEFMSG EndFunc The script fails when running as x64 (64-bit) due to how Windows and AutoIt handle message parameters (WPARAM) across different architectures. The Root Cause(s): Pointer & Integer Size (WPARAM width): In x86 (32-bit), AutoIt runs as a 32-bit process where WPARAM is exactly 32 bits. Hardcoded hex values like 0xFF880000 match the 32-bit integer representation of the message parameters precisely. In x64 (64-bit), AutoIt runs as a 64-bit process, and WPARAM is a 64-bit pointer-sized integer (UINT_PTR). When Windows passes the 32-bit WM_MOUSEWHEEL message to a 64-bit application, the upper bits get sign-extended or padded (e.g., resulting in 0xFFFFFFFFFF880000). Because the script compares $wParam directly against a 32-bit literal (0xFF880000), the comparison fails in x64 because the 64-bit high-order bits don't match. Fragility of Hardcoded Bitfield Hex Literals: Relying on raw hex constants like 0xFF880000 (which packs a 16-bit wheel delta in the high-order word and modifier keys in the low-order word) is architecture-dependent and breaks whenever register sizes change. The Solution: To make the script work seamlessly on both x86 and x64, the script should extract the high-order word (the wheel delta) using _WinAPI_HiWord() ( from <WinAPI.au3> ) rather than performing direct hex comparisons on $wParam. Gianni and robertocm 2 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
MattyD Posted October 12 Posted October 12 Also a hot tip - you can make use of wordtoshort to deal with signed 16bit values Func _Mousewheel($hWnd, $iMsg, $wParam, $lParam) Local $iDelta = _WinAPI_WordToShort(_WinAPI_HiWord($wParam)) ConsoleWrite($iDelta & @CRLF) Return $GUI_RUNDEFMSG EndFunc argumentum, Gianni and Dan_555 3
Dan_555 Posted October 12 Author Posted October 12 (edited) Thanks for the answers. btw: 10 hours ago, argumentum said: resulting in 0xFFFFFFFFFF880000). The return value is 0x00000000FF880000). (at least on my machine) So to summarize the problem/solution in short words: The 32 bit hexadecimal value can become negative decimal number while the 64bit does not and this messes up the comparison. Edited October 12 by Dan_555 Some of my script sourcecode , Gdi+ Canvas
MattyD Posted October 12 Posted October 12 (edited) yeah more or less... AutoIt treats hex notation with 4 bytes or fewer (e.g. 0xAABBCCDD) as signed 32-bit integers in both x86 and x64. Take $NC = 0xFF880000. $NC's datatype is an int32 - The first bit is set, so its always going to be treated as a negative number. (-7864320) in x64, wparam comes in as: 0x00000000FF880000. To do a comparison, $NC must first be converted to 64bit . -7864320 in 64bit is 0xFFFFFFFFFF880000. So $wParam <> $NC in this case. Edited October 12 by MattyD wording Dan_555 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now