1 (изменено: Androgen, 2006-07-29 06:34:41)

Тема: AutoHotkey: скрипты для сохранения и восстановления разделов реестра

Как известно, многие проги хранят свои настройки в реестре. Да что там проги, сама винда и та ...
Не менее известно, что винда периодически начинает сбоить и глючить. Иногда настолько, что без переустановки не обойтись. А переустановка винды означает потерю всех ваших так кропотливо или даже любовно сделанных настроек. Тут знающие люди делают хитрое лицо. Они-то знают, где у них лежит образ системы, сделанный Norton Ghost'ом, Acronis'ом или чем-то подобным. Они, в случае чего, р-раз - и восстановятся из образа за 5 минут. Честь им и хвала. Но есть нюанс. Предположим, что образ создавался, скажем, неделю назад. С тех пор некоторые интересующие вас настройки винды или любимых программ могли и измениться. И их снова придется поднастраивать. Это, конечно, не то, что переустановка, но все же труд. А если выяснится, что и "недельный" образ подглючивает, то возвращаться придется еще раньше. И настраивать, соответственно, еще больше. В общем, образ - образом, а нужные настройки не помешало бы перед восстановлением сохранить, а после него - поместить взад .
Или, скажем, вы не пользуетесь образами по религиозным соображениям , и предпочитаете старую добрую переустановку, ну, тогда сохранение и восстановление ваших настроек тем более уместны.
Или пришли вы куда-нибудь кому-нибудь чего-нибудь настраивать. Можно, конечно, долго ковыряться с измученным видом (надеясь, что клиент оценит), а можно клик-клик, и все настроено. Правда, денег дадут меньше (если вы за деньги), зато время сэкономите.
Вот для этих целей (и не только, но всего не расскажешь), я и написал прилагаемые скрипты.
Первый скрипт сохраняет указанные в ини-файле разделы реестра, второй восстанавливает сохраненное. Можете скачать целиком прилагающийся комплект (скрипты, ini-файл, иконка).
Как пользоваться описывать не стану, т.к. все необходимое написано внутри скриптов и ini-файла. Разберетесь без труда.
А вот об ограничениях скажу. Во-первых, для внесения файлов реестра в него, родимый, нужны соответствующие права (это я на всякий случай, сообщаю). Во-вторых, для комментариев в ini-файле используется точка с запятой (;) , а для задания имени файла, отличного от создаваемого по умолчанию - знак конвейера (|). Это значит, что эти символы недопустимы в именах разделов. Проблем с этим быть не должно, т.к. я, поискав по реестру эти символы нон-грата, нашел всего четыре экзотических раздела, имеющих в своем имени эти символы. И очень маловероятно, что вам захочется сохранять именно эти разделы. Однако знать об этом не помешает. В-третьих, если вы будете сохранять файлы реестра не в папку со скриптом (поведение по умолчанию), а зададите свой путь, то в ту же папку скрипт может скопировать скрипт для восстановления и иконку (см. пример в ini-файле). Для этого, они (скрипт _RegRestore.ahk и иконка _RegIcon.ico) должны быть в папке скрипта _RegSave.ahk. Если их там не окажется, то скрипт ничего и не скопирует. Никакого предупреждения выдаваться не будет, т.к. операция, мягко говоря, не критическая .
И последнее: если будут идеи по улучшению-расширению функционала, надеюсь вы поделитесь ими на форуме.

Итак, скрипт для сохранения разделов реестра:

;********************************************************************************************
; AutoHotkey Version:   1.0.44.08+
; Автор:                Androgen Belkin
; Имя скрипта:          _RegSave.ahk (v.2.0)
;********************************************************************************************
; Сохранить указанные в ini-файле разделы реестра.
; Простейший ini-файл - текстовый файл _RegSave.ini, где перечислены разделы по одному в строке.
; Разделы по умолчанию сохраняются в папку со скриптом. Если хотите сохранять разделы в другое место,
; то в ini-файле нужно указать секцию [SETTINGS] и параметр Dir_For_Save = путь.
; В пути поддерживаются переменные окружения и AHK-переменные.
; По умолчанию имена сохраняемых файлов реестра будут, как и у сохраняемых разделов.
; Если хотите сохранять файл под другим именем, то задайте его через "|" после имени раздела.
; Если укажите параметр Dir_For_Save, то будут доступны еще три параметра.
; Примеры смотрите в ini-файле.
;********************************************************************************************

#NoTrayIcon ; не показывать иконку в трее
SetBatchLines, -1 ; указываем максимальную скорость для скрипта

; ПРОВЕРЯЕМ, РАЗРЕШЕН ЛИ REGEDIT
RegRead, DisableRegEdit, HKCU, Software\Microsoft\Windows\CurrentVersion\Policies\System, DisableRegistryTools
If DisableRegEdit = 1 ; если regedit.exe запрещен, то...
{
    MsgBox, В системе запрещен редактор реестра.`n   Без него продолжение невозможно. ; показываем сообщение
    ExitApp ; закончить скрипт
}

SetWorkingDir, %A_ScriptDir% ; установить рабочей папкой для скрипта папку со скриптом (чтобы не сбивалась при запуске "со стороны")

SplitPath, A_ScriptName,,,, Script_Name_NoExt ; получить имя скрипта без расширения
Ini_Name = %A_ScriptDir%\%Script_Name_NoExt%.ini ; имя ini-файла будет имя этого скрипта с расширением .ini

; ПРОВЕРИТЬ НАЛИЧИЕ INI-ФАЙЛА
IfNotExist, %Ini_Name% ; если ini-файл не найден, то показать сообщение и закончить скрипт
{
    MsgBox, Не найден ini-файл для этого скрипта.`nБез ini-файла продолжение невозможно.
    ExitApp ; закончить скрипт
}

; ПРОВЕРЯЕМ И ЕСЛИ НУЖНО СОЗДАЕМ ПАПКУ ДЛЯ СОХРАНЕНИЯ РАЗДЕЛОВ
IniRead, Dir_For_Save, %Ini_Name%, SETTINGS, Dir_For_Save ; прочитать из ini-файла папку для сохранения разделов реестра
Dir_For_Save := Omit_Comment( Dir_For_Save ) ; избавляемся от комментариев в пути к папке для сохранений
If ( Dir_For_Save = "Error" OR Dir_For_Save = "" ) ; если параметра в ini-файле нет, или он пуст (не указан путь), то...
    Dir_For_Save = %A_ScriptDir% ; сохранять файлы реестра в папку со скриптом
Transform, Dir_For_Save, Deref, %Dir_For_Save% ; преобразуем переменные окружения в их значения
IfNotExist, %Dir_For_Save% ; если папка указана, но не существует, то...
{
    ; ПРОВЕРЯЕМ, НУЖНО ЛИ ВЫДАВАТЬ ЗАПРОС НА СОЗДАНИЕ ПАПКИ
    IniRead, Auto_Create_Dir, %Ini_Name%, SETTINGS, Auto_Create_Dir ; прочитать из ini-файла, показывать ли запрос на создание папки
    Auto_Create_Dir := Omit_Comment( Auto_Create_Dir ) ; избавляемся от комментариев в строке
    If Auto_Create_Dir != 1 ; если НЕ указано создавать папку автоматически, то...
    {
        MsgBox, 1, Внимание!, Не существует папки, указанной в ini-файле:`n"%Dir_For_Save%"`n`nСоздать эту папку ? ; показать запрос
        IfMsgBox, Cancel ; если нажата "Отмена", то...
            ExitApp ; закончить скрипт
    }
    FileCreateDir, %Dir_For_Save% ; создать указанную папку
    If ErrorLevel != 0 ; если создать папку не удалось, то...
    {
        MsgBox, 0, Внимание!, Не могу создать папку:`n"%Dir_For_Save%" ; показать сообщение
        ExitApp ; закончить скрипт
    }
}

; СОХРАНИТЬ РАЗДЕЛЫ РЕЕСТРА, УКАЗАННЫЕ В INI-ФАЙЛЕ
Loop, Read, %Ini_Name% ; читаем ini-файл по строке за раз
{
    Cur_String = %A_LoopReadLine% ; вносим текущую строку в переменную, заодно избавляемся от пробелов в начале и в конце строки
    If ( Omit_Comment( Cur_String ) = "" ) ; удаляем комменты из строки, и если возвращаемая строка пуста, то...
        Continue ; перейти к следующей строке
    If Cur_String Contains [SETTINGS],Dir_For_Save
            ,Auto_Create_Dir,Copy_RegRestore,Copy_RegIcon ; если в текущей строке - служебные строки, то...
        Continue ; перейти к следующей строке
    IfInString, Cur_String, | ; если в строке есть "|" (отделитель заказного имени), то...
    {
        StringRight, Custom_Name, Cur_String, StrLen( Cur_String ) - InStr( Cur_String, "|" ) ; извлекаем заказное имя
        StringTrimRight, Cur_String, Cur_String, StrLen( Cur_String ) - InStr( Cur_String, "|" ) + 1 ; отрезаем его из строки
        Cur_String = %Cur_String% ; избавляемся от пробелов в конце строки, возможно появившихся после удаления заказного имени
    }
    StringGetPos, Slash_Pos, Cur_String, \, R ; получить положение последнего слэша в строке
    StringTrimLeft, Reg_File_Name, Cur_String, Slash_Pos+1 ; назначить именем reg-файла часть стоки после слэша
    If Custom_Name ; если есть заказное имя, то...
        Reg_File_Name = %Custom_Name% ; его и назначить именем reg-файла (и избавляемся от пробелов)
    Custom_Name = ; очищаем переменную для следующего цикла
    IfInString, Cur_String, LOCAL_MACHINE ; если в строке есть LOCAL_MACHINE
        Final_Reg_File_Name := Dir_For_Save "\" Reg_File_Name "_LM.reg" ; составить полное имя сохраняемого reg-файла
    Else ; если сохраняемый раздел не из LOCAL_MACHINE, то...
        Final_Reg_File_Name := Dir_For_Save "\" Reg_File_Name ".reg" ; составить полное имя сохраняемого reg-файла
    Run, regedit /e "%Final_Reg_File_Name%" "%Cur_String%" ; сохранить reg-файл с указанным разделом
}

; ПРОВЕРЯЕМ, НУЖНО ЛИ В СОЗДАВАЕМУЮ ПАПКУ КОПИРОВАТЬ СКРИПТ ДЛЯ ВОССТАНОВЛЕНИЯ И ИКОНКУ
IniRead, Copy_RegRestore, %Ini_Name%, SETTINGS, Copy_RegRestore ; прочитать из ini-файла, копировать ли скрипт для восстановления
Copy_RegRestore := Omit_Comment( Copy_RegRestore ) ; избавляемся от комментариев в строке
If ( Dir_For_Save != A_ScriptDir AND Copy_RegRestore = 1 ) ; если указано копировать скрипт для восстановления, то...
    FileCopy, %A_ScriptDir%\_RegRestore.ahk, %Dir_For_Save% ; копировать скрипт для восстановления

IniRead, Copy_RegIcon, %Ini_Name%, SETTINGS, Copy_RegIcon ; прочитать из ini-файла, копировать ли иконку
Copy_RegIcon := Omit_Comment( Copy_RegIcon ) ; избавляемся от комментариев в строке
If ( Dir_For_Save != A_ScriptDir AND Copy_RegIcon = 1 ) ; если указано копировать иконку, то...
    FileCopy, %A_ScriptDir%\_RegIcon.ico, %Dir_For_Save% ; копировать иконку


; ПОКАЗАТЬ ФИНАЛЬНОЕ СООБЩЕНИЕ
SplashImage,, W180 B1,, Файлы реестра успешно сохранены ; показать сообщение
Sleep, 2000
ExitApp ; закончить скрипт

; ФУКЦИЯ УДАЛЕНИЯ КОММЕНТАРИЕВ ИЗ СТРОКИ
Omit_Comment( ByRef Getting_String, Comment = "" ) ; функция удаления комментариев из переданной строки
{
    If Comment = ; если комментарий не передан, то...
        Comment = `; ; назначить комментарием "`;" (точка с запятой с эскейп-последовательностью)
    If Getting_String = ; если строка пуста, то...
        Return ; вернуть из функции пустую строку
    StringGetPos, Comment_Pos, Getting_String, %Comment% ; получить положение комментария (если коммента нет, то Comment_Pos = -1 )
    If Comment_Pos = 0 ; если комментарий есть, и он в начале строки, то...
        Return ; вернуть из функции пустую строку
    If Comment_Pos > 0 ; если комментарий есть, и он НЕ в начале строки, то...
        StringLeft, Getting_String, Getting_String, Comment_Pos ; избавляемся от комментария в конце строки
    Getting_String = %Getting_String% ; избавляемся от пробелов в конце строки, возможно появившихся после удаления комментов
    Return, Getting_String ; вернуть очищенную от комментариев строку
} ; конец функции

Вот ini-файл для скрипта сохранения разделов реестра (короткий вариант, в прилагающемся архиве - более полный)

;*****************************************************************************
;   Сохранить указанные разделы реестра.
;*****************************************************************************

[SETTINGS]
; Куда сохранять файлы реестра (допустимые варианты задания пути к папке сохранений)
;Dir_For_Save = d:\Temp\RegSaves ; путь задан явно
;Dir_For_Save = %Temp%\RegSaves ; путь задан через переменную окружения
;Dir_For_Save = %A_Desktop%\RegSaves_%A_YYYY%.%A_MM%.%A_DD%-%A_Hour%.%A_Min% ; путь задан через AHK-переменные
Dir_For_Save = %A_ScriptDir%\RegSaves_%A_YYYY%.%A_MM%.%A_DD%-%A_Hour%.%A_Min%

; ЕСЛИ ПАПКА ДЛЯ СОХРАНЕНИЯ НЕ ЗАДАНА, ТО ОПЦИИ, УКАЗАННЫЕ НИЖЕ ИГНОРИРУЮТСЯ.
; не выдавать запрос на создание папки, если её не существует:
Auto_Create_Dir = 1 ; создавать папку без вопросов (1 - да, любое другое значение - нет)

; Копировать ли в папку с сохраняемыми файлами реестра:
Copy_RegRestore = 1 ; скрипт для восстановления разделов (1 - да)
Copy_RegIcon = 1 ; иконку для файлов реестра (используется скриптом восстановления)(1 - да)

; Какие разделы реестра сохранять
HKEY_CURRENT_USER\Software\ABBYY;тут комментарий
HKEY_CURRENT_USER\Software\ACD Systems\ACDSee ; и тут комментарий
HKEY_CURRENT_USER\Software\ACD Systems\FotoCanvas
HKEY_CURRENT_USER\Software\Funduc Software Inc.\SR32|Search and Replace ; тут назначаем имя для файла
HKEY_CURRENT_USER\Software\KsL Software\RFA\4.3 | RegistryFirstAid ; и тут назначаем имя для файла
HKEY_CU_0 ; тут какая-то лажа (сохранена не будет)

Теперь скрипт для восстановления разделов из reg-файлов:

;********************************************************************************************
; AutoHotkey Version:   1.0.44.08+
; Автор:                Androgen Belkin
; Имя скрипта:          _RegRestore.ahk (v.1.2)
;********************************************************************************************
; Ищет файлы реестра в указанной папке (см. настройки пользователя) и показывает их в списке.
; Перед тем как внести файлы в реестр, позволяет просматривать и редактировать их.
; Редактировать reg-файл можно дважды кликнув по нему или нажав кнопку "Правка".
; Для удобства выбора желаемых файлов, доступно выделение перетаскиванием и контекстное меню.
;********************************************************************************************

#NoTrayIcon ; не показывать иконку в трее
#NoEnv      ; запрещаем имена переменных как и переменных окружения (повышаем производительность скрипта)
#SingleInstance, Force ; перезапускать программу без вопросов
SetBatchLines, -1 ; указываем максимальную скорость для скрипта

; ========== НАСТРОЙКИ ПОЛЬЗОВАТЕЛЯ ==========
Reg_Dir = %A_ScriptDir% ; папка с обрабатываемыми файлами реестра (по умолчанию - папка, где находится скрипт)
Icon_File = %A_ScriptDir%\_RegIcon.ico ; значок для файлов реестра, отображаемый в списке (можно не указывать)
Editor_Path = D:\Totalcmd\Plugins\wlx_SynPlus\SPlusEditStart.exe ; путь к просмотровщику-редактору файлов реестра

Gui_Width = 550 ; начальная ширина окна со списком файлов реестра (не указывайте < 300)
Gui_Height = 300 ; начальная высота окна со списком файлов реестра
; ========== КОНЕЦ НАСТРОЕК ПОЛЬЗОВАТЕЛЯ ==========

; ПРОВЕРЯЕМ, РАЗРЕШЕН ЛИ REGEDIT
RegRead, DisableRegEdit, HKCU, Software\Microsoft\Windows\CurrentVersion\Policies\System, DisableRegistryTools
If DisableRegEdit = 1 ; если regedit.exe запрещен, то...
{
    MsgBox, В системе запрещен редактор реестра.`n   Без него продолжение невозможно. ; показываем сообщение
    ExitApp ; закончить скрипт
}

IfNotExist, %Reg_Dir%\*.reg ; если по указанному пути не найдено файлов реестра, то...
{
    MsgBox, %A_Space% По указанному пути не найдено файлов реестра.`nПроверьте НАСТРОЙКИ ПОЛЬЗОВАТЕЛЯ в скрипте. ; показать сообщение
    ExitApp ; закончить скрипт
}

IfNotExist, %Editor_Path% ; если путь к указанному редактору не верен, то...
    Editor_Path = notepad.exe ; назначить редактором блокнот

Gui, +Resize ; разрешить изменение размеров окна
Gui, Margin, 0 ; размещать контролы от нулевой координаты окна слева
Gui, Add, Text, Center w%Gui_Width%, Выберите файлы, содержимое которых вы хотите внести в реестр.
Gui, Margin, 10 ; размещать контролы на 10 пикселей от нулевой координаты окна слева
; создать надпись по центру, по ширине всего окна

w_listview := Gui_Width - 20
h_listview := Gui_Height - 60
Gui, Add, ListView, List Checked Count100 gView_Edit vMyListView xm w%w_listview% h%h_listview%
; создать список, в виде "список", с чекбоксами, xm начинает новую строку в разметке GUI, подстроить размер ListView под размер окна

IfExist, %Icon_File% ; если указанный значок существует
{
    ImageListID := IL_Create() ; создаем ImageList, чтобы ListView мог отображать значки
    LV_SetImageList( ImageListID ) ; присоединяем ImageLists к ListView, чтобы позже показать значки
    IL_Add( ImageListID, Icon_File, 0 ) ; назначаем значок для отображения
}


Loop, %Reg_Dir%\*.reg ; найти все файлы *.reg в указанной папке
    LV_Add( "Check", A_LoopFileName ) ; добавить файл в список и отметить его чекбокс (выбрать)

; создаем контекстное меню для работы со списком
Menu, MyContextMenu, Add, Отметить выделенные, CheckSelecting
Menu, MyContextMenu, Add, Снять отметку с выделенных, UnCheckSelecting
Menu, MyContextMenu, Add ; разделитель
Menu, MyContextMenu, Add, Отметить все, CheckAll
Menu, MyContextMenu, Add, Снять отметки со всех, UnCheckAll

w_Button = 75 ; задаем ширину для кнопок (эта переменная будет сейчас использоваться)
; для вычисления используется заданная Gui_Width, а не встроенная A_GuiWidth, т.к. окно еще не отображено и встроенная переменная пуста
x_Button1 := Gui_Width/2 - w_Button*2 ; задаем х-координату 1-ой кнопки
x_Button2 := Gui_Width/2 - w_Button/2 ; задаем х-координату 2-ой кнопки
x_Button3 := Gui_Width/2 + w_Button ; задаем х-координату 3-ей кнопки
y_Button := Gui_Height - 30 ; задаем у-координату (общую для всех трех кнопок)

Gui, Add, Button, gView_Edit x%x_Button1% y%y_Button% w%w_Button%, Правка ; кнопка "Правка"
Gui, Add, Button, Default gFile_To_Reg x%x_Button2% yp wp hp, ОК ; кнопка "ОК" (y-координата, ширина и высота как у предыдущей)
Gui, Add, Button, gGuiClose x%x_Button3% yp wp hp, Отмена ; кнопка "Отмена" (y-координата, ширина и высота как у предыдущей)

Gui, Show, w%Gui_Width% h%Gui_Height%, Внесение файлов в реестр - Androgen ®2006 ; показать созданное окно

Return ; конец секции автовыполнения (дальше скрипт будет что-то делать только в ответ на действия пользователя)

GuiSize: ; (встроенная метка) подпрограмма обработки изменения размера окна
    If A_EventInfo = 1 ; если окно минимизировано, то...
        Return ; ничего не делать
    ; если размер окна изменяется, то...
    if A_GuiWidth < 300 ; если ширина окна меньше той, когда кнопки располагаются нормально, то...
    {
        MouseClick,,,,,, U ; отжать мышку, которой делали ресайз (чтобы не было мельканий в окне)
        WinMove, ,,,, 308 ; увеличить размер окна в ширину на 8 пикселей
    }
    GuiControl, Move, MyListView, % "w" . ( A_GuiWidth - 20 ) . " h" . ( A_GuiHeight - 60 ) ; подстроить размер ListView под размер окна
    GuiControl, Move, Button1, % "x" . ( A_GuiWidth/2 - w_Button*2 ) . " y" . ( A_GuiHeight - 30 ) ; подстроить кнопку под размер окна
    GuiControl, Move, Button2, % "x" . ( A_GuiWidth/2 - w_Button/2 ) . " y" . ( A_GuiHeight - 30 ) ; подстроить кнопку под размер окна
    GuiControl, Move, Button3, % "x" . ( A_GuiWidth/2 + w_Button ) . " y" . ( A_GuiHeight - 30 ) ; подстроить кнопку под размер окна
Return ; конец подпрограммы

View_Edit: ; подпрограмма просмотра-правки файла реестра в заданном редакторе
    if A_GuiEvent = DoubleClick ; если подпрограмма запущена двойным кликом в списке файлов, то...
    {
        LV_GetText( Reg_File_Name, A_EventInfo ) ; получить имя кликнутого файла реестра
        If Reg_File_Name = ; если клик был сделан НЕ на каком-нибудь файле из списка, то...
            return ; конец подпрограммы
    }
    Else ; если подпрограмма запущена нажатием кнопки "Правка", то...
    {
        Loop ; пройти все строки в списке, пока не дойдем до фокусированной (если она есть)
        {
            RowNumber := LV_GetNext( 0, "F" ) ; получить номер фокусированной строки (а не выделенной и не отмеченной) (начинать с нуля)
            if RowNumber = 0 ; если фокусированной строки не найдено, то...
            {
                SplashImage,, W180 B1,, Выберите файл ; показать сообщение
                Sleep, 800
                SplashImage, Off ; выключить сообщение
                return ; конец подпрограммы
            }
            LV_GetText( Reg_File_Name, RowNumber ) ; если найдена, то сохранить в переменную
            break ; завершить поиск
        }
    }
    Run, "%Editor_Path%" "%Reg_Dir%\%Reg_File_Name%" ; открыть файл в указанном редакторе
Return ; конец подпрограммы

File_To_Reg: ; подпрограмма внесения файлов в реестр
    RowNumber := LV_GetNext( 0, "C" ) ; получить номер отмеченной строки (начинать с нуля)
    If RowNumber = 0 ; если отмеченных строк нет, то...
    {
        SplashImage,, W180 B1,, Ничего не выбрано ; показать сообщение
        Sleep, 800
        SplashImage, Off ; выключить сообщение
        Return ; ничего не делать
    }
    MsgBox, 1, Внимание!, Внести содержимое выбранных файлов в реестр ? ; показать запрос
    IfMsgBox, Cancel ; если нажата "Отмена", то...
        Return ; ничего не делать
    Loop ; если нажата "ОК", то...
    {
        RowNumber := LV_GetNext( 0, "C" ) ; получить номер отмеченной строки
        If RowNumber = 0 ; если отмеченных строк больше нет, то...
            Break ; закончить цикл
        LV_GetText( Reg_File_Name, RowNumber ) ; получить из строки имя файла
        Run, regedit /s "%Reg_Dir%\%Reg_File_Name%" ; внести файл в реестр
        LV_Delete( RowNumber ) ; удалить файл из списка ListView
    }
    SplashImage,, W180 B1,, Файлы были успешно внесены в реестр ; показать сообщение
    Sleep, 2000
    ExitApp ; закончить скрипт
Return ; конец подпрограммы

GuiContextMenu: ; показать контекстное меню при правом клике или при нажатии клавиши Apps
    if ( A_GuiControl = "MyListView" AND LV_GetCount() != 0 ) ; если правая кнопка кликнута на ListView и список не пуст, то...
        Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY% ; показать контекстное меню
Return ; конец подпрограммы

CheckSelecting: ; подпрограмма контекстного меню "Отметить выделенные"
RowNumber = 0 ; начинать поиск выделенных сверху списка
Loop
{
    RowNumber := LV_GetNext( RowNumber ) ; продолжить поиск в строке после последней найденной
    if RowNumber = 0 ; если больше выделенных строк не найдено, то...
        break ; завершить поиск
    LV_Modify( RowNumber, "Check" ) ; отметить найденный пункт
}
Return ; конец подпрограммы

UnCheckSelecting: ; подпрограмма контекстного меню "Снять отметку с выделенных"
RowNumber = 0 ; начинать поиск выделенных сверху списка
Loop
{
    RowNumber := LV_GetNext( RowNumber ) ; продолжить поиск в строке после последней найденной
    if RowNumber = 0 ; если больше выделенных строк не найдено, то...
        break ; завершить поиск
    LV_Modify( RowNumber, "-Check" ) ; снять отметку с найденного пункта
}
Return ; конец подпрограммы

CheckAll: ; подпрограмма контекстного меню "Отметить все"
    Loop % LV_GetCount() ; обработать все строки в списке
        LV_Modify( A_Index, "Check" ) ; отметить текущий пункт
Return ; конец подпрограммы

UnCheckAll: ; подпрограмма контекстного меню "Снять отметки со всех"
    Loop % LV_GetCount() ; обработать все строки в списке
        LV_Modify( A_Index, "-Check" ) ; снять отметку с текущего пункта
Return ; конец подпрограммы

GuiClose: ; (встроенная метка) подпрограмма выхода, если окно закрыто
GuiEscape: ; если нажата Escape
ExitApp ; закончить скрипт
Post's attachments

RegSave-Restore.zip 12.87 kb, 764 downloads since 2006-07-29 

You don't have the permssions to download the attachments of this post.
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).