## Код:
```
MODULE ObxWheel;
   IMPORT  Views, Controllers, Strings, Ports, Fonts, Properties;
   
   TYPE
       (* Создаем наследника абстрактоного объекта Views.View *)
      View = POINTER TO RECORD (Views.View) END;
   
   VAR
      posx, posy, number: INTEGER;
      xsize, ysize: INTEGER;
      font, comFont: Fonts.Font;
      v: View;
      
   (* Описываем обязательный метод отрисовки для объекта Views.View  *)
   PROCEDURE (v: View) Restore (f: Views.Frame; l, t, r, b: INTEGER);
      VAR tmp: ARRAY 64 OF CHAR;
   BEGIN
      (* Располагаем в кадре строку *)
      f.DrawString(5 * f.dot, 15 * f.dot, Ports.black, "Try to weel with/without Ctl & Shift", comFont);
      (* Преобразуем переменнуюnumber из целочисленного типа в строку *)
      Strings.IntToString(number, tmp);
      (* Располагаем в кадре строку с результатом преобразования *)
      f.DrawString(posx * f.dot, posy * f.dot, Ports.blue, tmp, font)
   END Restore;
   
   (* Описываем необязательный метод поведения размеров окна Views.View  *)
   PROCEDURE (v: View) HandlePropMsg (VAR msg: Properties.Message);
      (* Задаем размер по уплочанию *)
      CONST size = 150 * Ports.point;
   BEGIN
      (* Выполняем различные действия в зависимости от типа аругмента msg *)
      WITH msg: Properties.SizePref DO
         (* Если процедура примет сообщение об размерах окна
         и ширина окна неопределена, то устанавливаем по умолчанию *)
         IF msg.w = Views.undefined THEN msg.w := size; msg.h := size END
      ELSE END
   END HandlePropMsg;
   
   (* Описываем необязательный метод поведения Views.View  в зависимости от ввода *)
   PROCEDURE (v: View) HandleCtrlMsg* (f: Views.Frame; VAR msg: Views.CtrlMessage; VAR focus: Views.View);
      VAR x, y: INTEGER; isDown: BOOLEAN; m: SET;
   BEGIN
      WITH msg: Controllers.WheelMsg DO
         (* Если пользователь крутил колесо мыши,
         считываем информацию о вводе *)
         f.Input(x, y, m, isDown);         
         IF Controllers.modify IN m THEN
            (* Если нажат Ctrl *)
            IF msg.op = Controllers.incLine THEN
               INC(posx, 3)
            ELSE
               DEC(posx, 3)
            END
         ELSIF Controllers.extend IN m THEN
            (* Если нажат Shift *)
            IF msg.op = Controllers.incLine THEN
               INC(posy, 3)
            ELSE
               DEC(posy, 3)
            END
         ELSE
            (* Если не нажата ни Ctrl ни Shift *)
            IF msg.op = Controllers.incLine THEN
               INC(number)
            ELSE
               DEC(number)
            END;
         END;
         (* Чтобы сообщение не обрабатывалось другими отображениями, ставим флаг *)
         msg.done := TRUE;
         (* Обновляем отображение *)
         Views.Update(v, Views.keepFrames)
      ELSE
      END
   END HandleCtrlMsg;
   
   PROCEDURE Do*;
      VAR
   BEGIN
      (* Создаем в оперативной памяти новый объект *)
      NEW(v);
      (* Открываем отображение в новом окне *)
      Views.OpenAux(v, "Mouse Wheel Demo")
   END Do;
   
BEGIN
   (* Задаем начальные значения переменных *)
   number := 1;
   posx := 50;
   posy := 70;
   comFont := Fonts.dir.This("Arial", 9 * Ports.point, {}, Fonts.normal);
   font := Fonts.dir.This("Arial", 20 * Ports.point, {}, Fonts.normal);

END ObxWheel.
```
