wolfbartels Posted May 10, 2010 Posted May 10, 2010 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.
PsaltyDS Posted May 10, 2010 Posted May 10, 2010 You have to catch WM_MOUSEWHEEL notification messages. Haven't needed to do it myself, so I don't have a demo of it. You might search for that message to get more help though. 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
Moderators Melba23 Posted May 10, 2010 Moderators Posted May 10, 2010 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_MOUSEHWHEELYou will need to change the _SendMessage lines as they currently send the scroll commands to a scrollbar! M23 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: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
wolfbartels Posted May 13, 2010 Author Posted May 13, 2010 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! 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
PsaltyDS Posted May 13, 2010 Posted May 13, 2010 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. 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
wolfbartels Posted May 13, 2010 Author Posted May 13, 2010 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.
wolfbartels Posted May 17, 2010 Author Posted May 17, 2010 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_MOUSEWHEELThere 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?
PsaltyDS Posted May 17, 2010 Posted May 17, 2010 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. 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
wolfbartels Posted May 17, 2010 Author Posted May 17, 2010 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?
PsaltyDS Posted May 18, 2010 Posted May 18, 2010 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. 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
Synapsee Posted April 21, 2016 Posted April 21, 2016 (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. expandcollapse popup;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 April 21, 2016 by Synapsee
Synapsee Posted April 21, 2016 Posted April 21, 2016 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 : expandcollapse popup#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
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