Jump to content

Recommended Posts

Posted

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.

 

#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

Posted
#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. :) 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting  image.gif.922e3a93535f431de08b31ee669cc446.gif
autoit_scripter_blue_userbar.png

Posted (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 by Dan_555

Some of my script sourcecode  ,  Gdi+ Canvas

Posted (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 by MattyD
wording

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

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...