frank10 Posted June 15, 2014 Share Posted June 15, 2014 (edited) I made this script to add some functionality to windows' control (inspiring by tools like Preme), like: 1) minimize windows with wheel down on title 2) maximize windows with wheel up on title 3) changing master volume with wheel on taskbar 4) scrolling also windows not selected, just use the wheel over the window you want to scroll 5) arranging windows' position in one of the eight possible positions on screen: up-down-left-right, topLeft-topRight-bottomleft-bottomright with pressing middle button/wheel and moving it in the wanted direction 6) automatically arrange multiple windows on screen pressinng middle button/wheel outside windows' title and drawing a rectangle over the corners of the windows you want to arrange. 2-4 windows can be arranged to left-right, left+topright-bottomright, topLeft-topRight-bottomleft-bottomright. Known problems-limitations, using numbers from above description: 2) when maximize, sometimes the window scroll also the content, even if I made a "return 1" to block standard wheel behaviour (the minimize doesn't have this problem) 4) the scrolling of the window isn't exactly what I wanted, because I made it activating the window to scroll it's content (also you see a little "flash" on the window's borders), while I wanted to do that without activating the window, leaving it unactivated. I made it working using: _WinAPI_SetForegroundWindow ( $hWnd ) ;WinActivate($hWnd) ; doesn't work! I don't know how to send a mouse wheel event to a window not active. 6) I made a check func to see if one corner of a window is inside the rectangle drawed with mouse. This way if you draw the rectangle on the borders of the window it doesn't get selected. A better approach would consider also the entire borders, such as this Windows func to check the intersections of 2 rectangles struct: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); How to do in autoit? other improvements: a) it could be nice to draw the rectangle on the screen: I tried to do that with the func _WinAPI_DrawRect, but it's a lot SLOW, so if there's a faster method... Here's the script: (you need also this au3 to control master volume:) download the _AudioEndpointVolume.au3 Thanks to mikell for the base WinApi script. EDIT: I changed the detection of mouse over Taskbar WindowControlWheel_v1.1.au3: expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> #include "C:\Program Files (x86)\AutoIt3\Beta\Include\_AudioEndpointVolume.au3" #include "C:\Program Files (x86)\AutoIt3\Beta\Include\WinAPIex\WinAPIEx.au3" #include <Misc.au3> #include <Array.au3> ; thanks to mikell for the base WinApi script 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) global $firstTime = '' Global $posNew = 0 Global $posOld = 0 global $hWnd While 1 Sleep(10) 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_MOUSEMOVE Then ToolTip("") if $firstTime <> '' and TimerDiff($firstTime) > 400 Then $posNew = MouseGetPos() ; if over title: if _WinOverTit($posOld[0], $posOld[1]) Then _moveWin($posOld,$posNew) $firstTime = '' EndIf EndIf EndIf If $iwParam = $WM_MBUTTONDOWN and $firstTime = '' Then $firstTime = TimerInit() $posOld = MouseGetPos() EndIf If $iwParam = $WM_MBUTTONUP and $firstTime <> '' Then ;~ _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN) $posNew = MouseGetPos() _checkRect( $posOld,$posNew) $firstTime = '' EndIf If $iwParam = $WM_MOUSEWHEEL Then $x = DllStructGetData($tMSLL, 'X') $y = DllStructGetData($tMSLL, 'Y') Local $point = DllStructCreate($tagPOINT) DllStructSetData($point,"X", $x) DllStructSetData($point,"Y", $y) $hWnd = _WinAPI_WindowFromPoint($point) ; Retrieve the window handle. _WinAPI_SetForegroundWindow ( $hWnd ) ; works ok BUT makes a "flash" every time it activates the win I want also to scroll WITHOUT activate the win... ; if over title: if _WinOverTit($x, $y) Then local $iDelta = BitShift(DllStructGetData($tMSLL, 'mouseData'), 16) If $iDelta > 0 Then ; wheel up if $y >= @DesktopHeight -100 Then _VolumeStepUp() ToolTip(@CR & " VolumeUP: " & Round(_GetMasterVolumeLevelScalar(),0) & @CRLF ,@DesktopWidth/2-50,@DesktopHeight-100 ) Else WinSetState($hWnd,"", @SW_MAXIMIZE ) WinActivate($hWnd) EndIf Else ; wheel down if $y >= @DesktopHeight -100 Then _VolumeStepDown() ToolTip(@cr &" VolumeDOWN: " & Round(_GetMasterVolumeLevelScalar(),0) & @CRLF ,@DesktopWidth/2-50,@DesktopHeight-100 ) Else WinSetState($hWnd,"", @SW_MINIMIZE ) EndIf EndIf Return 1 EndIf EndIf Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc Func _Close() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hHook) Exit EndFunc Func _WinOverTit($x,$y) local $overTit = 0 Local $point = DllStructCreate($tagPOINT) DllStructSetData($point,"X", $x) DllStructSetData($point,"Y", $y) $hWnd = _WinAPI_WindowFromPoint($point) ; Retrieve the window handle. ; check it's a handle from the root window OR if you are over the taskbar to control the volume: if _WinAPI_GetParent($hWnd) = 0 or $y >= @DesktopHeight -40 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 $overTit = 1 EndIf return $overTit EndFunc Func _moveWin($pos_old, $pos_new) local $direction = "" If $pos_new[0] = $pos_old[0] and $pos_new[1] = $pos_old[1] Then Return $a = _GetAnglePO($pos_new[0] - $pos_old[0], $pos_new[1] - $pos_old[1]) * 57.2957795130823 Select Case $a >= 337.5 or $a < 22.5 $direction = "6" WinMove($hWnd,"",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight) Case $a >= 22.5 and $a < 67.5 $direction = "3" WinMove($hWnd,"",@DesktopWidth/2,@DesktopHeight/2,@DesktopWidth/2,@DesktopHeight/2) Case $a >= 67.5 and $a < 112.5 $direction = "2" WinMove($hWnd,"",0,@DesktopHeight/2,@DesktopWidth,@DesktopHeight/2) Case $a >= 112.5 and $a < 157.5 $direction = "1" WinMove($hWnd,"",0,@DesktopHeight/2,@DesktopWidth/2,@DesktopHeight/2) Case $a >= 157.5 and $a < 202.5 $direction = "4" WinMove($hWnd,"",0,0,@DesktopWidth/2,@DesktopHeight) Case $a >= 202.5 and $a < 247.5 $direction = "7" WinMove($hWnd,"",0,0,@DesktopWidth/2,@DesktopHeight/2) Case $a >= 247.5 and $a < 292.5 $direction = "8" WinMove($hWnd,"",0,0,@DesktopWidth,@DesktopHeight/2) Case $a >= 292.5 and $a < 337.5 $direction = "9" WinMove($hWnd,"",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight/2) EndSelect EndFunc Func _GetAnglePO( $x, $y ) ;by blindwig Local Const $pi = 3.14159265358979 Select Case $x > 0 If $y >= 0 Then Return ATan($y / $x) Else Return ATan($y / $x) + 2 * $pi EndIf Case $x = 0 If $y = 0 Then Return 0 ElseIf $y > 0 Then Return $pi / 2 Else Return 3 * $pi / 2 EndIf Case $x < 0 Return ATan($y / $x) + $pi EndSelect EndFunc 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 $aWin[1] 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 _ArrayAdd($aWin, $aList[$i][0]) EndIf Next Select Case UBound($aWin) = 3 WinMove($aWin[1],"",0,0,@DesktopWidth/2,@DesktopHeight) WinMove($aWin[2],"",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight) Case UBound($aWin) = 4 WinMove($aWin[1],"",0,0,@DesktopWidth/2,@DesktopHeight) WinMove($aWin[2],"",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight/2) WinMove($aWin[3],"",@DesktopWidth/2,@DesktopHeight/2,@DesktopWidth/2,@DesktopHeight/2) Case UBound($aWin) = 5 WinMove($aWin[1],"",0,0,@DesktopWidth/2,@DesktopHeight/2) WinMove($aWin[2],"",0,@DesktopHeight/2,@DesktopWidth/2,@DesktopHeight/2) WinMove($aWin[3],"",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight/2) WinMove($aWin[4],"",@DesktopWidth/2,@DesktopHeight/2,@DesktopWidth/2,@DesktopHeight/2) EndSelect EndFunc Func _WinAPI_DrawRect($start_x, $start_y, $iWidth, $iHeight, $iColor) ConsoleWrite($start_x &","& $start_y&"--"& $iWidth &","& $iHeight & @CRLF) Local $tRect = DllStructCreate($tagRECT) DllStructSetData($tRect, 1, $start_x) DllStructSetData($tRect, 2, $start_y) DllStructSetData($tRect, 3, $iWidth) DllStructSetData($tRect, 4, $iHeight) Local $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop) $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $iColor) $o_Orig = _WinAPI_SelectObject($hDC, $hPen) _WinAPI_DrawLine($hDC, $posOld[0] , $posOld[1], $posNew[0] , $posOld[1]) ; horizontal top _WinAPI_DrawLine($hDC, $posNew[0] , $posOld[1], $posNew[0] , $posNew[1]) ; vert right _WinAPI_DrawLine($hDC, $posNew[0] , $posNew[1], $posOld[0] , $posNew[1]) ; hor bottom _WinAPI_DrawLine($hDC, $posOld[0] , $posNew[1], $posOld[0] , $posOld[1]) ; vert left _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN) _WinAPI_SelectObject($hDC, $o_Orig) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) EndFunc ;==>_WinAPI_DrawRect Edited June 15, 2014 by frank10 ravkr 1 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