iCode Posted November 23, 2013 Posted November 23, 2013 (edited) This function prevents a window from being moved beyond any screen edge, sort of like docking, but there is no 'snap' function. Optionally, you can also prevent another window from overlapping the primary one. This works regardless of the Windows task-bar position/size or auto-hide status. expandcollapse popup#include-once ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinDock ; Version .......; 1.3.1 ; Description ...: Dock a window at any screen edge and, optionally, prevent another window from overlapping the first ; Syntax ........: _WinDock($hWnd1, [$hWnd2]) ; Parameters ....: $hWnd1 - Handle to primary window ; $hWnd2 - Handle to secondary window (optional) ; Return values .: 1 = No error ; set @error = 1, @extended = -1 : $hWnd1 is not a window handle ; set @error = 1, @extended = -2 : unable to get taskbar position ; set @error = 1, @extended = -3 : unable to get window position of $hWnd1 ; set @error = 1, @extended = -4 : unable to get window position of (optional) $hWnd2 ; Author ........: $iCode ; Modified ......: ; Remarks .......: Works regardless of taskbar position, size and auto-hide status ; Related .......: WinMove ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WinDock($hWnd1, $hWnd2 = 0) ; handle of primary window, [handle of secondary window] If Not IsHWnd($hWnd1) Then Return SetError(1, -1) Local $aWinPos2 = 0, $iMoveWin2 = 0, $overlap, _ $x1 = Default, $y1 = Default, _ $x2 = Default, $y2 = Default, $w2 = Default, _ $scrW = @DesktopWidth, $scrH = @DesktopHeight, _ $scrLeft = 0, $scrTop = 0 Local $aTskBarPos = WinGetPos("[CLASS:Shell_TrayWnd]") ; X, Y, W, H If @error Then Return SetError(1, -2) Local $aWinPos1 = WinGetPos($hWnd1) If @error Then Return SetError(1, -3) If IsHWnd($hWnd2) Then $aWinPos2 = WinGetPos($hWnd2) If @error Then Return SetError(1, -4) EndIf $iMoveWin2 = 1 EndIf ; set screen coordinates, less windows taskbar If $aTskBarPos[0] <= 0 And $aTskBarPos[3] = $scrH Then ; taskbar on left If $aTskBarPos[0] > 0 Then ; taskbar is visible $scrLeft = $aTskBarPos[2] $scrW -= $aTskBarPos[2] EndIf ElseIf $aTskBarPos[1] <= 0 And $aTskBarPos[2] = $scrW Then ; taskbar on top If $aTskBarPos[1] > 0 Then ; taskbar is visible $scrTop = $aTskBarPos[3] $scrH -= $aTskBarPos[3] EndIf ElseIf $aTskBarPos[1] <= 0 And $aTskBarPos[3] = $scrH Then ; taskbar on right $scrW = $aTskBarPos[0] Else ; taskbar on bottom $scrH = $aTskBarPos[1] EndIf ; positioning on x axis If $aWinPos1[0] <= $scrLeft Then $x1 = $scrLeft If $iMoveWin2 = 1 Then If $aWinPos1[2] + $aWinPos2[2] > $scrW Then ; we need to resize the width of $hWnd2 $x2 = $scrLeft + $aWinPos1[2] $w2 = $scrW - $aWinPos1[2] ElseIf $aWinPos2[0] < $scrLeft + $aWinPos1[2] Then $x2 = $scrLeft + $aWinPos1[2] EndIf EndIf ElseIf $aWinPos1[0] + $aWinPos1[2] >= $scrW Then $x1 = ($scrW + $scrLeft) - $aWinPos1[2] If $iMoveWin2 = 1 Then If $aWinPos1[2] + $aWinPos2[2] > $scrW Then ; we need to resize the width of $hWnd2 $x2 = $scrLeft $w2 = $scrW - $aWinPos1[2] ElseIf $aWinPos2[0] + $aWinPos2[2] > $scrW - $aWinPos1[2] Then $overlap = ($aWinPos2[0] + $aWinPos2[2]) - ($scrW - $aWinPos1[2]) $x2 = $scrLeft + ($aWinPos2[0] - $overlap) EndIf EndIf EndIf ; positioning on y axis If $aWinPos1[1] < $scrTop Then $y1 = $scrTop ElseIf $aWinPos1[1] + $aWinPos1[3] > $scrH + $scrTop Then $y1 = $aWinPos1[1] - (($aWinPos1[1] + $aWinPos1[3]) - ($scrH + $scrTop)) EndIf WinMove($hWnd1, "", $x1, $y1) If $iMoveWin2 = 1 Then WinMove($hWnd2, "", $x2, $y2, $w2) Return 1 EndFunc #cs ### EXAMPLE ### #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 400, 400, @DesktopWidth / 2, @DesktopHeight / 2, -1, BitOR($WS_EX_TOPMOST,$WS_EX_WINDOWEDGE)) $Label1 = GUICtrlCreateLabel("", 0, 0, 400, 200, $SS_CENTER, $GUI_WS_EX_PARENTDRAG) GUICtrlSetData(-1, "DRAG ME BEYOND A VERTICAL SCREEN EDGE " & @LF & "AND MOVE OTHER WINDOW") GUICtrlSetCursor (-1, 9) $Label2 = GUICtrlCreateLabel("", 0, 200, 400, 200, $SS_CENTER, $GUI_WS_EX_PARENTDRAG) GUICtrlSetData(-1, "DRAG ME BEYOND A VERTICAL SCREEN EDGE " & @LF & "AND DO NOT MOVE OTHER WINDOW") GUICtrlSetCursor (-1, 9) GUISetState(@SW_SHOW) $Form2 = GUICreate("Form2", @DesktopWidth - 150, @DesktopHeight - 150, 75, 50, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_TABSTOP)) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Label1 _WinDock($Form1, $Form2) Case $Label2 _WinDock($Form1) EndSwitch WEnd #ce last updated: 24-Mar-2014 v1.3.1 * forgot '#include-once' v1.3 * minor optimizations and some variables renamed * fixed an oversight where docking of primary window would not occur if the secondary window did not exist * dumped Return values and set @extended instead * now sets @error to 1 if something fails v1.2 * re-wrote most of the function, adding ability to compensate for task-bar position and auto-hide status Edited March 24, 2014 by iCode FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences) CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)
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