frank10 Posted June 9, 2014 Share Posted June 9, 2014 I want to call a func when user moves the wheel over the title of a window. I found scripts to intercept windows' messages but only in a GUI, with GUIRegisterMsg. Link to comment Share on other sites More sharing options...
Solution mikell Posted June 9, 2014 Solution Share Posted June 9, 2014 (edited) expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> HotKeySet('{ESC}', '_Close') If Not IsDeclared('WM_MOUSEWHEEL') Then Global Const $WM_MOUSEWHEEL = 0x020A Global Const $tagMSLLHOOKSTRUCT = $tagPOINT & ';uint mouseData;uint flags;uint time;ulong_ptr dwExtraInfo;' Global $hFunc, $pFunc, $hHook, $hMod $hFunc = DllCallbackRegister('_MouseProc', 'lresult', 'int;int;int') $pFunc = DllCallbackGetPtr($hFunc) $hMod = _WinAPI_GetModuleHandle(0) $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, $hMod) Global $aList = _WinAPI_EnumWindowsTop() While 1 Sleep(20) WEnd Func _MouseProc($iCode, $iwParam, $ilParam) Static $x0, $y0 If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) Local $tMSLL = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam) If $iwParam = $WM_MOUSEWHEEL Then $x = DllStructGetData($tMSLL, 'X') $y = DllStructGetData($tMSLL, 'Y') If $x <> $x0 And $y <> $y0 Then Local $point = DllStructCreate($tagPOINT) DllStructSetData($point,"X", $x) DllStructSetData($point,"Y", $y) For $i = 1 To $aList[0][0] Local $title = WinGetTitle($aList[$i][0]) If $title <> "" And $title <> "Program Manager" Then Local $rect = _WinAPI_GetWindowRect($aList[$i][0]) DllStructSetData($rect, "Bottom", DllStructGetData($rect, "Top")+35) If _WinAPI_PtInRect($rect, $point) Then $x0 = $x $y0 = $y Msgbox(4096, "", $title) EndIf EndIf Next EndIf EndIf Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc Func _Close() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hHook) Exit EndFunc Edited June 9, 2014 by mikell Link to comment Share on other sites More sharing options...
frank10 Posted June 10, 2014 Author Share Posted June 10, 2014 (edited) Thank you alot for your script! It works very well! Apart these: 1) If you have more than one windows' title overlapping, it cycles through all of them, instead I want only the handle to the one over which the mouse is (not necessarily the active one). 2) it detects all titles, even those hidden by the active window: instead it must act only if there is the mouse over the title and the window is visible, not hidden. 3) I need also to prevent the default scrolling behaviour after detecting it over the window's title. In javascript there is the preventDefault(e); Anyway, thank you again for this, it's a very good starting point. Edited June 10, 2014 by frank10 Link to comment Share on other sites More sharing options...
frank10 Posted June 11, 2014 Author Share Posted June 11, 2014 (edited) I made some changes, so now it works quite perfect: 1) it detects overlapping titles and select only the top window. 2) it stops default scrolling in window EDIT: no... 3) it gets also windows not active 4) it doesn't select hidden window 5) it detects if wheel up or down and make different actions I used the func _WinAPI_WindowFromPoint, _WinAPI_GetParent. I had to get the delta value to see if wheel up or down, but I don't know how, so I made an hack looking at the first number of DllStructGetData($tMSLL, 3): if 7 wheel UP. Now the code makes window minimize when wheel down on title and maximize when wheel up: expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> OnAutoItExitRegister("_Close") Global Const $tagMSLLHOOKSTRUCT = $tagPOINT & ';uint mouseData;uint flags;uint time;ulong_ptr dwExtraInfo;' Global $hFunc, $pFunc, $hHook, $hMod $hFunc = DllCallbackRegister('_MouseProc', 'lresult', 'int;int;int') $pFunc = DllCallbackGetPtr($hFunc) $hMod = _WinAPI_GetModuleHandle(0) $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, $hMod) While 1 Sleep(20) WEnd Func _MouseProc($iCode, $iwParam, $ilParam) Static $x0, $y0 If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) Local $tMSLL = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam) If $iwParam = $WM_MOUSEWHEEL Then $x = DllStructGetData($tMSLL, 'X') $y = DllStructGetData($tMSLL, 'Y') If $x <> $x0 And $y <> $y0 Then Local $point = DllStructCreate($tagPOINT) DllStructSetData($point,"X", $x) DllStructSetData($point,"Y", $y) local $hWnd = _WinAPI_WindowFromPoint($point) ; Retrieve the window handle. ; check it's a handle from the root window if _WinAPI_GetParent($hWnd) = 0 Then ; check it's not a wheel outside title: Local $rect = _WinAPI_GetWindowRect($hWnd) DllStructSetData($rect, "Bottom", DllStructGetData($rect, "Top")+35) If _WinAPI_PtInRect($rect, $point) Then if StringLeft(DllStructGetData($tMSLL, 3),1) = 7 Then ; hack to get if wheel UP... (it starts with 4 for down) WinSetState($hWnd,"",@SW_MAXIMIZE ) Else WinSetState($hWnd,"",@SW_MINIMIZE ) EndIf Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndIf EndIf EndIf EndIf Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc Func _Close() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hHook) Exit EndFunc Edited June 13, 2014 by frank10 mLipok 1 Link to comment Share on other sites More sharing options...
mikell Posted June 11, 2014 Share Posted June 11, 2014 To check the delta you can also do it like this $iDelta = BitShift(DllStructGetData($tMSLL, 'mouseData'), 16) If $iDelta > 0 Then ; wheel up If $iDelta < 0 Then ; wheel down Link to comment Share on other sites More sharing options...
frank10 Posted June 12, 2014 Author Share Posted June 12, 2014 Thank you, the correct way, of course. Link to comment Share on other sites More sharing options...
frank10 Posted June 13, 2014 Author Share Posted June 13, 2014 1) I still have the problem of blocking the default behaviour of wheel... how do I block it? 2) You used the WinApi_PointInrect to detect if I'm over the title. I'm trying to make another func: I get a rect from drawing the mouse. Is there a way to check how many windows are inside a rectangle (drawn by mouse)? i.e. if a rectangle intersects other win rectangles? Link to comment Share on other sites More sharing options...
frank10 Posted June 13, 2014 Author Share Posted June 13, 2014 For the 2) it could be done in a loop with this: http://msdn.microsoft.com/en-us/library/system.windows.rect.intersectswith%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1 bool doesIntersect = myRectangle.IntersectsWith(myRectangle2); In autoit ? In alternative I've just done a check of Points in Rect, like this: Func _checkRect( $pos_old, $pos_new ) Local $rectMouse = DllStructCreate( "int x1; int y1; int x2; int y2") DllStructSetData($rectMouse, "x1", $pos_old[0] ) DllStructSetData($rectMouse, "y1", $pos_old[1] ) DllStructSetData($rectMouse, "x2", $pos_new[0] ) DllStructSetData($rectMouse, "y2", $pos_new[1] ) Local $point1 = DllStructCreate($tagPOINT) Local $point2 = DllStructCreate($tagPOINT) Local $point3 = DllStructCreate($tagPOINT) Local $point4 = DllStructCreate($tagPOINT) local $winNum = 0 Global $aList = _WinAPI_EnumWindowsTop() For $i = 1 To $aList[0][0] Local $rect = _WinAPI_GetWindowRect($aList[$i][0]) DllStructSetData($point1,"X", DllStructGetData($rect, "left")) DllStructSetData($point1,"Y", DllStructGetData($rect, "top") ) DllStructSetData($point2,"X", DllStructGetData($rect, "right")) DllStructSetData($point2,"Y", DllStructGetData($rect, "top") ) DllStructSetData($point3,"X", DllStructGetData($rect, "right")) DllStructSetData($point3,"Y", DllStructGetData($rect, "bottom") ) DllStructSetData($point4,"X", DllStructGetData($rect, "left")) DllStructSetData($point4,"Y", DllStructGetData($rect, "bottom") ) If _WinAPI_PtInRect($rectMouse, $point1 ) or _WinAPI_PtInRect($rectMouse, $point2 ) or _WinAPI_PtInRect($rectMouse, $point3 ) or _WinAPI_PtInRect($rectMouse, $point4 ) Then ConsoleWrite("Win In Mouserect:" & WinGetTitle($aList[$i][0]) & @CRLF) $winNum += 1 EndIf Next ConsoleWrite("WinNumFound: " &$winNum & @CRLF) EndFunc but it's not perfect: it detects only the 4 corners, not all the sides. Link to comment Share on other sites More sharing options...
KaFu Posted June 13, 2014 Share Posted June 13, 2014 For 1) Return 1 ; If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
frank10 Posted June 13, 2014 Author Share Posted June 13, 2014 Ok, that works for the minimize func, but when maximize it scrolls again: expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> OnAutoItExitRegister("_Close") Global Const $tagMSLLHOOKSTRUCT = $tagPOINT & ';uint mouseData;uint flags;uint time;ulong_ptr dwExtraInfo;' Global $hFunc, $pFunc, $hHook, $hMod $hFunc = DllCallbackRegister('_MouseProc', 'lresult', 'int;int;int') $pFunc = DllCallbackGetPtr($hFunc) $hMod = _WinAPI_GetModuleHandle(0) $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, $hMod) While 1 Sleep(20) WEnd Func _MouseProc($iCode, $iwParam, $ilParam) Static $x0, $y0 If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) Local $tMSLL = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam) If $iwParam = $WM_MOUSEWHEEL Then $x = DllStructGetData($tMSLL, 'X') $y = DllStructGetData($tMSLL, 'Y') If $x <> $x0 And $y <> $y0 Then Local $point = DllStructCreate($tagPOINT) DllStructSetData($point,"X", $x) DllStructSetData($point,"Y", $y) local $hWnd = _WinAPI_WindowFromPoint($point) ; Retrieve the window handle. ; check it's a handle from the root window if _WinAPI_GetParent($hWnd) = 0 Then ; check it's not a wheel outside title: Local $rect = _WinAPI_GetWindowRect($hWnd) DllStructSetData($rect, "Bottom", DllStructGetData($rect, "Top")+35) If _WinAPI_PtInRect($rect, $point) Then if StringLeft(DllStructGetData($tMSLL, 3),1) = 7 Then ; hack to get if wheel UP... (it starts with 4 for down) WinSetState($hWnd,"",@SW_MAXIMIZE ) return 1 Else WinSetState($hWnd,"",@SW_MINIMIZE ) return 1 EndIf EndIf EndIf EndIf EndIf Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc Func _Close() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hHook) Exit EndFunc i.e. in the scite win when you have a script tab active in focus, position the mouse over title and scroll up: the windows maximize correctly, but sometimes the text in tab has scrolled up. With wheel down instead it minimizes and doesn't scroll. Link to comment Share on other sites More sharing options...
frank10 Posted June 15, 2014 Author Share Posted June 15, 2014 I made >this thread with the script discussed here. This thread is solved. Link to comment Share on other sites More sharing options...
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