(*~\Глагол\Отделы\Обмен\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                            ОТДЕЛ ГОС;
(*============================================================================*)
(* НАЗНАЧЕНИЕ: взаимодействие с Графической Оконной Системой (ГОС)            *)
(*============================================================================*)

ИСПОЛЬЗУЕТ 
  ОБХОД,
  ОС,
  ЦвЗнак,
  Ввод;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
 * Взаимодействие с ОС
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ВИД
    WNDPROC = ЗАДАЧА*(_para1,_para2,_para3,_para4:ЦЕЛ):ЦЕЛ;
  TIMERPROC = ЗАДАЧА*(hWnd,uMsg,uIDEvent,dwTime:ЦЕЛ);

  POINT = НАБОР
    x,y:ЦЕЛ;
  КОН;

  SIZE = НАБОР
    x,y:ЦЕЛ
  КОН;

  RECT = НАБОР
    Left,Top,Right,Bottom:ЦЕЛ;
  КОН;

  MSG = НАБОР
    hWnd   :ЦЕЛ;
    message:ЦЕЛ;
    wParam :ЦЕЛ;
    lParam :ЦЕЛ;
    time   :ЦЕЛ;
    pt     :POINT;
  КОН;

  PAINTSTRUCT = НАБОР
    hdc        :ЦЕЛ;
    fErase     :ЦЕЛ;
    rcPaint    :RECT;
    fRestore   :ЦЕЛ;
    fIncUpdate :ЦЕЛ;
    rgbReserved:РЯД 32 ИЗ ЯЧЦЕЛ;
  КОН;
  WNDCLASS = НАБОР
    style        :ЦЕЛ;
    lpfnWndProc  :WNDPROC;
    cbClsExtra   :ЦЕЛ;
    cbWndExtra   :ЦЕЛ;
    hInstance    :ЦЕЛ;
    hIcon        :ЦЕЛ;
    hCursor      :ЦЕЛ;
    hbrBackground:ЦЕЛ;
    lpszMenuName :ЦЕЛ;
    lpszClassName:ЦЕЛ;
  КОН;
  LOGFONT = НАБОР
    lfHeight        :ЦЕЛ;
    lfWidth         :ЦЕЛ;
    lfEscapement    :ЦЕЛ;
    lfOrientation   :ЦЕЛ;
    lfWeight        :ЦЕЛ;
    lfItalic        :ЯЧЦЕЛ;
    lfUnderline     :ЯЧЦЕЛ;
    lfStrikeOut     :ЯЧЦЕЛ;
    lfCharSet       :ЯЧЦЕЛ;
    lfOutPrecision  :ЯЧЦЕЛ;
    lfClipPrecision :ЯЧЦЕЛ;
    lfQuality       :ЯЧЦЕЛ;
    lfPitchAndFamily:ЯЧЦЕЛ;
    lfFaceName      :ЦЕПЬ[32];
  КОН;
  MINMAXINFO = НАБОР
    ptReserved:POINT;
    ptMaxSize:POINT;
    ptMaxPosition:POINT;
    ptMinTrackSize:POINT;
    ptMaxTrackSize:POINT;
  КОН;
  СостояниеКлавиш = РЯД 256 ИЗ ЯЧЦЕЛ;

ПОСТ
  WM_CREATE           = 1;
  WM_DESTROY          = 2;
  WM_SETFOCUS         = 7;
  WM_KILLFOCUS        = 8;
  WM_PAINT            = 15;
  WM_ERASEBKGND       = 20;
  WM_GETMINMAXINFO    = 36;
  WM_KEYDOWN          = 256;
  WM_SYSKEYDOWN       = 260;
  WM_TIMER            = 275;
  WM_LBUTTONDBLCLK    = 515;
  WM_LBUTTONDOWN      = 513;
  WM_LBUTTONUP        = 514;
  WM_RBUTTONDBLCLK    = 518;
  WM_RBUTTONDOWN      = 516;
  WM_RBUTTONUP        = 517;
  WM_MBUTTONDBLCLK    = 521;
  WM_MBUTTONDOWN      = 519;
  WM_MBUTTONUP        = 520;
  WM_MOUSEWHEEL       = 522;
  PM_REMOVE           = 1;
  SWP_NOMOVE          = 2;
  CS_VREDRAW          = 1;
  CS_HREDRAW          = 2;
  IDC_ARROW           = 32512; 
  IDI_APPLICATION     = 32512;
  WS_OVERLAPPEDWINDOW = 0CF0000H;
  CW_USEDEFAULT       = МИН(ЦЕЛ);
  SW_SHOWDEFAULT      = 1;
  FIXED_PITCH         = 1;
  HORZRES             = 8;
  VERTRES             = 10;
  VK_RMENU            = 165;
  VK_LMENU            = 164;
  VK_RCONTROL         = 163;
  VK_LCONTROL         = 162;
  VK_RSHIFT           = 161;
  VK_LSHIFT           = 160;
  VK_NUMLOCK          = 144;
  VK_SCROLL           = 145;
  VK_CAPITAL          = 20;
  ETO_OPAQUE          = 2;
  ETO_CLIPPED         = 4;
  TA_CENTER           = 6;

ПЕР
  hInstance:ЦЕЛ;
  hWnd:ЦЕЛ;
  hfont:ЦЕЛ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
 * Посылки от окна
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ПЕР
  естьОчередь:КЛЮЧ;
  родПосылки:ЦЕЛ;
  отКлавиш:Ввод.нОтКлавиш;
  отМышки :Ввод.нОтМышки;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
 * Знаки на экране
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ВИД  
                              (* местоположение точки или размер области *)
  нТочка- = НАБОР
    к+,           (* к = колонка *)
    с+:ЦЕЛ        (* с = строка  *)
  КОН;

ПЕР
  окно+:ДОСТУП К РЯД ИЗ РЯД ИЗ ЦвЗнак.Вид; (* наибольшего размера *)

  КЗСцвета:РЯД 16 ИЗ ЦЕЛ;     (* красно-зелёно-синий состав цвета *)
  указка:ГОС.нТочка;          (* местоположение                   *)
  размерУказки:ЦЕЛ;           (* высота, точек                    *)
  размерОкна:POINT;           (* точек                            *)
  размерЗнака:SIZE;           (* точек                            *)
  полуширинаЗнака:ЦЕЛ;        (* точек                            *)
  размерЭкрана:ГОС.нТочка;    (* по границе экрана                *)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
 *                         Задача выполняющаяся по времени
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ВИД  
                  зЧасы- = ЗАДАЧА(номер:ЦЕЛ);
ПЕР
  Задача_Часы:ГОС.зЧасы;                             (* локальная для ГОС.отд *)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
 * Задачи ОС
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА GetModuleHandle(lpModuleName:ЦЕЛ):ЦЕЛ;            ВЫЗОВ "GetModuleHandleW"        ИЗ "kernel32.dll";
ЗАДАЧА CreateWindowEx(dwExStyle:ЦЕЛ; lpClassName-,lpWindowName-:ЦЕПЬ; dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam:ЦЕЛ):ЦЕЛ; ВЫЗОВ "CreateWindowExW" ИЗ "user32.dll";
ЗАДАЧА GetMessage(lpMsg+:MSG; hWnd,wMsgFilterMin,wMsgFilterMax:ЦЕЛ); ВЫЗОВ "GetMessageW" ИЗ "user32.dll";
ЗАДАЧА PeekMessage(lpMsg+:MSG; hWnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg:ЦЕЛ):ЦЕЛ; ВЫЗОВ "PeekMessageW" ИЗ "user32.dll";
ЗАДАЧА DispatchMessage(lpMsg+:MSG);                      ВЫЗОВ "DispatchMessageW"        ИЗ "user32.dll";
ЗАДАЧА BeginPaint(hWnd:ЦЕЛ; lpPaint+:PAINTSTRUCT):ЦЕЛ;   ВЫЗОВ "BeginPaint"              ИЗ "user32.dll";
ЗАДАЧА EndPaint(hWnd:ЦЕЛ; lpPaint+:PAINTSTRUCT);         ВЫЗОВ "EndPaint"                ИЗ "user32.dll";
ЗАДАЧА GetClientRect(hWnd:ЦЕЛ; lpRect+:RECT);            ВЫЗОВ "GetClientRect"           ИЗ "user32.dll";
ЗАДАЧА InvalidateRect(hWnd:ЦЕЛ; lpRect-:RECT; bErase:ЦЕЛ); ВЫЗОВ "InvalidateRect"        ИЗ "user32.dll";
ЗАДАЧА DefWindowProc(hWnd,Msg,wParam,lParam:ЦЕЛ):ЦЕЛ;    ВЫЗОВ "DefWindowProcW"          ИЗ "user32.dll";
ЗАДАЧА LoadIcon(hInstance,lpIconName:ЦЕЛ):ЦЕЛ;           ВЫЗОВ "LoadIconW"               ИЗ "user32.dll";
ЗАДАЧА LoadCursor(hInstance:ЦЕЛ; lpCursorName:ЦЕЛ):ЦЕЛ;  ВЫЗОВ "LoadCursorW"             ИЗ "user32.dll";
ЗАДАЧА RegisterClass(lpWndClass+:WNDCLASS);              ВЫЗОВ "RegisterClassW"          ИЗ "user32.dll";
ЗАДАЧА ShowWindow(hWnd,nCmdShow:ЦЕЛ);                    ВЫЗОВ "ShowWindow"              ИЗ "user32.dll";
ЗАДАЧА GetDC(hWnd:ЦЕЛ):ЦЕЛ;                              ВЫЗОВ "GetDC"                   ИЗ "user32.dll";
ЗАДАЧА ReleaseDC(hWnd,hdc:ЦЕЛ);                          ВЫЗОВ "ReleaseDC"               ИЗ "user32.dll";
ЗАДАЧА CreateCaret(hWnd,hBitmap,nWidth,nHeight:ЦЕЛ);     ВЫЗОВ "CreateCaret"             ИЗ "user32.dll";
ЗАДАЧА SetCaretPos(X,Y:ЦЕЛ);                             ВЫЗОВ "SetCaretPos"             ИЗ "user32.dll";
ЗАДАЧА ShowCaret(hWnd:ЦЕЛ);                              ВЫЗОВ "ShowCaret"               ИЗ "user32.dll";
ЗАДАЧА DestroyCaret();                                   ВЫЗОВ "DestroyCaret"            ИЗ "user32.dll";
ЗАДАЧА AdjustWindowRect(lpRect+:RECT;dwStyle,bMenu:ЦЕЛ); ВЫЗОВ "AdjustWindowRect"        ИЗ "user32.dll";
ЗАДАЧА SetWindowPos(hWnd,hWndIA,X,Y,cx,cy,uFlags:ЦЕЛ);   ВЫЗОВ "SetWindowPos"            ИЗ "user32.dll";
ЗАДАЧА GetKeyboardState(состояние+:СостояниеКлавиш);     ВЫЗОВ "GetKeyboardState"        ИЗ "user32.dll";
ЗАДАЧА ToUnicode(wVirtKey,wScanCode:ЦЕЛ; состояние+:СостояниеКлавиш; знак+:ЗНАК; cchBuff,wFlags:ЦЕЛ); ВЫЗОВ "ToUnicode" ИЗ "user32.dll";
ЗАДАЧА SetTimer(окно,номер,время:ЦЕЛ; задача:TIMERPROC):ЦЕЛ; ВЫЗОВ "SetTimer"            ИЗ "user32.dll";
ЗАДАЧА KillTimer(окно,номер:ЦЕЛ);                        ВЫЗОВ "KillTimer"               ИЗ "user32.dll";

ЗАДАЧА ExtTextOut(hdc,x,y,fuOptions:ЦЕЛ; lprc+:RECT; lpString+:ЗНАК; cbCount,lpDx:ЦЕЛ); ВЫЗОВ "ExtTextOutW" ИЗ "gdi32.dll";
ЗАДАЧА GetTextExtentPoint32(hdc:ЦЕЛ; lpString-:ЦЕПЬ; chars:ЦЕЛ; lpSize+:SIZE); ВЫЗОВ "GetTextExtentPoint32W" ИЗ "gdi32.dll";
ЗАДАЧА SelectObject(hdc,hgdiobj:ЦЕЛ);                    ВЫЗОВ "SelectObject"            ИЗ "gdi32.dll";
ЗАДАЧА CreateFontIndirect(lplf-:LOGFONT):ЦЕЛ;            ВЫЗОВ "CreateFontIndirectW"     ИЗ "gdi32.dll";
ЗАДАЧА DeleteObject(hObject:ЦЕЛ);                        ВЫЗОВ "DeleteObject"            ИЗ "gdi32.dll";
ЗАДАЧА GetDeviceCaps(hdc,nIndex:ЦЕЛ):ЦЕЛ;                ВЫЗОВ "GetDeviceCaps"           ИЗ "gdi32.dll";
ЗАДАЧА SetTextColor(hdc,crColor:ЦЕЛ);                    ВЫЗОВ "SetTextColor"            ИЗ "gdi32.dll";
ЗАДАЧА SetBkColor(hdc,crColor:ЦЕЛ);                      ВЫЗОВ "SetBkColor"              ИЗ "gdi32.dll";
ЗАДАЧА SetTextAlign(_para1,para2:ЦЕЛ);                   ВЫЗОВ "SetTextAlign"            ИЗ "gdi32.dll";

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
 * Знаки на экране
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СоздатьУказку;
УКАЗ
  ЕСЛИ 
        размерУказки > 0
  ТО
    CreateCaret(hWnd,0,размерЗнака.x-1,размерУказки);
    SetCaretPos(указка.к*размерЗнака.x,(указка.с+1)*размерЗнака.y-размерУказки);
    ShowCaret(hWnd)
  КОН;
КОН СоздатьУказку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА УдалитьУказку;
УКАЗ
  ЕСЛИ
        размерУказки > 0
  ТО
    DestroyCaret
  КОН
КОН УдалитьУказку;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Запятнать(вс,лк,нс,пк:ЦЕЛ);
(*
 * Цель:  пометить данную область, как требующую перирисовки
 * До:    <вс>,<лк>,<нс>,<пк> - границы области
 *)
ПЕР
  rect:RECT;
УКАЗ
  rect.Left  :=лк*размерЗнака.x;
  rect.Top   :=вс*размерЗнака.y;
  rect.Right :=(пк+1)*размерЗнака.x;
  rect.Bottom:=(нс+1)*размерЗнака.y;
  InvalidateRect(hWnd,rect,0)
КОН Запятнать;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Отрисовка;
ПЕР
  ps:PAINTSTRUCT;
  hdc:ЦЕЛ;
  rect:RECT;
  нс,нк,с,к,пс,пк:ЦЕЛ; (* начальная, текущая, последняя строка и колонка  *)
  нx,нy:ЦЕЛ;           (* начальные координаты окна                       *)
  цвЗнак:ЦвЗнак.Вид;   (* текущий обрабатываемый знак                     *)
  цвет:ЗНАК;
УКАЗ
                                                  (* начинаем отрисовку *)
  hdc:=BeginPaint(hWnd,ps);
  SelectObject(hdc,hfont);
  SetTextAlign(hdc,TA_CENTER);

                                                  (* границы вывода *)
  нс:= ps.rcPaint.Top       ДЕЛИТЬ размерЗнака.y;
  пс:=(ps.rcPaint.Bottom-1) ДЕЛИТЬ размерЗнака.y;
  нк:= ps.rcPaint.Left      ДЕЛИТЬ размерЗнака.x;
  пк:=(ps.rcPaint.Right-1)  ДЕЛИТЬ размерЗнака.x;
  нy:=нс*размерЗнака.y;
  нx:=нк*размерЗнака.x;
  УВЕЛИЧИТЬ(пк); (* барьер *)
  цвет:=МАКС(ЗНАК);
                                                  (* пробегаем по всем знакам *)
  rect.Top:=нy;
  ОТ с:=нс ДО пс ВЫП
    rect.Left:=нx;
    ОТ к:=нк ДО пк ВЫП
      цвЗнак:=окно[с][к];
      ЕСЛИ цвЗнак.цвет # МАКС(ЗНАК) ТО
        ЕСЛИ цвЗнак.цвет # цвет ТО
          цвет:=цвЗнак.цвет;
          SetTextColor(hdc,КЗСцвета[ВЦЕЛ(цвЗнак.цвет) ОСТАТОК 10H]);
          SetBkColor  (hdc,КЗСцвета[ВЦЕЛ(цвЗнак.цвет) ДЕЛИТЬ  10H]);
        КОН;
        rect.Right:=rect.Left+размерЗнака.x;
        rect.Bottom:=rect.Top+размерЗнака.y;
        ExtTextOut(hdc,rect.Left+полуширинаЗнака,
                       rect.Top,
                       ETO_OPAQUE+ETO_CLIPPED,
                       rect,
                       цвЗнак.знак,1,0)
      КОН;
      УВЕЛИЧИТЬ(rect.Left,размерЗнака.x)
    КОН;
    УВЕЛИЧИТЬ(rect.Top,размерЗнака.y)
  КОН;
  (* заканчиваем отрисовку *)
  EndPaint(hWnd,ps)
КОН Отрисовка;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Клавиши(код,мкод:ЦЕЛ);
ПЕР 
  состояние:СостояниеКлавиш;
УКАЗ
  ЕСЛИ  (код = 10H)    (* просто шифт  *)
    ИЛИ (код = 11H)    (* просто контр *)
    ИЛИ (код = 12H)    (* просто альт  *)
  ТО
    ВОЗВРАТ
  КОН;
  отКлавиш.код:=код;
  отКлавиш.мкод:=мкод;
  отКлавиш.упрКнопки:={};
  отКлавиш.упрАльт :=ОТКЛ;
  отКлавиш.упрКонтр:=ОТКЛ;
  отКлавиш.упрШифт :=ОТКЛ;
 
    GetKeyboardState(состояние);
  ToUnicode(код,мкод,состояние,отКлавиш.знак,1,0);

  ЕСЛИ
       состояние[VK_RMENU] < 0
  ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.пАльт};
    отКлавиш.упрАльт:=ВКЛ
  КОН;
  ЕСЛИ состояние[VK_LMENU] < 0 ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.лАльт};
    отКлавиш.упрАльт:=ВКЛ
  КОН;
  ЕСЛИ состояние[VK_RCONTROL] < 0 ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.пКонтр};
    отКлавиш.упрКонтр:=ВКЛ
  КОН;
  ЕСЛИ состояние[VK_LCONTROL] < 0 ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.лКонтр};
    отКлавиш.упрКонтр:=ВКЛ
  КОН;
  ЕСЛИ (состояние[VK_RSHIFT] < 0) ИЛИ (состояние[VK_LSHIFT] < 0) ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.шифт};
    отКлавиш.упрШифт:=ВКЛ
  КОН;
  ЕСЛИ НЕ ЧЕТ(состояние[VK_NUMLOCK]) ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.нумЛок}
  КОН;
  ЕСЛИ НЕ ЧЕТ(состояние[VK_SCROLL]) ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.скролЛок}
  КОН;
  ЕСЛИ НЕ ЧЕТ(состояние[VK_CAPITAL]) ТО
    отКлавиш.упрКнопки:=отКлавиш.упрКнопки+{Ввод.капсЛок}
  КОН;
  родПосылки:=Ввод.клавиши
КОН Клавиши;

(*~======================================~общедоступная ЗАДАЧА~==============~*)
ЗАДАЧА*
        ОконнаяЗадача(
                             hWnd,
                          message,
                           wParam,
                           lParam :ЦЕЛ
                     ):ЦЕЛ;                               (* Вызывается из ОС *)
ВИД
  MINMAXINFOPTR=ДОСТУП К MINMAXINFO;
ПЕР
  mmi:MINMAXINFOPTR;

  ЗАДАЧА Мышка(кнопки,события:МНОЖ);
  УКАЗ
    отМышки.кнопки:=кнопки;
    отМышки.события:=события;
    отМышки.к:=(lParam ОСТАТОК 10000H) ДЕЛИТЬ размерЗнака.x;
    отМышки.с:=(lParam ДЕЛИТЬ  10000H) ДЕЛИТЬ размерЗнака.y;
    отМышки.упрКнопки:=ОБХОД.Значение(МНОЖ,wParam ОСТАТОК 10000H);
    отМышки.прокрут:=wParam ДЕЛИТЬ (10000H*120);
    отМышки.отработана:=ОТКЛ;
    родПосылки:=Ввод.мышка
  КОН Мышка;

УКАЗ
  ВЫБРАТЬ message ИЗ
  | WM_CREATE:     естьОчередь:=ВКЛ
  | WM_DESTROY:    естьОчередь:=ОТКЛ
  | WM_PAINT:      Отрисовка
  | WM_KEYDOWN,
    WM_SYSKEYDOWN: Клавиши(wParam,(lParam ДЕЛИТЬ 10000H) ОСТАТОК 100H)
  | WM_TIMER:      ЕСЛИ
                        Задача_Часы # ПУСТО
                   ТО
                        Задача_Часы(wParam)
                   КОН
  | WM_SETFOCUS:   СоздатьУказку
  | WM_KILLFOCUS:  УдалитьУказку
  | WM_ERASEBKGND: ВОЗВРАТ 1
  | WM_GETMINMAXINFO:
      mmi:=ОБХОД.Значение(MINMAXINFOPTR,lParam);
      mmi.ptMaxTrackSize:=размерОкна;
      mmi.ptMinTrackSize:=размерОкна;
  ИНАЧЕ (* большие номера message *)
    ВЫБРАТЬ message ИЗ
    | WM_LBUTTONDBLCLK: Мышка({  Ввод.левая},{Ввод.щелк2  })
    | WM_LBUTTONDOWN:   Мышка({  Ввод.левая},{            })
    | WM_RBUTTONDBLCLK: Мышка({ Ввод.правая},{Ввод.щелк2  })
    | WM_RBUTTONDOWN:   Мышка({ Ввод.правая},{            })
    | WM_MBUTTONDBLCLK: Мышка({Ввод.средняя},{Ввод.щелк2  })
    | WM_MBUTTONDOWN:   Мышка({Ввод.средняя},{            })
    | WM_MOUSEWHEEL:    Мышка({            },{Ввод.прокрут})
    | WM_LBUTTONUP,WM_RBUTTONUP,WM_MBUTTONUP:
                        Мышка({            },{            })
    ИНАЧЕ
      ВОЗВРАТ DefWindowProc(hWnd,message,wParam,lParam)
    КОН
  КОН;
  ВОЗВРАТ 0
КОН ОконнаяЗадача;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Подготовить-(
                    имяПриложения-,
                        имяШрифта-:ЦЕПЬ;
                     размерШрифта :ЦЕЛ;
                          задЧасы :ГОС.зЧасы
                   );
ПЕР
  hdc:ЦЕЛ;
  wndClass:WNDCLASS;
  logFont:LOGFONT;
УКАЗ
  hInstance:=GetModuleHandle(0);
  Задача_Часы:=задЧасы;
                              (* указка *)
  размерУказки:=0;
  указка.с:=0;
  указка.к:=0;
                              (* красно-зелёно-синий состав цвета *)
  КЗСцвета[ 0]:=0000000H;
  КЗСцвета[ 1]:=0900000H;
  КЗСцвета[ 2]:=0009000H;
  КЗСцвета[ 3]:=0909000H;
  КЗСцвета[ 4]:=0000090H;
  КЗСцвета[ 5]:=0900090H;
  КЗСцвета[ 6]:=0009090H;
  КЗСцвета[ 7]:=0C0C0C0H;
  КЗСцвета[ 8]:=0808080H;
  КЗСцвета[ 9]:=0FF0000H;
  КЗСцвета[10]:=000FF00H;
  КЗСцвета[11]:=0FFFF00H;
  КЗСцвета[12]:=00000FFH;
  КЗСцвета[13]:=0FF00FFH;
  КЗСцвета[14]:=000FFFFH;
  КЗСцвета[15]:=0FFFFFFH;
                              (* прописываем оконный класс *)
  wndClass.style:=CS_HREDRAW+CS_VREDRAW;
  wndClass.lpfnWndProc:=ОконнаяЗадача;
  wndClass.cbClsExtra:=0;
  wndClass.cbWndExtra:=0;
  wndClass.hInstance:=hInstance;
  wndClass.hIcon:=LoadIcon(0,IDI_APPLICATION);
  wndClass.hCursor:=LoadCursor(0,IDC_ARROW);
  wndClass.hbrBackground:=0;
  wndClass.lpszMenuName:=0;
  wndClass.lpszClassName:=ОБХОД.ПолучитьАдрес(имяПриложения);
  RegisterClass(wndClass);
                              (* создаём окно *)
  размерОкна.x:=200;
  размерОкна.y:=200;
  hWnd:=CreateWindowEx(0,имяПриложения,имяПриложения,WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hInstance,0);

                              (* подбор шрифта *)
  ОБНУЛИТЬ(logFont);
  logFont.lfPitchAndFamily:=FIXED_PITCH;
  logFont.lfHeight:=размерШрифта;       
  СПИСАТЬ(имяШрифта,logFont.lfFaceName);

                              (* размер знака и экрана *)
  hdc:=GetDC(hWnd);
  hfont:=CreateFontIndirect(logFont);
  SelectObject(hdc,hfont);
  GetTextExtentPoint32(hdc,"А",1,размерЗнака);
  полуширинаЗнака:=размерЗнака.x ДЕЛИТЬ 2;
  размерЭкрана.с:=(GetDeviceCaps(hdc,VERTRES)+размерЗнака.y-1) ДЕЛИТЬ размерЗнака.y;
  размерЭкрана.к:=(GetDeviceCaps(hdc,HORZRES)+размерЗнака.x-1) ДЕЛИТЬ размерЗнака.x;
  ReleaseDC(hWnd,hdc);
                              (* память для знаков и барьера *)
  СОЗДАТЬ(окно,размерЭкрана.с,размерЭкрана.к+1);
КОН Подготовить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Отработать-;     (* Цель: внутренняя отработка ОС накопившихся посылок *)
ПЕР
  msg:MSG;
УКАЗ
  ПОКА
         естьОчередь
       И
        (PeekMessage(msg,0,0,0,PM_REMOVE) # 0)
  ВЫП
     DispatchMessage(msg)
  КОН
КОН Отработать;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПоказатьОкно-;
УКАЗ
  ShowWindow(hWnd,SW_SHOWDEFAULT)
КОН ПоказатьОкно;

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

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       УдалитьЧасы-(часы:ЦЕЛ);
УКАЗ
  KillTimer(hWnd,часы)
КОН УдалитьЧасы;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       РазмерЭкрана-(  строк+,
                     колонок+ :ЦЕЛ);       (* Цель:  возвращает размер экрана *)
УКАЗ
  строк  :=размерЭкрана.с;
  колонок:=размерЭкрана.к
КОН РазмерЭкрана; 

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзменитьРазмерОкна-(  строк,
                           колонок :ЦЕЛ);      (* Цель:  изменить размер окна *)
ПЕР
  rect:RECT;
УКАЗ
  ЕСЛИ
       (    строк > РАЗМЕР(окно^,0))
      ИЛИ
       (колонок+1 > РАЗМЕР(окно^,1))
  ТО                                           (* память для знаков и барьера *)
    СОЗДАТЬ(окно,строк,колонок+1)
  КОН;

  rect.Left  :=0;
  rect.Top   :=0;
  rect.Right :=колонок*размерЗнака.x;
  rect.Bottom:=строк*размерЗнака.y;

  AdjustWindowRect(rect,WS_OVERLAPPEDWINDOW,0);

  размерОкна.x:=rect.Right-rect.Left;
  размерОкна.y:=rect.Bottom-rect.Top;

  SetWindowPos(hWnd,0,0,0,размерОкна.x,размерОкна.y,SWP_NOMOVE);

КОН ИзменитьРазмерОкна; 

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Опрос-(
                   отКлавиш+:Ввод.нОтКлавиш;
                    отМышки+:Ввод.нОтМышки
             ):ЦЕЛ;
(*
 * Цель: опрос ОС на наличие посылок от пользователя
 *)
ПЕР
  msg:MSG;
УКАЗ
  родПосылки:=Ввод.пустой;
  ПОКА естьОчередь И (родПосылки = Ввод.пустой) ВЫП
    GetMessage(msg,0,0,0);
    DispatchMessage(msg)
  КОН;
  ЕСЛИ НЕ естьОчередь ТО 
    родПосылки:=Ввод.закрыт
  КОН;
  ЕСЛИ родПосылки = Ввод.клавиши ТО
    отКлавиш:=ГОС.отКлавиш
  АЕСЛИ родПосылки = Ввод.мышка ТО
    отМышки:=ГОС.отМышки
  КОН;
  ВОЗВРАТ родПосылки
КОН Опрос;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПереместитьУказку-(с,к:ЦЕЛ);
УКАЗ
  указка.с:=с;
  указка.к:=к;
  SetCaretPos(указка.к*размерЗнака.x,(указка.с+1)*размерЗнака.y-размерУказки)
КОН ПереместитьУказку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       РазмерУказки-(размер:ЦЕЛ);
(*
 *     <размер> указывается в процентах,
 * при <размер> = 0 указка убирается с экрана
 *)
УКАЗ
  УдалитьУказку;
  размерУказки:=УЗК(ВШИРЦЕЛ(размерЗнака.y*размер/100));
  СоздатьУказку
КОН РазмерУказки;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПисатьЦвет-(с,к:ЦЕЛ;
                  цвет:ЗНАК);
УКАЗ
  окно[с][к].цвет:=цвет;
  Запятнать(с,к,с,к)
КОН ПисатьЦвет;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПисатьЗнак-(с,к:ЦЕЛ;
                  знак:ЗНАК);
УКАЗ
  окно[с][к].знак:=знак;
  Запятнать(с,к,с,к)
КОН ПисатьЗнак;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЧитатьЗнак-(с,к:ЦЕЛ):ЗНАК;
УКАЗ
  ВОЗВРАТ окно[с][к].знак
КОН ЧитатьЗнак;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЧитатьЦвет-(с,к:ЦЕЛ):ЗНАК;
УКАЗ
  ВОЗВРАТ окно[с][к].цвет
КОН ЧитатьЦвет;

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

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Вверх-(вс,лк,нс,пк :ЦЕЛ;
                  новЗнак-:ЦвЗнак.Вид);
(*
 * Цель:  сдвиг содержимого заданной области окна вверх
 * До:    <вс>,<лк>,<нс>,<пк> - границы области
 *        <новЗнак>           - знак для заполнения освободившегося места
 *)
ПЕР
  к,с:ЦЕЛ;
УКАЗ
  ОТ с:=вс ДО нс-1 ВЫП
    ОТ к:=лк ДО пк ВЫП
      окно[с][к]:=окно[с+1][к]
    КОН
  КОН;
  ОТ к:=лк ДО пк ВЫП
    окно[нс][к]:=новЗнак
  КОН;
  Запятнать(вс,лк,нс,пк)
КОН Вверх;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Вниз-(вс,лк,нс,пк :ЦЕЛ;
                 новЗнак-:ЦвЗнак.Вид);
(*
 * Цель:  сдвиг содержимого данной области окна вниз
 * До:    <вс>,<лк>,<нс>,<пк> - границы области
 *        <новЗнак>           - знак для заполнения освободившегося места
 *)
ПЕР
  к,с:ЦЕЛ;
УКАЗ
  ОТ с:=нс ДО вс+1 ПО -1 ВЫП
    ОТ к:=лк ДО пк ВЫП
      окно[с][к]:=окно[с-1][к]
    КОН
  КОН;
  ОТ к:=лк ДО пк ВЫП
    окно[вс][к]:=новЗнак
  КОН;
  Запятнать(вс,лк,нс,пк)
КОН Вниз;

(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
  естьОчередь:=ОТКЛ
КОН ГОС.
