AZJIO Posted June 5, 2013 Share Posted June 5, 2013 (edited) expandcollapse popup#include-once #include <WinAPI.au3> ; UserGUI.au3 ; ======================================= ; Title .........: UserGUI ; AutoIt Version : 3.3.8.1 ; Language ......: English + Русский ; Description ...: Operations with GUI ; ======================================= ; #CURRENT# ============================= ; _GetChildCoor ; _WinAPI_LoadKeyboardLayoutEx ; _SetCoor ; _WinAPI_GetWorkingArea ; ======================================= ; Внутренние функции ; #INTERNAL_USE_ONLY#==================== ; __Coor1 ; __Coor2 ; ======================================= ; ============================================================================================ ; Имя функции ...: _WinAPI_LoadKeyboardLayoutEx ; Описание ........: Устанавливает раскладку клавиатуры для указанного окна ; Синтаксис.......: _WinAPI_LoadKeyboardLayoutEx([$sLayoutID = 0x0409[, $hWnd = 0]]) ; Параметры: ; $sLayoutID - Код раскладки, по умолчанию 0x0409 (En) ; $hWnd - Дескриптор окна, по умолчанию 0, что означает для окна AutoIt3 ; Возвращаемое значение: Успешно - 1 ; Неудачно - 0, @error = 1 ; Автор ..........: CreatoR ; Примечания ..: ; ============================================================================================ Func _WinAPI_LoadKeyboardLayoutEx($sLayoutID = 0x0409, $hWnd = 0) Local Const $WM_INPUTLANGCHANGEREQUEST = 0x50 Local $aRet = DllCall("user32.dll", "long", "LoadKeyboardLayoutW", "wstr", Hex($sLayoutID, 8), "int", 0) If Not @error And $aRet[0] Then If $hWnd = 0 Then $hWnd = WinGetHandle(AutoItWinGetTitle()) EndIf DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", $WM_INPUTLANGCHANGEREQUEST, "int", 1, "int", $aRet[0]) Return 1 EndIf Return SetError(1) EndFunc ;==>_WinAPI_LoadKeyboardLayoutEx ; #FUNCTION# ;================================================================================= ; Function Name ...: _SetCoor ; Description ........: Corrects the coordinates to display the window in the working area of the screen ; Syntax................: _SetCoor(ByRef $aWHXY[, $iMinWidth = 0[, $iMinHeight = 0[, $iStyle = 2[, $iFixed = 0[, $iMargin = 0]]]]]) ; Parameters: ; $aWHXY - The array in the following format: ; [0] - Window width ; [1] - Window height ; [2] - X-coordinate of the window ; [3] - Y-coordinate of the window ; $iMinWidth - Minimum width ; $iMinHeight - Minimum height ; $iStyle - Style window that determines the width of the border ; 0 - No window borders, border width 0 pixel ; 1 - The window with the style $WS_BORDER, usually the width of the border 1 pixel ; 2 - The window is not resizable, usually the width of the border 3 pixels ; 3 - With the ability to resize window ($WS_OVERLAPPEDWINDOW), usually the width of the border 4 pixels ; $iFixed - Fix window coordinates when you place it right or bottom in the absence of style $WS_DLGFRAME or $WS_CAPTION ; $iMargin - Offset from the edges ; Return values ....: The correct array ; Author(s) ..........: AZJIO ; Remarks ..........: ; ============================================================================================ ; Имя функции ...: _SetCoor ; Описание ........: Корректирует координаты для отображения окна в рабочей области экрана ; Синтаксис.......: _SetCoor(ByRef $aWHXY[, $iMinWidth = 0[, $iMinHeight = 0[, $iStyle = 2[, $iFixed = 0[, $iMargin = 0]]]]]) ; Параметры: ; $aWHXY - Массив следующего формата: ; [0] - Ширина окна ; [1] - Высота окна ; [2] - X-координата окна ; [3] - Y-координата окна ; $iMinWidth - Минимальная ширина ; $iMinHeight - Минимальная высота ; $iStyle - Стиль окна, который определяет ширину границ ; 0 - Окно без границ, ширина границы 0 пиксел ; 1 - Окно со стилем $WS_BORDER, обычно ширина этой границы 1 пиксел ; 2 - Окно не изменяемое в размерах, обычно ширина этой границы 3 пиксел ; 3 - Окно изменяемое в размерах ($WS_OVERLAPPEDWINDOW), обычно ширина этой границы 4 пиксел ; $iFixed - Исправляет координаты окна при помещении его справа или снизу при отсутствии стиля $WS_CAPTION или $WS_DLGFRAME ; $iMargin - Отступ от краёв ; Возвращаемое значение: Корректный массив ; Автор ..........: AZJIO ; Примечания ..: Функция предназначена для коррекции координат прочитанных из ini-файла. ; ============================================================================================ Func _SetCoor(ByRef $aWHXY, $iMinWidth = 0, $iMinHeight = 0, $iStyle = 2, $iFixed = 0, $iMargin = 0) Local $Xtmp, $Ytmp, $aWA, $iBorderX = 0, $iBorderY = 0, $iFixedH = 0 If $iFixed Then $iFixedH += _WinAPI_GetSystemMetrics(4) ; + SMCYCAPTION $aWHXY[1] -= $iFixedH ; Вычисление одновременно приводит к числовому формату, необходимое для следующего условия If $iMinWidth And Number($aWHXY[0]) < $iMinWidth Then $aWHXY[0] = $iMinWidth ; ограничение ширины If $iMinHeight And Number($aWHXY[1]) < $iMinHeight Then $aWHXY[1] = $iMinHeight ; ограничение высоты __Coor1($aWA, $aWHXY[0], $aWHXY[1], $iBorderX, $iBorderY, $iStyle, $iMargin) $Xtmp = Number($aWHXY[2]) $Ytmp = Number($aWHXY[3]) __Coor2($Xtmp, $aWHXY[0], $aWA[4]) __Coor2($Ytmp, $aWHXY[1], $aWA[5]) $aWHXY[0] = $aWHXY[0] - $iBorderX - $iMargin $aWHXY[1] = $aWHXY[1] - $iBorderY - $iMargin + $iFixedH If $aWHXY[2] == '' Then $aWHXY[2] = (@DesktopWidth - $aWHXY[0] - $aWA[0] - $iMargin)/2 + $aWA[0] + $iMargin / 2 Else $aWHXY[2] = $Xtmp + $aWA[0] + $iMargin / 2 EndIf If $aWHXY[3] == '' Then $aWHXY[3] = (@DesktopHeight - $aWHXY[1] - $aWA[1] - $iMargin)/2 + $aWA[1] + $iMargin / 2 Else $aWHXY[3] = $Ytmp + $aWA[1] + $iMargin / 2 EndIf EndFunc ;==>_SetCoor Func __Coor1(ByRef $aWA, ByRef $iWidth, ByRef $iHeight, ByRef $iBorderX, ByRef $iBorderY, ByRef $iStyle, ByRef $iMargin) Local $iX = 7, $iY = 8 If $iStyle Then Switch $iStyle Case 1 $iX = 5 ; SMCXBORDER $iY = 6 ; SMCYBORDER Case 2 $iX = 7 ; SMCXDLGFRAME $iY = 8 ; SMCYDLGFRAME Case 3 $iX = 32 ; SMCXFRAME $iY = 33 ; SMCYFRAME EndSwitch $iBorderX = _WinAPI_GetSystemMetrics($iX) * 2 $iBorderY = _WinAPI_GetSystemMetrics($iY) * 2 + _WinAPI_GetSystemMetrics(4) ; + SMCYCAPTION Else $iBorderY = _WinAPI_GetSystemMetrics(4) ; + SMCYCAPTION EndIf $iWidth += $iBorderX $iHeight += $iBorderY $aWA = _WinAPI_GetWorkingArea() ReDim $aWA[6] $aWA[4] = $aWA[2] - $aWA[0] ; ширина Рабочей области $aWA[5] = $aWA[3] - $aWA[1] ; высота Рабочей области $iMargin *= 2 ; Вычисление наибольшего отступа If $iMargin > ($aWA[4] - $iWidth) Then $iMargin = $aWA[4] - $iWidth If $iMargin > ($aWA[5] - $iHeight) Then $iMargin = $aWA[5] - $iHeight If $iMargin < 0 Then $iMargin = 0 $iWidth += $iMargin $iHeight += $iMargin EndFunc ;==>__Coor1 Func __Coor2(ByRef $Len1, ByRef $Len2, ByRef $Len3) If $Len1 < 0 Then $Len1 = 0 If $Len2 >= $Len3 Then $Len2 = $Len3 $Len1 = 0 EndIf If $Len1 > $Len3 - $Len2 Then $Len1 = $Len3 - $Len2 EndFunc ;==>__Coor2 ; #FUNCTION# ;================================================================================= ; Function Name ...: _GetChildCoor ; Description ........: Returns the coordinates of the child window close to the parent, but in visible working area of the screen ; Syntax................: _GetChildCoor($hGui, $iWidth, $iHeight[, $iCenter = 1[, $iStyle = 2[, $iFixed = 0[, $iMargin = 0]]]]) ; Parameters: ; $hGui - The parent window handle ; $iWidth - The width of the child window ; $iHeight - The height of the child window ; $iCenter - Alignment of the child window ; |0 - The top-left corner of the ; |1 - (by default) On the center ; $iStyle - Style window that determines the width of the border ; 0 - No window borders, border width 0 pixel ; 1 - The window with the style $WS_BORDER, usually the width of the border 1 pixel ; 2 - The window is not resizable, usually the width of the border 3 pixels ; 3 - With the ability to resize window ($WS_OVERLAPPEDWINDOW), usually the width of the border 4 pixels ; $iFixed - Fix window coordinates when you place it right or bottom in the absence of style $WS_DLGFRAME or $WS_CAPTION ; $iMargin - Offset from the edges ; Return values ....: The array in the following format: ; [0] - Window width ; [1] - Window height ; [2] - X-coordinate of the window ; [3] - Y-coordinate of the window ; Author(s) ..........: AZJIO ; Remarks ..........: ; ============================================================================================ ; Имя функции ...: _GetChildCoor ; Описание ........: Возвращает координаты дочернего окна приближенные к родительскому, но в видимой рабочей области экрана ; Синтаксис.......: _GetChildCoor($hGui, $iWidth, $iHeight[, $iCenter = 1[, $iStyle = 2[, $iFixed = 0[, $iMargin = 0]]]]) ; Параметры: ; $hGui - Дескриптор родительского окна ; $iWidth - Ширина дочернего окна ; $iHeight - Высота дочернего окна ; $iCenter - Выравнивание дочернего окна ; |0 - По левому верхнему углу ; |1 - (по умолчанию) По центру ; $iStyle - Стиль окна, который определяет ширину границ ; 0 - Окно без границ, ширина границы 0 пиксел ; 1 - Окно со стилем $WS_BORDER, обычно ширина этой границы 1 пиксел ; 2 - Окно не изменяемое в размерах, обычно ширина этой границы 3 пиксел ; 3 - Окно изменяемое в размерах ($WS_OVERLAPPEDWINDOW), обычно ширина этой границы 4 пиксел ; $iFixed - Исправляет координаты окна при помещении его справа или снизу при отсутствии стиля $WS_CAPTION или $WS_DLGFRAME ; $iMargin - Отступ от краёв ; Возвращаемое значение: Массив следующего формата: ; [0] - Ширина окна ; [1] - Высота окна ; [2] - X-координата окна ; [3] - Y-координата окна ; Автор ..........: AZJIO ; Примечания ..: ; ============================================================================================ Func _GetChildCoor($hGui, $iWidth, $iHeight, $iCenter = 1, $iStyle = 2, $iFixed = 0, $iMargin = 0) Local $aRect, $aWA, $iBorderX, $iBorderY, $iFixedH = 0 If $iFixed Then $iFixedH += _WinAPI_GetSystemMetrics(4) ; + SMCYCAPTION $iHeight -= $iFixedH ; Вычисление одновременно приводит к числовому формату, необходимое для следующего условия $aRect = WinGetPos($hGui) __Coor1($aWA, $iWidth, $iHeight, $iBorderX, $iBorderY, $iStyle, $iMargin) $aRect[0] -= $aWA[0] $aRect[1] -= $aWA[1] If $iCenter Then $aRect[0] = $aRect[0] + ($aRect[2] - $iWidth) / 2 $aRect[1] = $aRect[1] + ($aRect[3] - $iHeight) / 2 EndIf __Coor2($aRect[0], $iWidth, $aWA[4]) __Coor2($aRect[1], $iHeight, $aWA[5]) $aRect[2] = $aRect[0] + $aWA[0] + $iMargin / 2 $aRect[3] = $aRect[1] + $aWA[1] + $iMargin / 2 $aRect[0] = $iWidth - $iBorderX - $iMargin $aRect[1] = $iHeight - $iBorderY - $iMargin + $iFixedH Return $aRect EndFunc ;==>_GetChildCoor ; #FUNCTION# ;================================================================================= ; Function Name ...: _WinAPI_GetWorkingArea ; Description ........: Returns the coordinates of the working area of the screen ; Syntax................: _WinAPI_GetWorkingArea() ; Return values ....: The array in the following format: ; [0] - X-coordinate of the upper left corner of the rectangle ; [1] - Y-coordinate of the upper left corner of the rectangle ; [2] - X-coordinate of the lower right corner of the rectangle ; [3] - Y-coordinate of the lower right corner of the rectangle ; Failure - Array with coordinate of whole screen, @error = 1 ; Author(s) ..........: CreatoR, AZJIO ; Remarks ..........: ; ============================================================================================ ; Имя функции ...: _WinAPI_GetWorkingArea ; Описание ........: Возвращает прямоугольник рабочей области экрана ; Синтаксис.......: _WinAPI_GetWorkingArea() ; Возвращаемое значение: Массив следующего формата: ; [0] - X-координата левой стороны прямоугольника ; [1] - Y-координата верхней стороны прямоугольника ; [2] - X-координата правой стороны прямоугольника ; [3] - Y-координата нижней стороны прямоугольника ; Неудачно - Массив с прямоугольником экрана, @error = 1 ; Автор ..........: CreatoR, AZJIO ; Примечания ..: ; ============================================================================================ Func _WinAPI_GetWorkingArea() ; Local Const $SPI_GETWORKAREA = 48 Local $stRECT = DllStructCreate("long; long; long; long") Local $aRet = DllCall("User32.dll", "int", "SystemParametersInfo", "uint", 48, "uint", 0, "ptr", DllStructGetPtr($stRECT), "uint", 0) If @error Or Not $aRet[0] Then Local $aRet[4] = [0, 0, @DesktopWidth, @DesktopHeight] Return SetError(1, 0, $aRet[4]) EndIf Local $aRet[4] = [DllStructGetData($stRECT, 1), DllStructGetData($stRECT, 2), DllStructGetData($stRECT, 3), DllStructGetData($stRECT, 4)] Return $aRet EndFunc ;==>_WinAPI_GetWorkingArea example _GetChildCoor #include <WindowsConstants.au3> #include <UserGUI.au3> $hGui = GUICreate('My program', 420, 250, 50, 50) $MsgBox = GUICtrlCreateButton("Button", 20, 20, 90, 30) GUISetState() While 1 Switch GUIGetMsg() Case $MsgBox _Child($hGui) Case -3 Exit EndSwitch WEnd Func _Child($hGui) Local $EditBut, $hGui1, $aRect, $msg, $StrBut $aRect = _GetChildCoor($hGui, 410, 240) GUISetState(@SW_DISABLE, $hGui) $hGui1 = GUICreate('Child', $aRect[0], $aRect[1], $aRect[2], $aRect[3], BitOR($WS_CAPTION, $WS_SYSMENU, $WS_POPUP), -1, $hGui) GUISetState(@SW_SHOW, $hGui1) While 1 Switch GUIGetMsg() Case -3 GUISetState(@SW_ENABLE, $hGui) GUIDelete($hGui1) ExitLoop EndSwitch WEnd EndFunc ;==>_Child example _SetCoor #include <UserGUI.au3> Local $aWHXY[4] = [10, 10, 3000, 1900] ; Specify the settings window bad _SetCoor($aWHXY, 200, 170) ; correction minimum size 200 x 170 ; The window is created visible $hGui = GUICreate('My program', $aWHXY[0], $aWHXY[1], $aWHXY[2], $aWHXY[3]) GUISetState() Do Until GUIGetMsg() = -3 example 2, _SetCoor expandcollapse popup#include <WindowsConstants.au3> #include <UserGUI.au3> Local $aWHXY[4] $hGui = GUICreate('Тест', 250, 260) GUICtrlCreateLabel('Width', 10, 10, 60, 17) GUICtrlCreateLabel('Height', 10, 30, 60, 17) GUICtrlCreateLabel('X-coord.', 10, 50, 60, 17) GUICtrlCreateLabel('Y-coord.', 10, 70, 60, 17) GUICtrlCreateLabel('Min. width', 10, 90, 60, 17) GUICtrlCreateLabel('Min. height', 10, 110, 60, 17) GUICtrlCreateLabel('Indent', 10, 130, 60, 17) $iInpW = GUICtrlCreateInput('5', 70, 10, 60, 20) $iInpH = GUICtrlCreateInput('5', 70, 30, 60, 20) $iInpX = GUICtrlCreateInput('10', 70, 50, 60, 20) $iInpY = GUICtrlCreateInput('10', 70, 70, 60, 20) $iInpMinW = GUICtrlCreateInput('200', 70, 90, 60, 20) $iInpMinH = GUICtrlCreateInput('170', 70, 110, 60, 20) $iInpMrg = GUICtrlCreateInput('0', 70, 130, 60, 20) $iButton = GUICtrlCreateButton('Test', 10, 160, 120, 30) GUISetState() While 1 Switch GUIGetMsg() Case $iButton _GuiTest($hGui) Case -3 Exit EndSwitch WEnd Func _GuiTest($hGui) $aWHXY[0] = GUICtrlRead($iInpW) $aWHXY[1] = GUICtrlRead($iInpH) $aWHXY[2] = GUICtrlRead($iInpX) $aWHXY[3] = GUICtrlRead($iInpY) $iMinW = GUICtrlRead($iInpMinW) $iMinH = GUICtrlRead($iInpMinH) $iMrg = GUICtrlRead($iInpMrg) _SetCoor($aWHXY, $iMinW, $iMinH, 2, 0, $iMrg) GUISetState(@SW_DISABLE, $hGui) $hGui1 = GUICreate('My program', $aWHXY[0], $aWHXY[1], $aWHXY[2], $aWHXY[3], BitOR($WS_CAPTION, $WS_SYSMENU, $WS_POPUP), -1, $hGui) GUISetState(@SW_SHOW, $hGui1) While 1 Switch GUIGetMsg() Case -3 GUISetState(@SW_ENABLE, $hGui) GUIDelete($hGui1) ExitLoop EndSwitch WEnd EndFunc ;==>_GuiTest Attention! When you save the coordinates it is necessary to take away coordinates of the left top corner of working area from coordinates of a window. Full example, _SetCoor. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <UserGUI.au3> Global $WHXY[5], $ini = @ScriptDir & '\SaveXY.ini' $WHXY[0] = Number(IniRead($ini, 'Set', 'W', '330')) $WHXY[1] = Number(IniRead($ini, 'Set', 'H', '220')) $WHXY[2] = IniRead($ini, 'Set', 'X', '') $WHXY[3] = IniRead($ini, 'Set', 'Y', '') $WHXY[4] = Number(IniRead($ini, 'Set', 'WinMax', '')) _SetCoor($WHXY, 230, 300, 3, 0) ; MsgBox(0, '-', $WHXY[0] & @LF & $WHXY[1] & @LF & $WHXY[2] & @LF & $WHXY[3] & @LF & $WHXY[4]) ; $hGui = GUICreate('My Program', $WHXY[0], $WHXY[1], $WHXY[2], $WHXY[3], $WS_SYSMENU ) ; $iStyle = 0, $iFixed = 1 ; $hGui = GUICreate('My Program', $WHXY[0], $WHXY[1], $WHXY[2], $WHXY[3], BitOR( $WS_BORDER, $WS_POPUP)) ; $iStyle = 1, $iFixed = 1 ; $hGui = GUICreate('My Program', $WHXY[0], $WHXY[1], $WHXY[2], $WHXY[3], BitOR($WS_SYSMENU, $WS_SIZEBOX) ) ; $iStyle = 2, $iFixed = 1 ; $hGui = GUICreate('My Program', $WHXY[0], $WHXY[1], $WHXY[2], $WHXY[3], BitOR( $WS_BORDER, $WS_POPUP, $WS_SIZEBOX)) ; $iStyle = 3, $iFixed = 1 ; $hGui = GUICreate('My Program', $WHXY[0], $WHXY[1], $WHXY[2], $WHXY[3], BitOR($WS_CAPTION, $WS_SYSMENU, $WS_POPUP)) ; $iStyle = 2, $iFixed = 0 $hGui = GUICreate('My Program', $WHXY[0], $WHXY[1], $WHXY[2], $WHXY[3], $WS_OVERLAPPEDWINDOW) ; $iStyle = 3, $iFixed = 0 GUISetBkColor(0x000066) $iExit = GUICtrlCreateButton('Exit', 5, 5, 86, 28) $Label = GUICtrlCreateLabel('move', 10, 45, $WHXY[0] - 20, $WHXY[1] - 50, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, 0xfdffae) GUISetState() If $WHXY[4] Then GUISetState(@SW_MAXIMIZE, $hGui) OnAutoItExitRegister("_Exit_Save_Ini") GUIRegisterMsg(0x0216, "WM_MOVING") While 1 Switch GUIGetMsg() Case $GUI_EVENT_MAXIMIZE $WHXY[4] = 1 Case $GUI_EVENT_RESTORE $WHXY[4] = 0 Case $GUI_EVENT_RESIZED _Resized() Case $GUI_EVENT_CLOSE, $iExit Exit EndSwitch WEnd Func _Exit_Save_Ini() $iState = WinGetState($hGui) $aWA = _WinAPI_GetWorkingArea() ; If Not (BitAnd($iState, 16) Or BitAnd($iState, 32)) Then _Resized() IniWrite($ini, 'Set', 'WinMax', $WHXY[4]) IniWrite($ini, 'Set', 'W', $WHXY[0]) IniWrite($ini, 'Set', 'H', $WHXY[1]) IniWrite($ini, 'Set', 'X', $WHXY[2] - $aWA[0]) IniWrite($ini, 'Set', 'Y', $WHXY[3] - $aWA[1]) EndFunc ;==>_Exit_Save_Ini Func _Resized() ; fires once when the window is resized, but not when "maximized", "Restore" $GuiPos = WinGetPos($hGui) $ClientSz = WinGetClientSize($hGui) $WHXY[0] = $ClientSz[0] $WHXY[1] = $ClientSz[1] $WHXY[2] = $GuiPos[0] $WHXY[3] = $GuiPos[1] EndFunc ;==>_Resized Func WM_MOVING($hWnd, $Msg, $wParam, $lParam) ; get the coordinates of the window. This is when you close a window from the taskbar Local $sRect = DllStructCreate("Int[4]", $lParam) $WHXY[2] = DllStructGetData($sRect, 1, 1) $WHXY[3] = DllStructGetData($sRect, 1, 2) Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOVING Edited July 3, 2013 by AZJIO My other projects or all Link to comment Share on other sites More sharing options...
xpresso Posted June 9, 2013 Share Posted June 9, 2013 What's "GetChildCoor" mean? It will get the "Windows now focus" position? Link to comment Share on other sites More sharing options...
AZJIO Posted June 9, 2013 Author Share Posted June 9, 2013 (edited) xpresso, >Child window is always in the center or in the visible region ----------------------------- I made changes to _SetCoor. Parameter $iMargin now the last. ----------------------------- Updated. $iStyle = 2, $iFixed = 0 Edited June 22, 2013 by AZJIO My other projects or all Link to comment Share on other sites More sharing options...
AZJIO Posted June 22, 2013 Author Share Posted June 22, 2013 On WinXP works fine. On Win7, 8 if the window outside of the screen, then recovered near the edge a little bit of crossing the border. I took into account the width of the borders for different styles. Why Win7, 8 there is a problem? I would like to do perfectly. I would not want to resort to the function WinMove. There are at whom ideas? My other projects or all 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