Jump to content

Recommended Posts

Posted

Hi,

is it possible in an .au3 to detect the movements of the mouse wheel and translate these to corresponding {UP}s and {DOWN}s for use in Send() ???

I use a script to extend control of an old fashioned 16-bit program. I want to implement text scrolling with the mousewheel, as actually scrolling can be done only by using {UP} and {DOWN} keys.

Thanks for any idea.

  • Moderators
Posted

wolfbartels,

Try these:

GUIRegisterMsg($WM_MOUSEWHEEL, "_WM_MOUSEWHEEL")
GUIRegisterMsg($WM_MOUSEHWHEEL, '_WM_MOUSEHWHEEL')

Func _WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = $SB_LINEDOWN
    If BitShift($wParam, 16) > 0 Then $iDirn = $SB_LINEUP
    _SendMessage($hWnd, $WM_VSCROLL, $iDirn)
    
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_MOUSEWHEEL

Func _WM_MOUSEHWHEEL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = $SB_LINERIGHT
    If BitShift($wParam, 16) > 0 Then $iDirn = $SB_LINELEFT
    _SendMessage($hWnd, $WM_HSCROLL, $iDirn)
    
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_MOUSEHWHEEL

You will need to change the _SendMessage lines as they currently send the scroll commands to a scrollbar! :idea:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

Posted

  On 5/10/2010 at 1:47 PM, 'Melba23 said:

wolfbartels,

Try these:

GUIRegisterMsg($WM_MOUSEWHEEL, "_WM_MOUSEWHEEL")
GUIRegisterMsg($WM_MOUSEHWHEEL, '_WM_MOUSEHWHEEL')

Func _WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = $SB_LINEDOWN
    If BitShift($wParam, 16) > 0 Then $iDirn = $SB_LINEUP
    _SendMessage($hWnd, $WM_VSCROLL, $iDirn)
    
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_MOUSEWHEEL

Func _WM_MOUSEHWHEEL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = $SB_LINERIGHT
    If BitShift($wParam, 16) > 0 Then $iDirn = $SB_LINELEFT
    _SendMessage($hWnd, $WM_HSCROLL, $iDirn)
    
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_MOUSEHWHEEL

You will need to change the _SendMessage lines as they currently send the scroll commands to a scrollbar! :idea:

M23

Hi Melba23,

That's looks interesting, although I do not understand how this technic works.

Could you please show me some simple code where this is used, so that I can try to understand it?

Thanks anyway, Wolf

Posted

A demo:

#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Global $iX = 0, $iY = 0, $hGUI, $idLabel
$hGUI = GUICreate("Test", 300, 300)
$idLabel = GUICtrlCreateLabel("$iX = 0; $iY = 0", 20, 20, 260, 20)
GUISetState()

GUIRegisterMsg($WM_MOUSEWHEEL, "_WM_MOUSEWHEEL")
GUIRegisterMsg($WM_MOUSEHWHEEL, '_WM_MOUSEHWHEEL')

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = -1
    If BitShift($wParam, 16) > 0 Then $iDirn *= -1
    $iY += $iDirn
    ControlSetText($hGUI, "", $idLabel, "$iX = " & $iX & "; $iY = " & $iY)
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_MOUSEWHEEL

Func _WM_MOUSEHWHEEL($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = -1
    If BitShift($wParam, 16) > 0 Then $iDirn *= -1
    $iX += $iDirn
    ControlSetText($hGUI, "", $idLabel, "$iX = " & $iX & "; $iY = " & $iY)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MOUSEHWHEEL

My mouse doesn't have the horizontal scroll on the mousewheel, so I couldn't test that part.

:idea:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

Thanks PsaltyDS and Melba23,

it works fine, both ways, moving the mousewheel vertically or horizontally. Excellent.

Now I'll try to translate these movements in Send ( arrow keys ).

I want to teach mouse scrolling to an old Win95 parametric CAD program that knows only arrow keys.

Posted

I have a CAD application (Win 3.1) which I improved using an AutoIt script to add some buttons. This works fine.

Now I want the content in the CAD window to scroll using the mousewheel.

I added the following code (thanks to Melba23 and PsaltyDS):

GUIRegisterMsg($WM_MOUSEWHEEL, "_WM_MOUSEWHEEL")

.........
Func _WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam
    $hWnd = $hCAD ;                    <--  to force scrolling in CAD window!
    Local $iDirn = $SB_LINEDOWN
    If BitShift($wParam, 16) > 0 Then $iDirn = $SB_LINEUP
    _SendMessage($hWnd, $WM_VSCROLL, $iDirn)
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_MOUSEWHEEL

There is only one problem, the content of the application window ($hCAD) scrolles only if the CAD window is not active, as soon as the CAD window is active the mousewheel is dead. How this can be fixed?

Posted

  On 5/17/2010 at 5:48 AM, 'wolfbartels said:

CAD window is not active, as soon as the CAD window is active the mousewheel is dead. How this can be fixed?

Put a ConsoleWrite(), MsgBox(), or something in that event function to see if it is being called then failing to scroll, or if it's not called at all while the CAD app is active.

:idea:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

Hi PsaltyDS,

I followed your advice, the event function Func _WM_MOUSEWHEEL in NOT called when the CAD window is active. After clicking anywhere on a GUI created by AutoIt the CAD window becomes not active and the scrolling in this non active window works fine. I suppose the problem has to do with GUIRegisterMsg. How can I force this registration for the CAD window, using AutoIt?

Is there a way to detect the MsgID? Is it possible that the old fashioned CAD program supresses the event message?

Posted

Ouch. I should have seen that coming. We registered mouse messages coming to AutoIt. You want to get ("hook") mouse messages going to an outside app. Similar to this example, using hook.dll.

:idea:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
  • 5 years later...
Posted (edited)

Hi, i think the PsaltyDS mousewheel sample (thx for that) can be improve with mousewheel delta use.
I have add some tips too on code.

 

;Original Code
;PsaltyDS
;Post 5
;https://www.autoitscript.com/forum/topic/114220-translate-mwheel-to-up-and-down/

;My change use delta
;See : https://msdn.microsoft.com/en-us/library/windows/desktop/ms645617%28v=vs.85%29.aspx

#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Global $iX = 0, $iY = 0, $hGUI, $idLabel
Global $iX2 = 0, $iY2 = 0
$hGUI = GUICreate("Test", 300, 300)
$idLabel = GUICtrlCreateLabel("Without delta : $iX = 0; $iY = 0", 20, 20, 260, 20)
$idLabel2 = GUICtrlCreateLabel("With delta      : $iX2 = 0; $iY2 = 0", 20, 40, 260, 20);<=====with delta use
GUISetState()

GUIRegisterMsg($WM_MOUSEWHEEL, "_WM_MOUSEWHEEL")
GUIRegisterMsg($WM_MOUSEHWHEEL, '_WM_MOUSEHWHEEL')

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)

    ;Original Code without delta
    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = -1
    If BitShift($wParam, 16) > 0 Then $iDirn *= -1
    $iY += $iDirn
    ControlSetText($hGUI, "", $idLabel, "Without delta : $iX = " & $iX & "; $iY = " & $iY)

    ;My change with delta
    #forceref $hWnd, $iMsg, $lParam
    $iY2 += BitShift($wParam, 16) / 120
    ControlSetText($hGUI, "", $idLabel2, "With delta      : $iX2 = " & $iX2 & "; $iY2 = " & $iY2)

    ;ConsoleWrite
    ConsoleWrite(BitShift($wParam, 16) & " " & $iY & " " & $iY2 & @CRLF)
    ;BitShift($wParam, 16) can be 120 or on fast move wheel 240/360/480... (neg value for scroll down)

    ;the "code execution time" here need to be fast for dont miss mousewheel event
    ;sleep(1000);<=====u can comment/uncommand that for test

    ;if your code need more time (ms) u can do something like this :
    AdlibRegister("_WM_MOUSEWHEEL_Long", 300)

    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MOUSEWHEEL

Func _WM_MOUSEWHEEL_Long()

    AdlibUnRegister("_WM_MOUSEWHEEL_Long")

    ;the "code execution time" here can be more long
    Msgbox(0,"Pause",$iY2);<=====u can comment/uncommand that for test

EndFunc   ;==>_WM_MOUSEWHEEL

Func _WM_MOUSEHWHEEL($hWnd, $iMsg, $wParam, $lParam)

    ;Original Code
    #forceref $hWnd, $iMsg, $lParam
    Local $iDirn = -1
    If BitShift($wParam, 16) > 0 Then $iDirn *= -1
    $iX += $iDirn
    ControlSetText($hGUI, "", $idLabel, "Without delta : $iX = " & $iX & "; $iY = " & $iY)

    ;My change with delta
    #forceref $hWnd, $iMsg, $lParam
    $iX2 += BitShift($wParam, 16) / 120
    ControlSetText($hGUI, "", $idLabel2, "With delta     : $iX2 = " & $iX2 & "; $iY2 = " & $iY2)

    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MOUSEHWHEEL

Tell me if i'm wrong

Edited by Synapsee
Posted

The JRowe's post you quote don't use wheel delta. So i have transfrom it for use wheel delta and now both script run together return same result.
so my wheel delta use seems ok, one method have confirmed another. thx u mpower for remember me this hook dll method.

Jrowe code with wheel delta use :

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"

Global $currentEvent[2]

Global $iLBUTTONDOWN = 0
Global $iRBUTTONDOWN = 0
Global $iMBUTTONDOWN = 0
Global $LRClickStatus = 0
Global $RLClickStatus = 0
Global $LRDrag = 0
Global $RLDrag = 0
Global $LMDrag = 0
Global $RMDrag = 0
Global $doubleClickTime = 400

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 633, 447, 192, 124)
$Label1 = GUICtrlCreateLabel("Label1", 200, 8, 228, 49)
GUISetState(@SW_SHOW)

;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)

#EndRegion ### END Koda GUI section ###

$i = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            OnAutoItExit()
            Exit

    EndSwitch
WEnd

Func _Mouse_Proc($nCode, $wParam, $lParam)

    Local $info, $mouseData, $time, $timeDiff
    If $nCode < 0 Then
        $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
                "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $ret[0]
    EndIf

    $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam)
    $mouseData = DllStructGetData($info, 3)

    Select
        Case $wParam = $WM_MOUSEWHEEL
            If _WinAPI_HiWord($mouseData) > 0 Then
                ;Up
                ConsoleWrite("up " & $mouseData/7864320 & @crlf);<===== Delta count return
                $i = $i + $mouseData/7864320;<========================= delta use
                ;$i = $i + 1<========================================== no delta use
                ConsoleWrite($i & @CRLF);<============================= $i console return
                $currentEvent[0] = "WheelUp"
                $currentEvent[1] = $time
            Else
                ;Down
                $count = $mouseData - 4287102976
                if $count <> 0 Then
                    $count = - (($count / 7864320)-1)
                Else
                    $count = 1
                Endif
                ConsoleWrite("down " & $count & @crlf);<=============== Delta count return
                $i = $i - $count;<===================================== delta use
                ;$i = $i - 1<========================================== no delta use
                ConsoleWrite($i & @CRLF);<============================= $i console return
                $currentEvent[0] = "WheelDown"
                $currentEvent[1] = $time
            EndIf

    EndSelect
    GUICtrlSetData($Label1, $currentEvent[0] & @CRLF & $currentEvent[1])

    $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
            "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $ret[0]
EndFunc   ;==>_Mouse_Proc

Func OnAutoItExit()
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
    $hM_Hook[0] = 0
    DllCallbackFree($hKey_Proc)
    $hKey_Proc = 0
EndFunc   ;==>OnAutoItExit

 

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...