|
(*~\Глагол\Отделы\Обмен~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**) ОТДЕЛ КОС;
(*============================================================================*
* НАЗНАЧЕНИЕ: взаимодействие с Консольной Оконной Системой
*============================================================================*)
ИСПОЛЬЗУЕТ
ОБХОД,
ЦвЗнак,
ОС,
Ввод;
ВИД
(* посылки от ОС Win32 *)
ОтКлавиш=НАБОР
вид :ОБХОД.Цел16;
прозапас :ОБХОД.Цел16;
нажато- :ЦЕЛ;
повтор- :ОБХОД.Цел16;
код- :ОБХОД.Цел16;
мкод- :ОБХОД.Цел16;
знак- :ЗНАК;
упрКнопки-:МНОЖ;
КОН;
ОтМышки=НАБОР
вид :ОБХОД.Цел16;
прозапас :ОБХОД.Цел16;
к- :ОБХОД.Цел16;
с- :ОБХОД.Цел16;
кнопки- :МНОЖ;
упрКнопки-:МНОЖ;
события- :МНОЖ;
КОН;
TIMERPROC=ЗАДАЧА*(uID,uMsg,dwUser,dw1,dw2:ЦЕЛ);
(* прямоугольная область экрана *)
Область=НАБОР
лк:ОБХОД.Цел16; (* левая колонка *)
вс:ОБХОД.Цел16; (* верхняя строка *)
пк:ОБХОД.Цел16; (* правая колонка *)
нс:ОБХОД.Цел16; (* нижняя строка *)
КОН;
(* состояние указки *)
СостояниеУказки=НАБОР
размер,видимость:ЦЕЛ
КОН;
(******************************************************************************
* Задача выполняющаяся по времени
******************************************************************************)
ВИД
ВидЗадачиЧасы-=ЗАДАЧА(номер:ЦЕЛ);
ПЕР
ЗадачаЧасы:ВидЗадачиЧасы;
(* используемые Win задачи *)
ЗАДАЧА SetConsoleMode(
hConsoleHandle,
dwMode:ЦЕЛ); ВЫЗОВ "SetConsoleMode" ИЗ "kernel32.dll";
ЗАДАЧА GetNumberOfConsoleInputEvents(
hConsoleInput,
lpNumberOfEvents+:ЦЕЛ); ВЫЗОВ "GetNumberOfConsoleInputEvents" ИЗ "kernel32.dll";
ЗАДАЧА ReadConsoleInput(
hConsoleInput:ЦЕЛ;
lpBuffer+:ОтМышки;
nLength,
lpNumberOfEventsRead+:ЦЕЛ); ВЫЗОВ "ReadConsoleInputW" ИЗ "kernel32.dll";
ЗАДАЧА WaitForSingleObject(
hHandle,
dwMilliseconds:ЦЕЛ); ВЫЗОВ "WaitForSingleObject" ИЗ "kernel32.dll";
ЗАДАЧА ReadConsoleOutputCharacter(
hConsoleOutput:ЦЕЛ;
lpCharacter+:ЗНАК;
nLength,
dwReadCoord,
lpNumberOfCharsRead+:ЦЕЛ); ВЫЗОВ "ReadConsoleOutputCharacterW" ИЗ "kernel32.dll";
ЗАДАЧА WriteConsoleOutputCharacter(
hConsoleOutput:ЦЕЛ;
lpCharacter+:ЗНАК;
nLength,
dwWriteCoord,
lpNumberOfCharsWritten+:ЦЕЛ); ВЫЗОВ "WriteConsoleOutputCharacterW" ИЗ "kernel32.dll";
ЗАДАЧА ReadConsoleOutputAttribute(
hConsoleOutput:ЦЕЛ;
lpAttribute+:ЗНАК;
nLength,
dwReadCoord,
lpNumberOfAttrsRead+:ЦЕЛ); ВЫЗОВ "ReadConsoleOutputAttribute" ИЗ "kernel32.dll";
ЗАДАЧА WriteConsoleOutputAttribute(
hConsoleOutput:ЦЕЛ;
lpAttribute+:ЗНАК;
nLength,
dwWriteCoord,
lpNumberOfAttrsWritten+:ЦЕЛ); ВЫЗОВ "WriteConsoleOutputAttribute" ИЗ "kernel32.dll";
ЗАДАЧА WriteConsoleOutput(
hConsoleOutput:ЦЕЛ;
lpBuffer-:ЦвЗнак.Строка;
dwBufferSize,
dwBufferCoord:ЦЕЛ;
lpWriteRegion-:Область); ВЫЗОВ "WriteConsoleOutputW" ИЗ "kernel32.dll";
ЗАДАЧА SetConsoleCursorPosition(
hConsoleOutput,
dwCursorPosition:ЦЕЛ); ВЫЗОВ "SetConsoleCursorPosition" ИЗ "kernel32.dll";
ЗАДАЧА SetConsoleCursorInfo(hConsoleOutput:ЦЕЛ;
lpConsoleCursorInfo+:СостояниеУказки); ВЫЗОВ "SetConsoleCursorInfo" ИЗ "kernel32.dll";
ЗАДАЧА ScrollConsoleScreenBuffer(
hConsoleOutput:ЦЕЛ;
lpScrollRectangle+,
lpClipRectangle+:Область;
dwDestinationOrigin:ЦЕЛ;
lpFill-:ЦвЗнак.Вид); ВЫЗОВ "ScrollConsoleScreenBufferW" ИЗ "kernel32.dll";
ЗАДАЧА GetLargestConsoleWindowSize(
hConsoleOutput:ЦЕЛ):ЦЕЛ; ВЫЗОВ "GetLargestConsoleWindowSize" ИЗ "kernel32.dll";
ЗАДАЧА SetConsoleScreenBufferSize(
hConsoleOutput,dwSize:ЦЕЛ); ВЫЗОВ "SetConsoleScreenBufferSize" ИЗ "kernel32.dll";
ЗАДАЧА SetConsoleWindowInfo(
hConsoleOutput,
bAbsolute:ЦЕЛ;
lpConsoleWindow-:Область); ВЫЗОВ "SetConsoleWindowInfo" ИЗ "kernel32.dll";
ЗАДАЧА timeSetEvent(
uDelay,
uResolution:ЦЕЛ;
lpTimerProc:TIMERPROC;
dwUser,
fuEvent:ЦЕЛ):ЦЕЛ; ВЫЗОВ "timeSetEvent" ИЗ "winmm.dll";
ЗАДАЧА timeKillEvent(uTimerID:ЦЕЛ); ВЫЗОВ "timeKillEvent" ИЗ "winmm.dll";
(******************************************************************************)
ЗАДАЧА* Часы(uID,uMsg,dwUser,dw1,dw2:ЦЕЛ);
УКАЗ
ЕСЛИ ЗадачаЧасы # ПУСТО ТО
ЗадачаЧасы(dwUser)
КОН
КОН Часы;
(******************************************************************************)
ЗАДАЧА Подготовить-(задачаЧасы:ВидЗадачиЧасы);
УКАЗ
ЗадачаЧасы:=задачаЧасы
КОН Подготовить;
(******************************************************************************)
ЗАДАЧА Отработать-;
(* заглушка для совместимости с ГОС *)
УКАЗ
КОН Отработать;
(******************************************************************************)
ЗАДАЧА ПоказатьОкно-;
(* заглушка для совместимости с ГОС *)
УКАЗ
КОН ПоказатьОкно;
(******************************************************************************)
ЗАДАЧА СоздатьЧасы-(номер,время:ЦЕЛ):ЦЕЛ;
(* Цель: добавляет новые, или заменяет старые часы
* До: <номер> - опознавательный номер часов
* <время> - время повторения срабатывания данных часов в мс *)
УКАЗ
ВОЗВРАТ timeSetEvent(время,время,Часы,номер,1)
КОН СоздатьЧасы;
(******************************************************************************)
ЗАДАЧА УдалитьЧасы-(часы:ЦЕЛ);
УКАЗ
timeKillEvent(часы)
КОН УдалитьЧасы;
(******************************************************************************)
ЗАДАЧА РазмерЭкрана-(строк+,колонок+:ЦЕЛ);
(* Цель: возвращает размер экрана *)
ПЕР
ск:ЦЕЛ;
УКАЗ
ск:=GetLargestConsoleWindowSize(ОС.ссылкаНаВывод);
строк:=ск ДЕЛИТЬ 10000H;
колонок:=ск ОСТАТОК 10000H
КОН РазмерЭкрана;
(******************************************************************************)
ЗАДАЧА ИзменитьРазмерОкна-(строк,колонок:ЦЕЛ);
(* Цель: изменить размер окна приложения *)
ПЕР
область:Область;
ск:ЦЕЛ;
УКАЗ
(* подготовим рабочую область для увеличения окна *)
ск:=строк*10000H+колонок;
SetConsoleScreenBufferSize(ОС.ссылкаНаВывод,ск);
(* изменение видимой области *)
область.вс:=0;
область.нс:=УЗК(строк-1);
область.лк:=0;
область.пк:=УЗК(колонок-1);
SetConsoleWindowInfo(ОС.ссылкаНаВывод,1,область);
(* поправим рабочую область при уменьшении окна *)
SetConsoleScreenBufferSize(ОС.ссылкаНаВывод,ск)
КОН ИзменитьРазмерОкна;
(******************************************************************************)
ЗАДАЧА Опрос-(отКлавиш+:Ввод.ОтКлавиш; отМышки+:Ввод.ОтМышки):ЦЕЛ;
ПЕР
откуда,посылок:ЦЕЛ;
ОСотМышки:ОтМышки;
ОСотКлавиш:ОтКлавиш;
УКАЗ
WaitForSingleObject(ОС.ссылкаНаВвод,-1);
GetNumberOfConsoleInputEvents(ОС.ссылкаНаВвод,посылок);
(* наверное, это посылка от мышки *)
ReadConsoleInput(ОС.ссылкаНаВвод,ОСотМышки,1,посылок);
откуда:=ОСотМышки.вид;
ЕСЛИ откуда = Ввод.клавиши ТО (* нет, не от мышки *)
ОБХОД.Образ(ОБХОД.ПолучитьАдрес(ОСотМышки),ОБХОД.ПолучитьАдрес(ОСотКлавиш),20);
(* ждём отпускания клавиши *)
ЕСЛИ ОСотКлавиш.нажато = 0 ТО
ВОЗВРАТ Ввод.пустой
КОН;
ЕСЛИ (ОСотКлавиш.код = 10H) (* просто шифт *)
ИЛИ (ОСотКлавиш.код = 11H) (* просто контр *)
ИЛИ (ОСотКлавиш.код = 12H) ТО (* просто альт *)
ВОЗВРАТ Ввод.пустой
КОН;
отКлавиш.код:=ОСотКлавиш.код;
отКлавиш.мкод:=ОСотКлавиш.мкод;
отКлавиш.знак:=ОСотКлавиш.знак;
отКлавиш.упрКнопки:=ОСотКлавиш.упрКнопки;
отКлавиш.упрШифт:=Ввод.шифт В ОСотКлавиш.упрКнопки;
отКлавиш.упрКонтр:={Ввод.лКонтр,Ввод.пКонтр}*ОСотКлавиш.упрКнопки # {};
отКлавиш.упрАльт:={Ввод.лАльт,Ввод.пАльт}*ОСотКлавиш.упрКнопки # {}
АЕСЛИ откуда = Ввод.мышка ТО
ЕСЛИ Ввод.смещение В ОСотМышки.события ТО
ВОЗВРАТ Ввод.пустой
КОН;
отМышки.к:=ОСотМышки.к;
отМышки.с:=ОСотМышки.с;
отМышки.кнопки:=ОСотМышки.кнопки;
отМышки.упрКнопки:=ОСотМышки.упрКнопки;
отМышки.события:=ОСотМышки.события;
ЕСЛИ Ввод.прокрут В ОСотМышки.события ТО
отМышки.прокрут:=ОБХОД.Значение(ЦЕЛ,отМышки.кнопки) ДЕЛИТЬ (10000H*120)
ИНАЧЕ
отМышки.прокрут:=0
КОН;
отМышки.отработана:=ОТКЛ
ИНАЧЕ
откуда:=Ввод.пустой
КОН;
ВОЗВРАТ откуда
КОН Опрос;
(******************************************************************************)
ЗАДАЧА ПереместитьУказку-(с,к:ЦЕЛ);
УКАЗ
SetConsoleCursorPosition(ОС.ссылкаНаВывод,с*10000H+к)
КОН ПереместитьУказку;
(******************************************************************************)
ЗАДАЧА РазмерУказки-(размер:ЦЕЛ);
(* <размер> указывается в процентах,
* при <размер> = 0 указка убирается с экрана *)
ПЕР
состояние:СостояниеУказки;
УКАЗ
ЕСЛИ размер = 0 ТО
состояние.видимость:=0;
состояние.размер:=1
ИНАЧЕ
состояние.видимость:=1;
состояние.размер:=размер
КОН;
SetConsoleCursorInfo(ОС.ссылкаНаВывод,состояние)
КОН РазмерУказки;
(******************************************************************************)
ЗАДАЧА ПисатьЗнак-(с,к:ЦЕЛ; зн:ЗНАК);
ПЕР
отработано:ЦЕЛ;
УКАЗ
WriteConsoleOutputCharacter(ОС.ссылкаНаВывод,зн,1,с*10000H+к,отработано)
КОН ПисатьЗнак;
(******************************************************************************)
ЗАДАЧА ЧитатьЗнак-(с,к:ЦЕЛ):ЗНАК;
ПЕР
отработано:ЦЕЛ;
зн:ЗНАК;
УКАЗ
ReadConsoleOutputCharacter(ОС.ссылкаНаВывод,зн,1,с*10000H+к,отработано);
ВОЗВРАТ зн
КОН ЧитатьЗнак;
(******************************************************************************)
ЗАДАЧА ПисатьЦвет-(с,к:ЦЕЛ; цв:ЗНАК);
ПЕР
отработано:ЦЕЛ;
УКАЗ
WriteConsoleOutputAttribute(ОС.ссылкаНаВывод,цв,1,с*10000H+к,отработано);
КОН ПисатьЦвет;
(******************************************************************************)
ЗАДАЧА ЧитатьЦвет-(с,к:ЦЕЛ):ЗНАК;
ПЕР
отработано:ЦЕЛ;
цв:ЗНАК;
УКАЗ
ReadConsoleOutputAttribute(ОС.ссылкаНаВывод,цв,1,с*10000H+к,отработано);
ВОЗВРАТ цв
КОН ЧитатьЦвет;
(******************************************************************************)
ЗАДАЧА Вверх-(вс,лк,нс,пк:ЦЕЛ; новЗнак-:ЦвЗнак.Вид);
(* Цель: сдвиг содержимого заданной области вверх
* До: <вс>,<лк>,<нс>,<пк> - границы области на окне
* <новЗнак> - знак для заполнения освободившегося места *)
ПЕР
область:Область;
УКАЗ
область.лк:=УЗК(лк);
область.вс:=УЗК(вс);
область.пк:=УЗК(пк);
область.нс:=УЗК(нс);
ScrollConsoleScreenBuffer(ОС.ссылкаНаВывод,область,область,(вс-1)*10000H+лк,новЗнак)
КОН Вверх;
(******************************************************************************)
ЗАДАЧА Вниз-(вс,лк,нс,пк:ЦЕЛ; новЗнак-:ЦвЗнак.Вид);
(* Цель: сдвиг содержимого данной области вниз
* До: <вс>,<лк>,<нс>,<пк> - границы области на окне
* <новЗнак> - знак для заполнения освободившегося места *)
ПЕР
область:Область;
УКАЗ
область.лк:=УЗК(лк);
область.вс:=УЗК(вс);
область.пк:=УЗК(пк);
область.нс:=УЗК(нс);
ScrollConsoleScreenBuffer(ОС.ссылкаНаВывод,область,область,(вс+1)*10000H+лк,новЗнак)
КОН Вниз;
(******************************************************************************)
ЗАДАЧА ПисатьСтроку-(цвСтрока-:ЦвЗнак.Строка; с,к,длина:ЦЕЛ);
(* Цель: отрисовка содержимого строки
* До: <с>,<к> - начало строки на экране
* <длина> - длина строки *)
(******************************************************************************)
ПЕР
область:Область;
УКАЗ
область.лк:=УЗК(к);
область.вс:=УЗК(с);
область.пк:=УЗК(к+длина-1);
область.нс:=УЗК(с);
WriteConsoleOutput(ОС.ссылкаНаВывод,цвСтрока,1*10000H+РАЗМЕР(цвСтрока),0,область)
КОН ПисатьСтроку;
(******************************************************************************)
УКАЗ
(* подключаем мышку *)
SetConsoleMode(ОС.ссылкаНаВвод,10H)
КОН КОС.
|
|