(*~\Глагол\Отделы\Обмен\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                               ОТДЕЛ ОС;
(*============================================================================*
 * НАЗНАЧЕНИЕ:
 *             взаимодействие с операционной системой (Win32 - 2000,XP,7,8,10)
 *============================================================================*)

ИСПОЛЬЗУЕТ
  ОБХОД,
        (*  \Глагол\              *)
 оБуквы   ИЗ "..\..\Отделы\Иное\",
 оЦепи    ИЗ "..\..\Отделы\Иное\";

ПОСТ
                                  (* наибольшие длины (с учетом конечного 0X) *)
  длПутиФ-     = 260; (* пути к файлу                     *)
  длИмениФ-    = 256; (* имени файла без типа файла       *)
  длТипаФ-     = 5;   (* типа файла с начальной "."       *)
  длКорИмениФ- = 14;  (* короткого имени с типом файла    *)
  длПолногоФ-  = ОС.длПутиФ+
                 ОС.длИмениФ; (* полного имени файла *)

                                  (* свойства файлов *)
  сфТолькоЧтение-  = 0;
  сфНевидимый-     = 1;
  сфСистемный-     = 2;
  сфНазваниеДиска- = 3;
  сфКаталог-       = 4;
  сфАрхивный-      = 5;
  сфОбычный-       = 7;
  сфОшибкаЧтения-  =31;
                                     (* файлы *)
ВИД
                            (* время *)
  шцВремяФ- = ОБХОД.Цел64;
                            (* поиск + фссылка *)
  нПоискФ- = НАБОР
    свойства-         :МНОЖ;       (* использовалось в СвойстваИзПоискаФ() *)
    времяСоздания-    :ОС.шцВремяФ;              
    времяПослДоступа- :ОС.шцВремяФ;              
    времяПослЗаписи-  :ОС.шцВремяФ;              
    размерСтарш-      :ЦЕЛ;                 
    размерМладш-      :ЦЕЛ;        (* использовалось в РазмерИзПоискаФ() *)
    прозапас0         :ЦЕЛ;                 
    прозапас1         :ЦЕЛ;                 
    имя-              :РЯД ОС.длПутиФ ИЗ ЗНАК; (* использовалось в ИмяИзПоискаФ() *)
    короткоеИмя-      :РЯД ОС.длКорИмениФ ИЗ ЗНАК;      
    фссылка           :ЦЕЛ;                 (* добавок *)      
  КОН;
                        (* текущее время *)
  нСейчас- = НАБОР
    год-     :ОБХОД.Цел16; (* год                *)
    месяц-   :ОБХОД.Цел16; (* 1-январь, ...      *)
    деньНед- :ОБХОД.Цел16; (* 0-воскресенье, ... *)
    день-    :ОБХОД.Цел16; (* день месяца        *)
    час-     :ОБХОД.Цел16; (* час                *)
    минута-  :ОБХОД.Цел16; (* минута             *)
    секунда- :ОБХОД.Цел16; (* секунда            *)
    мсекунда-:ОБХОД.Цел16; (* миллисекунда       *)
  КОН;
 
ПЕР
  русРаскладка:ЦЕЛ;   (* раскладка клавиатуры для русского языка *)
  латРаскладка:ЦЕЛ;   (* раскладка клавиатуры для английского языка *)
  ссылкаНаВвод- :ЦЕЛ; (* ссылка на встроенный файл ввода  *)
  ссылкаНаВывод-:ЦЕЛ; (* ссылка на встроенный файл вывода *)
  ссылкаНаСтог:ЦЕЛ;   (* ссылка на встроенный стог памяти *)

                                 (* используемые виды ОС Windows *)
ВИД
  SECURITY_ATTRIBUTES =
  НАБОР
    nLength             :ЦЕЛ; 
    lpSecurityDescriptor:ЦЕЛ; 
    bInheritHandle      :ЦЕЛ; 
  КОН;
  STARTUPINFO =
  НАБОР
    cb                  :ЦЕЛ; 
    lpReserved          :ЦЕЛ; 
    lpDesktop           :ЦЕЛ; 
    lpTitle             :ЦЕЛ; 
    dwX                 :ЦЕЛ;                   
    dwY                 :ЦЕЛ; 
    dwXSize             :ЦЕЛ;               
    dwYSize             :ЦЕЛ; 
    dwXCountChars       :ЦЕЛ; 
    dwYCountChars       :ЦЕЛ; 
    dwFillAttribute     :ЦЕЛ; 
    dwFlags             :ЦЕЛ; 
    wShowWindow         :ОБХОД.Цел16;
    cbReserved2         :ОБХОД.Цел16;
    lpReserved2         :ЦЕЛ; 
    hStdInput           :ЦЕЛ; 
    hStdOutput          :ЦЕЛ; 
    hStdError           :ЦЕЛ; 
  КОН;
  PROCESS_INFORMATION =
  НАБОР
    hProcess            :ЦЕЛ; 
    hThread             :ЦЕЛ; 
    dwProcessId         :ЦЕЛ; 
    dwThreadId          :ЦЕЛ; 
  КОН;

                        (* используемые Win задачи *)

ЗАДАЧА GetProcAddress(hModule,lpProcName:ЦЕЛ):ЦЕЛ;       ВЫЗОВ "GetProcAddress"             ИЗ "kernel32.dll";
ЗАДАЧА GetProcessHeap():ЦЕЛ;                             ВЫЗОВ "GetProcessHeap"             ИЗ "kernel32.dll";
ЗАДАЧА HeapAlloc(hHeap,dwFlags,dwBytes:ЦЕЛ):ЦЕЛ;         ВЫЗОВ "HeapAlloc"                  ИЗ "kernel32.dll";
ЗАДАЧА HeapFree(hHeap,dwFlags,lpMem:ЦЕЛ);                ВЫЗОВ "HeapFree"                   ИЗ "kernel32.dll";
ЗАДАЧА CloseHandle(hObject:ЦЕЛ);                         ВЫЗОВ "CloseHandle"                ИЗ "kernel32.dll";
ЗАДАЧА FindClose(hFindFile:ЦЕЛ);                         ВЫЗОВ "FindClose"                  ИЗ "kernel32.dll";
ЗАДАЧА GlobalAlloc(uFlags,dwBytes:ЦЕЛ):ЦЕЛ;              ВЫЗОВ "GlobalAlloc"                ИЗ "kernel32.dll";
ЗАДАЧА GlobalLock(hMem:ЦЕЛ):ЦЕЛ;                         ВЫЗОВ "GlobalLock"                 ИЗ "kernel32.dll";
ЗАДАЧА GlobalUnlock(hMem:ЦЕЛ);                           ВЫЗОВ "GlobalUnlock"               ИЗ "kernel32.dll";
ЗАДАЧА GlobalFree(hMem:ЦЕЛ);                             ВЫЗОВ "GlobalFree"                 ИЗ "kernel32.dll";
ЗАДАЧА LocalAlloc(uFlags,uBytes:ЦЕЛ):ЦЕЛ;                ВЫЗОВ "LocalAlloc"                 ИЗ "kernel32.dll";
ЗАДАЧА LocalFree(hMem:ЦЕЛ):ЦЕЛ;                          ВЫЗОВ "LocalFree"                  ИЗ "kernel32.dll";
ЗАДАЧА GetStdHandle(nStdHandle:ЦЕЛ):ЦЕЛ;                 ВЫЗОВ "GetStdHandle"               ИЗ "kernel32.dll";
ЗАДАЧА WaitForSingleObject(hHandle,dwMilliseconds:ЦЕЛ);  ВЫЗОВ "WaitForSingleObject"        ИЗ "kernel32.dll";
ЗАДАЧА SetEnvironmentVariable(lpName-,lpValue-:ЦЕПЬ);    ВЫЗОВ "SetEnvironmentVariableW"    ИЗ "kernel32.dll";
ЗАДАЧА GetFileAttributes(lpFileName-:ЦЕПЬ):ЦЕЛ;          ВЫЗОВ "GetFileAttributesW"         ИЗ "kernel32.dll";
ЗАДАЧА GetCommandLine():ЦЕЛ;                             ВЫЗОВ "GetCommandLineW"            ИЗ "kernel32.dll";

ЗАДАЧА CreateDirectory(lpPathName-:ЦЕПЬ; lpSecurityAttributes:ЦЕЛ):КЛЮЧ; ВЫЗОВ "CreateDirectoryW" ИЗ "kernel32.dll";
ЗАДАЧА ReadFile(hFile,lpBuffer,nNumberOfBytesToRead,lpNumberOfBytesRead+,lpOverlapped:ЦЕЛ):ЦЕЛ;  ВЫЗОВ "ReadFile" ИЗ "kernel32.dll";
ЗАДАЧА WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,lpNumberOfBytesWritten+,lpOverlapped:ЦЕЛ); ВЫЗОВ "WriteFile" ИЗ "kernel32.dll";
ЗАДАЧА SetFilePointer(hFile,lDistanceToMove,lpDistanceToMoveHigh,dwMoveMethod:ЦЕЛ):ЦЕЛ; ВЫЗОВ "SetFilePointer" ИЗ "kernel32.dll";
ЗАДАЧА CreateProcess(lpApplicationName:ЦЕЛ; lpCommandLine-:ЦЕПЬ; lpProcessAttributes,ThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory:ЦЕЛ; lpStartupInfo+:STARTUPINFO; lpProcessInformation+:PROCESS_INFORMATION):ЦЕЛ; ВЫЗОВ "CreateProcessW" ИЗ "kernel32.dll";
ЗАДАЧА GetEnvironmentVariable(lpName-,lpBuffer+:ЦЕПЬ; nSize:ЦЕЛ):ЦЕЛ; ВЫЗОВ "GetEnvironmentVariableW" ИЗ "kernel32.dll";
ЗАДАЧА SetFileAttributes(lpFileName-:ЦЕПЬ; dwFileAttributes:МНОЖ); ВЫЗОВ "SetFileAttributesW" ИЗ "kernel32.dll";
ЗАДАЧА FindFirstFile(lpFileName-:ЦЕПЬ; lpFindFileData+:нПоискФ):ЦЕЛ; ВЫЗОВ "FindFirstFileW" ИЗ "kernel32.dll";
ЗАДАЧА FindNextFile(hFindFile:ЦЕЛ; lpFindFileData+:нПоискФ):ЦЕЛ; ВЫЗОВ "FindNextFileW" ИЗ "kernel32.dll";
ЗАДАЧА GetCurrentDirectory(nBufferLength:ЦЕЛ; lpBuffer-:ЦЕПЬ):ЦЕЛ; ВЫЗОВ "GetCurrentDirectoryW" ИЗ "kernel32.dll";
ЗАДАЧА GetFullPathName(lpFileName-:ЦЕПЬ; nBufferLength:ЦЕЛ; lpBuffer-:ЦЕПЬ; lpFilePart+:ЦЕЛ):ЦЕЛ; ВЫЗОВ "GetFullPathNameW" ИЗ "kernel32.dll";
ЗАДАЧА CreateFile(lpFileName-:ЦЕПЬ; dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile:ЦЕЛ):ЦЕЛ; ВЫЗОВ "CreateFileW" ИЗ "kernel32.dll";
ЗАДАЧА LoadKeyboardLayout(pwszKLID-:ЦЕПЬ; Flags:ЦЕЛ):ЦЕЛ;ВЫЗОВ "LoadKeyboardLayoutW"        ИЗ "user32.dll";
ЗАДАЧА VkKeyScanEx(ch:ЗНАК; dwhkl:ЦЕЛ):ЦЕЛ;              ВЫЗОВ "VkKeyScanExW"               ИЗ "user32.dll";
ЗАДАЧА OpenClipboard(hWndNewOwner:ЦЕЛ):КЛЮЧ;             ВЫЗОВ "OpenClipboard"              ИЗ "user32.dll";
ЗАДАЧА CloseClipboard();                                 ВЫЗОВ "CloseClipboard"             ИЗ "user32.dll";
ЗАДАЧА EmptyClipboard();                                 ВЫЗОВ "EmptyClipboard"             ИЗ "user32.dll";
ЗАДАЧА SetClipboardData(uFormat,hMem:ЦЕЛ);               ВЫЗОВ "SetClipboardData"           ИЗ "user32.dll";
ЗАДАЧА GetClipboardData(uFormat:ЦЕЛ):ЦЕЛ;                ВЫЗОВ "GetClipboardData"           ИЗ "user32.dll";
ЗАДАЧА IsClipboardFormatAvailable(format:ЦЕЛ):КЛЮЧ;      ВЫЗОВ "IsClipboardFormatAvailable" ИЗ "user32.dll";

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Связаться-(имя-:ЦЕПЬ):ЦЕЛ;                        ВЫЗОВ "LoadLibraryW"               ИЗ "kernel32.dll";
(*
 * Связывание с ДПБ, имя которой <имя>. Возвращает ссылку на ДПБ или 0.
 *)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Отвязаться-(ссылка:ЦЕЛ);                          ВЫЗОВ "FreeLibrary"                ИЗ "kernel32.dll";
(*
 * Отказ от использования ДПБ.
 *)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       УдалитьФ-(имя-:ЦЕПЬ):КЛЮЧ;                        ВЫЗОВ "DeleteFileW"                ИЗ "kernel32.dll";
(*
 * Удаляет файл с именем <имя>, возвращая ВКЛ в случае успеха.
 *)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПереименоватьФ-(староеимя-,
                        новоеимя-:ЦЕПЬ):КЛЮЧ;            ВЫЗОВ "MoveFileW"                  ИЗ "kernel32.dll";
(*
 * Переименовывает файл со <староеимя> на <новоеимя>.
 * При успешном выполнении возвращает ВКЛ.
 *)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Спать-(мс:ЦЕЛ);                                   ВЫЗОВ "Sleep"                      ИЗ "kernel32.dll";
(*
 * Приостановить работу приложения на <мс> миллисекунд.
 *)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Гудок-(частота,
              длительность:ЦЕЛ);                         ВЫЗОВ "Beep"                       ИЗ "kernel32.dll";

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       КоторыйЧас-(сейчас+:нСейчас);                     ВЫЗОВ "GetSystemTime"              ИЗ "kernel32.dll";
(*
 * Возвращает текущее время.
 *)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Время-():ЦЕЛ;                                     ВЫЗОВ "GetTickCount"               ИЗ "kernel32.dll";
(*
 * Возвращает время в [мсек] от старта Windows
 *                                             с шагом 15-16 мсек (!),
 *     однако замечено, что при запущенном AIMP3.exe шаг = 1 мсек (!), хотя и не на всех компьютерах
 *)
(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТекВремя_в_мсек(год,
                           минута,
                                  секунда,
                                 мсекунда:ШИРЦЕЛ):ШИРЦЕЛ;         (* в [мсек] *)
(*
 * Возвращает в [мсек] текущее время вида ШИРЦЕЛ,
 * преобразуя сразу 4 источника вида ОБХОД.Цел16 из ОС.КоторыйЧас(t)
                  в 4 приёмника вида ШИРЦЕЛ
 *)
УКАЗ
  ВОЗВРАТ (((год*60 + минута)*60 + секунда)*1000 + мсекунда)
КОН ТекВремя_в_мсек;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВремяТекущее-():ШИРЦЕЛ;                                    (* в [мсек] *)
(*VAR                     t:SysClock.DateTime;  *)
ПЕР                       t:ОС.нСейчас;
УКАЗ
            ОС.КоторыйЧас(t);
(*      SysClock.GetClock(t); *)
  ВОЗВРАТ ТекВремя_в_мсек(t.год,      t.минута,      t.секунда,        t.мсекунда)
(*
  ВОЗВРАТ              (((t.год*60  + t.минута)*60 + t.секунда)*1000 + t.мсекунда)

  RETURN                 (t.hour*60 + t.minute)*60 + t.second;    (* в [сек]  *)
*)
КОН ВремяТекущее;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьП-(имя-:ЦЕПЬ):КЛЮЧ;
(*
 *     Создаёт папку с именем <имя>, возвращая ВКЛ в случае успеха.
 *)
УКАЗ
  ВОЗВРАТ CreateDirectory(имя,0)
КОН СоздатьП;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЗакрытьФ-(фссылка:ЦЕЛ);
(*     Закрывает файл по ссылке <фссылка>. *)
УКАЗ
  CloseHandle(фссылка)
КОН ЗакрытьФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ФДляЧтения-(имя-:ЦЕПЬ):ЦЕЛ;
(*
 * Открывает файл <имя> для чтения. При неудаче возвращает 0.
 *)
ПЕР
            цОтвет:ЦЕЛ;
УКАЗ
            цОтвет:=CreateFile(имя,МИН(ОБХОД.Цел32)(*80000000H*),1,0,3,80H,0);
  ЕСЛИ
            цОтвет = -1
  ТО
    ВОЗВРАТ 0
  ИНАЧЕ
    ВОЗВРАТ цОтвет
  КОН
КОН ФДляЧтения;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ФДляЗаписи-(имя-:ЦЕПЬ):ЦЕЛ;
(*
 *   Создает файл <имя> для записи. При неудаче возвращает 0.
 *)
ПЕР
            цОтвет:ЦЕЛ;
УКАЗ
            цОтвет:=CreateFile(имя,40000000H,1,0,2,80H,0);
  ЕСЛИ
            цОтвет = -1
  ТО
    ВОЗВРАТ 0
  ИНАЧЕ
    ВОЗВРАТ цОтвет
  КОН
КОН ФДляЗаписи;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ФДляПополнения-(имя-:ЦЕПЬ):ЦЕЛ;
(*
 * Открывает (или создает, если не существует) файл с именем <имя> для записи
 * данных в его конец. При неудаче возвращает 0.
 *)
ПЕР
       цОтвет:ЦЕЛ;

       фссылка:ЦЕЛ;
УКАЗ
       фссылка:=CreateFile(имя,40000000H,1,0,4,80H,0);
  ЕСЛИ
       фссылка = -1
  ТО
    ВОЗВРАТ 0
  КОН;
       цОтвет:=SetFilePointer(фссылка,0,0,2);
  ЕСЛИ
       цОтвет = -1
  ТО
    ВОЗВРАТ 0
  КОН;
    ВОЗВРАТ фссылка
КОН ФДляПополнения;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЧитатьФ-(
                    фссылка:ЦЕЛ;
                    память+:ОБХОД.Ячейки;
                     размер:ЦЕЛ
               ):ЦЕЛ;
(* 
 * Читает из файла по ссылке <фссылка> в <память> данные размером <размер> ячеек.
 * Возвращает число прочитанных ячеек.
 *)
ПЕР
       цОтвет:ЦЕЛ;
УКАЗ
       цОтвет:=ReadFile(фссылка,ОБХОД.ПолучитьАдрес(память),размер,размер,0);
  ЕСЛИ
       цОтвет = 0
  ТО
    ВОЗВРАТ 0
  КОН;
    ВОЗВРАТ размер
КОН ЧитатьФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПисатьФ-(
                    фссылка:ЦЕЛ;
                    память-:ОБХОД.Ячейки;
                     размер:ЦЕЛ
               );
(*
 * Записывает в <фссылка> из <память> данные размером <размер> ячеек.
 *)
УКАЗ
  WriteFile(фссылка,ОБХОД.ПолучитьАдрес(память),размер,размер,0)
КОН ПисатьФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СвойстваФ-(имя-:ЦЕПЬ):МНОЖ;        (* Возвращает свойства файла <имя>. *)
ПЕР
       цОтвет:ЦЕЛ;
УКАЗ
       цОтвет:=GetFileAttributes(имя);
  ЕСЛИ
       цОтвет = -1
  ТО
    ВОЗВРАТ {сфОшибкаЧтения}              (* множество *)
  ИНАЧЕ
    ВОЗВРАТ ОБХОД.Значение(МНОЖ,цОтвет)
  КОН
КОН СвойстваФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СменаСвойствФ-(имя-:ЦЕПЬ; свойства:МНОЖ);
(*
 * Меняет свойства файла <имя> на <свойства>. Свойства можно
 * получать, объединяя постоянные <сф_>.
 *)
УКАЗ
  SetFileAttributes(имя,свойства)
КОН СменаСвойствФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПозицияФ-(фссылка:ЦЕЛ):ЦЕЛ;
(*
 * Возвращает позицию, отсчитываемую от начала открытого файла
 *   со ссылкой <фссылка>.
 *)
УКАЗ
  ВОЗВРАТ SetFilePointer(фссылка,0,0,1)
КОН ПозицияФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СменаПозицииФ-(фссылка,позиция:ЦЕЛ);
(*
 * Меняет позицию в открытом файле с сылкой <фссылка> на <позиция>,
 * отсчитываемую от начала файла.
 *)
ПЕР
  цОтвет:ЦЕЛ;
УКАЗ
  цОтвет:=SetFilePointer(фссылка,позиция,0,0)
КОН СменаПозицииФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПервыйПоискФ-(путь-:ЦЕПЬ; поиск+:нПоискФ):КЛЮЧ;
(*
 * Начинает поиск файлов в каталоге по образцу <путь>.
 * Например, "C:\Глагол\*.отд". При успешном завершении возвращает
 * ВКЛ, а результаты поиска заносятся в поисковый набор <поиск>.
 *)
ПЕР
       цОтвет,поз:ЦЕЛ;
УКАЗ
       цОтвет:=FindFirstFile(путь,поиск);
  ЕСЛИ
       цОтвет = -1
  ТО
    ВОЗВРАТ ОТКЛ
  КОН;
  поиск.фссылка:=цОтвет;
    ВОЗВРАТ ВКЛ
КОН ПервыйПоискФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СледующийПоискФ-(поиск+:нПоискФ):КЛЮЧ;
(*
 * Продолжает поиск начатый действием <ПервыйПоискФ>. При успешном завершении
 * возвращает ВКЛ и результаты поиска заносятся в поисковый набор <поиск>.
 *)
УКАЗ
  ВОЗВРАТ FindNextFile(поиск.фссылка,поиск) # 0
КОН СледующийПоискФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ОкончитьПоискФ-(поиск+:нПоискФ);
(*
 * Оканчивает поиск начатый <ПервыйПоискФ>.
 *)
УКАЗ
  FindClose(поиск.фссылка)
КОН ОкончитьПоискФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ТекущийПутьФ-(дискпуть+:ЦЕПЬ);
(*
 * Записывает в <дискпуть> текущий путь
 *)
ПЕР
       цОтвет:ЦЕЛ;
УКАЗ
                             (* вызов задачи-функции возвращающей целый ответ *)
       цОтвет:=GetCurrentDirectory(РАЗМЕР(дискпуть),дискпуть);
  ЕСЛИ
       цОтвет = 0
  ТО
    дискпуть[0]:=0X
  КОН
КОН ТекущийПутьФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       МестоФ-(имя-,место+:ЦЕПЬ);
(*
 * Переводит имя файла <имя> в местоположение файла <место>. Относительное
 * имя <имя> может содержать ".\" и "..". Если <имя> не содержит название
 * диска, то подставляется название текущего диска.
 *)
ПЕР
       цОтвет,адрес:ЦЕЛ;
УКАЗ
                             (* вызов задачи-функции возвращающей целый ответ *)
       цОтвет:=GetFullPathName(имя,РАЗМЕР(место),место,адрес);
  ЕСЛИ
       цОтвет = 0
  ТО
    место[0]:=0X
  КОН
КОН МестоФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПолучитьКомСтроку-(куда+:ЦЕПЬ);
ПЕР
  адрес,поз:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
  поз:=0;
  адрес:=GetCommandLine();
  ПОВТОРЯТЬ
    ОБХОД.ИзПамяти(адрес+поз*2,зн);
    куда[поз]:=зн;
    УВЕЛИЧИТЬ(поз)
  ДО (зн = 0X) ИЛИ (поз >= РАЗМЕР(куда))
КОН ПолучитьКомСтроку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВзятьПамять-(размер:ЦЕЛ):ЦЕЛ;
(*
 * Берёт у ОС кусок памяти в <размер> ячеек и обнуляет его.
 * Возвращает <адрес> этого куска и ссылку Win на него.
 * <ссылка> равная 0 означает, что Win не выделила память.
 *)
УКАЗ
  ВОЗВРАТ HeapAlloc(ссылкаНаСтог,8,размер)
КОН ВзятьПамять;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ОтдатьПамять-(адрес:ЦЕЛ);
(*
 * Отдаёт в ОС кусок памяти, взятый до этого с помощью ВзятьПамять.
 *)
УКАЗ
  HeapFree(ссылкаНаСтог,0,адрес)
КОН ОтдатьПамять;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЦепочкуВОбменник-(цепь-:ЦЕПЬ);
ПЕР
  длина,ссылка,адрес:ЦЕЛ;
УКАЗ
  длина:=ДЛИНА(цепь)*2; (* ячеек *)
  ЕСЛИ
       OpenClipboard(0)
  ТО
      EmptyClipboard();
          ссылка:=GlobalAlloc(2000H,длина+2);
    ЕСЛИ
          ссылка # 0
    ТО
           адрес:=GlobalLock(ссылка);
      ЕСЛИ
           адрес # 0
      ТО
        ОБХОД.Образ(ОБХОД.ПолучитьАдрес(цепь),адрес,длина);
        ОБХОД.ВПамять(адрес+длина,0X)
      КОН;
      GlobalUnlock(ссылка)
    КОН;
    SetClipboardData(13,ссылка);
    CloseClipboard()
  КОН
КОН ЦепочкуВОбменник;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       НайтиЗнак0(адрес:ЦЕЛ):ЦЕЛ;
ПЕР
  поз:ЦЕЛ;
  знак:ЗНАК;
УКАЗ
  поз:=-1;
  ПОВТОРЯТЬ 
    УВЕЛИЧИТЬ(поз);
    ОБХОД.ИзПамяти(адрес+поз*2,знак)
  ДО знак = 0X;
  ВОЗВРАТ поз
КОН НайтиЗнак0;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       РазмерЦепочкиОбменника-():ЦЕЛ;
ПЕР
  размер,ссылка,адрес:ЦЕЛ;
УКАЗ
  размер:=0;
  ЕСЛИ IsClipboardFormatAvailable(13) ТО
    ЕСЛИ OpenClipboard(0) ТО
      ссылка:=GetClipboardData(13);
      ЕСЛИ ссылка # 0 ТО
        адрес:=GlobalLock(ссылка);
        ЕСЛИ адрес # 0 ТО
          размер:=НайтиЗнак0(адрес)+1
        КОН;
        GlobalUnlock(ссылка)
      КОН;
      CloseClipboard()
    КОН
  КОН;
  ВОЗВРАТ размер
КОН РазмерЦепочкиОбменника;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЦепочкуИзОбменника-(цепь+:ЦЕПЬ);
ПЕР
  размер,ссылка,адрес:ЦЕЛ;
УКАЗ
  ЕСЛИ IsClipboardFormatAvailable(13) ТО
    ЕСЛИ OpenClipboard(0) ТО
      ссылка:=GetClipboardData(13);
      ЕСЛИ ссылка # 0 ТО
        адрес:=GlobalLock(ссылка);
        ЕСЛИ адрес # 0 ТО
          размер:=НайтиЗнак0(адрес)+1;
          ЕСЛИ размер > РАЗМЕР(цепь) ТО
            размер:=РАЗМЕР(цепь)
          КОН;
          ОБХОД.Образ(адрес,ОБХОД.ПолучитьАдрес(цепь),размер*2)
        КОН;
        GlobalUnlock(ссылка)
      КОН;
      CloseClipboard()
    КОН
  КОН
КОН ЦепочкуИзОбменника;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЧитатьИзПерОкружения-(имя-,значение+:ЦЕПЬ);
ПЕР
       цОтвет:ЦЕЛ;
УКАЗ
       цОтвет:=GetEnvironmentVariable(имя,значение,РАЗМЕР(значение));
  ЕСЛИ
       цОтвет = 0
  ТО
    значение[0]:=0X
  КОН
КОН ЧитатьИзПерОкружения;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПисатьВПерОкружения-(имя-,значение-:ЦЕПЬ);
УКАЗ
     SetEnvironmentVariable(имя, значение)

КОН ПисатьВПерОкружения;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Вызов-(комСтрока-:ЦЕПЬ);
(*
 * Цель:  отработка команды ОС без завершения оболочки ОС
 * До:       <комСтрока> - отрабатываемая командная строка
 *)
ПЕР
  si:STARTUPINFO;
  pi:PROCESS_INFORMATION;
  команда:ЦЕПЬ[300];
  цОтвет:ЦЕЛ;
УКАЗ
  ОБНУЛИТЬ(si);
  si.cb:=44H;
  ОБНУЛИТЬ(pi);
                                            (* найдем командный обработчик ОС *)
  ОС.ЧитатьИзПерОкружения("COMSPEC",команда);
                                                   (* работаем без завершения *)
  оЦепи.ДобавитьВКонец(команда," /k ");
  оЦепи.ДобавитьВКонец(команда,комСтрока);
                             (* вызов задачи-функции возвращающей целый ответ *)
  цОтвет:=CreateProcess(0,команда,0,0,0,10H,0,0,si,pi);
КОН Вызов;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВызовВФайл-(комСтрока-,имяФ-:ЦЕПЬ);
(*
 * Цель: отработка команды ОС с сохранением вывода в текстовый файл 
 *        и завершением оболочки ОС
 * До:   <комСтрока> - отрабатываемая командная строка
 *       <имяФ>      - имя выходного текстового файла
 *)
ПЕР
  sa:SECURITY_ATTRIBUTES;
  si:STARTUPINFO;
  pi:PROCESS_INFORMATION;
  команда:ЦЕПЬ[300];
(*цОтвет,*)
  фссылка:ЦЕЛ;
УКАЗ
                                          (* найдем командный обработчик ОС *)
  ОС.ЧитатьИзПерОкружения("COMSPEC",команда);
                                          (* работаем с завершением *)
 оЦепи.ДобавитьВКонец(команда," /c ");
 оЦепи.ДобавитьВКонец(команда,комСтрока);
                                          (* SECURITY_ATTRIBUTES *)
  sa.nLength:=12; (* размер *)
  sa.lpSecurityDescriptor:=0;
  sa.bInheritHandle:=1; (* да *)
                                          (* фссылка должна наследоваться *)

       фссылка:=CreateFile(имяФ,40000000H,1,ОБХОД.ПолучитьАдрес(sa),2,8000000H,0);
  ЕСЛИ
       фссылка # -1
  ТО
    ОБНУЛИТЬ(si);
    si.cb:=44H;
    si.dwFlags:=100H;
    si.hStdInput:=ОС.ссылкаНаВвод;
    si.hStdOutput:=фссылка;
    si.hStdError:=фссылка;
    ОБНУЛИТЬ(pi);
                             (* вызов задачи-функции возвращающей целый ответ *)
    ЕСЛИ
         CreateProcess(0,команда,0,0,1,8000000H,0,0,si,pi) # 0
    ТО 
                                                (* команда начала свою работу *)
      WaitForSingleObject(pi.hProcess,-1);
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess)
    КОН;
    CloseHandle(фссылка)
  КОН
КОН ВызовВФайл;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВинЗнакВКодКлавиши-(знак:ЗНАК):ЦЕЛ;
(*
 * Цель:  перевод знака в код соответствующей клавиши
 *)
ПЕР
    раскладка:ЦЕЛ;
УКАЗ
  ЕСЛИ
       оБуквы.Русская(знак)
  ТО
    раскладка:=русРаскладка
  ИНАЧЕ
    раскладка:=латРаскладка
  КОН;
  ВОЗВРАТ VkKeyScanEx(знак,раскладка) ОСТАТОК 100H
КОН ВинЗнакВКодКлавиши;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       АдресЗадачи-(ссылка:ЦЕЛ; имя-:ЦЕПЬ):ЦЕЛ;
(*
 * Возвращает адрес задачи из связанной по ссылке <ссылка> ДПБ,
 * имя которой <имя>.
 *)
ПЕР
                уимя:РЯД 100 ИЗ ЯЧЦЕЛ;
УКАЗ
 оЦепи.ВВин(имя,уимя);
  ВОЗВРАТ GetProcAddress(ссылка,ОБХОД.ПолучитьАдрес(уимя))
КОН АдресЗадачи; 

(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
  ОС.ссылкаНаВвод :=GetStdHandle(-10);
  ОС.ссылкаНаВывод:=GetStdHandle(-11);
      ссылкаНаСтог:=GetProcessHeap();
                                    (* считываем русскую раскладку клавиатуры *)
  русРаскладка:=LoadKeyboardLayout("00000419",0);
  латРаскладка:=LoadKeyboardLayout("00000409",0)
КОН ОС.
