Что нового

Размеры и положение окон в реестре

musicstashall

Знающий
Сообщения
322
Репутация
7
Необходимо получить текущие координаты положения папок проводника на рабочем столе. Это координаты, в которых система располагает все вновь открытые папки проводника на раб столе. Параметры хранятся в реестре: HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell
Набросал такую функу, проверьте на своих мониторах, правильно ли определяет. А быть может существуют стандартные средства AutoIt?

Код:
#include <WinAPIGdi.au3>
#include <Array.au3>

Global $_HKEY_LOCAL_MACHINE, $_HKEY_CLASSES_ROOT, $_HKEY_CURRENT_USER, $_HKEY_USERS
DetectInfrastructure()
Local $tRect = _GetRectAllFolders()
Local $Pos = _WinAPI_GetPosFromRect($tRect)
_ArrayDisplay($Pos)

Func _GetRectAllFolders()
    Local $string = 'WinPos' & @DesktopWidth & 'x' & @DesktopHeight
    Local $Key = $_HKEY_CURRENT_USER & '\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell'
    Local $data = _GetEnumValue($Key, True)
    Local $aiResult = _ArrayFindAll($data, $string, 0, 0, 0, 1)
    If UBound($aiResult) < 4 Then Return SetError(1, 0, 0)
    Local $aData = _ArrayExtract($data, $aiResult[UBound($aiResult) -4], $aiResult[UBound($aiResult) -1], 0, 1) ; берем снизу четыре последние
    If UBound($aData) < 4 Then Return SetError(1, 0, 0)
    Local $tRect = DllStructCreate($tagRECT)
    For $i = 0 To 3
        DllStructSetData($tRect, $i + 1, $aData[$i][1])
    Next
    Return SetError(0, 0, $tRect)
EndFunc

Func _GetEnumValue($Key, $param = False, $Flag = True) ; возвращает список всех параметров в ключе, флаг — кол-во в нулевой ячейке, $Param — возвращает двух-мерный массив со значениями
    Local $data[0], $i = 1, $read
    If $param Then Dim $data[0][2]
    If $Flag Then _ArrayAdd($data, 0)
    If $param Then _ArrayAdd($data, '||' & RegRead($Key, ''), 0, '||') 
    While 1
        $read = RegEnumVal($Key, $i)
        If @error Then ExitLoop
        If Not $param Then _ArrayAdd($data, $read)
        If $param Then _ArrayAdd($data, $read & '||' & RegRead($Key, $read), 0, '||') 
        $i += 1
    Wend
    If $Flag And Not $param Then $data[0] = UBound($data) -1
    If $Flag And $param Then $data[0][0] = UBound($data) -1 
    Return $data
EndFunc

Func DetectInfrastructure()
    If @OSTYPE = "WIN32_WINDOWS" Then
    Else
        If Not @AutoItX64 And @OSArch = "X86" Or (@OSArch = "X64" And @AutoItX64) Then
            $_HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE"
            $_HKEY_CLASSES_ROOT = 'HKEY_CLASSES_ROOT'
            $_HKEY_CURRENT_USER = 'HKEY_CURRENT_USER'
            $_HKEY_USERS = 'HKEY_USERS'
        Else
            $_HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE64"
            $_HKEY_CLASSES_ROOT = "HKEY_CLASSES_ROOT64"
            $_HKEY_CURRENT_USER = "HKEY_CURRENT_USER64"
            $_HKEY_USERS = 'HKEY_USERS64'
        EndIf
    EndIf
    Return @OSArch
EndFunc   ;==>DetectInfrastructure


Не понятно, из чего состоит значение параметра WinPos1920x1080x96(2).top. Ширина, высота, а что такое 96 и (2)? Есть значения так же и (1) в конце.
Переключил мониторы, меньший поставил основным, теперь параметры пишутся в WinPos1680x1050x96(2).top. Как определить, какие параметры надо читать?
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
немного не понял, что должно отобразиться в массиве?
у меня так
482
207
1139
641
монитор fullhd. система win x64
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
немного не понял, что должно отобразиться в массиве?
у меня так
482
207
1139
641
монитор fullhd. система win x64
Должны отобразиться координаты, в которых открываются все папки проводника. Нужно проверить, соответствуют ли данные координаты вашим. Хотя бы примерно прикинуть. Открыли Мой компьютер, к примеру, переместили окно в верхний левый угол и запустили скрипт, он должен показать Left = 0, Top = 0 и тд.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
все время одни и те же результаты. запускал в обеих разрядностях от имени админа
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
все время одни и те же результаты. запускал в обеих разрядностях от имени админа
Я так понял, что у тебя используется только один монитор? Или больше двух? У себя я тоже такое заметил. Попробуйте теперь исправленный скрипт:

Код:
Func _GetRectAllFolders()
    Local $aData = _WinAPI_EnumDisplayMonitors(), $enum = 1
    If IsArray($aData) Then $enum = $aData[0][0]
    Local $string = 'WinPos' & @DesktopWidth & 'x' & @DesktopHeight & 'x' & 96 & '(' & $enum & ')'
    Local $data = _GetEnumValue($AllFolders, True)
    Local $aiResult = _ArrayFindAll($data, $string, 0, 0, 0, 1)
    If UBound($aiResult) < 4 Then Return SetError(1, 0, 0)
    Local $aData = _ArrayExtract($data, $aiResult[UBound($aiResult) -4], $aiResult[UBound($aiResult) -1], 0, 1) ; берем снизу четыре последние
    If UBound($aData) < 4 Then Return SetError(1, 0, 0)
    Local $tRect = DllStructCreate($tagRECT)
    For $i = 0 To 3
        DllStructSetData($tRect, $i + 1, $aData[$i][1])
        ;ConsoleWrite($data[$aiResult[UBound($aiResult) -4 + $i]][0] & ' = ' & $data[$aiResult[UBound($aiResult) -4 + $i]][1] & @CR)
    Next
    Return SetError(0, 0, $tRect)
EndFunc

Func _SetRectAllFolders($hWnd)
    Local $Point = _WinAPI_GetWindowRect($hWnd)
    Local $aData = _WinAPI_EnumDisplayMonitors(), $enum = 1
    If IsArray($aData) Then $enum = $aData[0][0]
    Local $string = 'WinPos' & @DesktopWidth & 'x' & @DesktopHeight & 'x' & 96 & '(' & $enum & ')'
    Local $data = _GetEnumValue($AllFolders, True)
    Local $aiResult = _ArrayFindAll($data, $string, 0, 0, 0, 1)
    If UBound($aiResult) < 4 Then Return SetError(1, 0, 0)
    For $i = 0 To 3
        RegWrite($AllFolders, $data[$aiResult[UBound($aiResult) -4 + $i]][0], 'REG_DWORD', DllStructGetData($Point, $i + 1)    )
        ;ConsoleWrite($data[$aiResult[UBound($aiResult) -4 + $i]][0] & ' = ' & $Val & @CR)
    Next
EndFunc


Цифра в скобках означает количество мониторов. До сих пор не понимаю пока, что такое 96 в строках WinPos1920x1080x96(2).top

Чтобы создать окно в координатах проводника, примените следующий скрипт:

Код:
Func _GuiCreate()
    $GuiSize = _WinAPI_GetPosFromRect(_GetRectAllFolders())
    If @error Then Dim $GuiSize[4] = [-1, -1, 1022, 570]
    
    $GUI_CAPTION = _WinAPI_GetSystemMetrics($SM_CYCAPTION)
    $GUI_SIZEFRAME = _WinAPI_GetSystemMetrics($SM_CXSIZEFRAME)
    
    $GuiSize[2] -= ($GUI_SIZEFRAME * 2)
    $GuiSize[3] -= ($GUI_CAPTION + $GUI_SIZEFRAME * 2)
    $iGUI = GUICreate('#1', $GuiSize[2], $GuiSize[3], $GuiSize[0], $GuiSize[1])
EndFunc
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
проверить не могу
$AllFolders - неизвестная переменная
в итоге, в новом варианте нет чтения реестра?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
вот теперь работает и регистрирует перемещение окна. я про функцию
_GetRectAllFolders()
 
Верх