Logo    
Деловая газета CitCity.ru citforum.ck.ua - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: citforum.ck.ua
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Friday, 14-Mar-2008 17:11:45 EET

Google
WWW citforum.ck.ua
Техническая конференция «Корпоративные базы данных-2008»
Москва, 24-25 апреля

ГЛАВА 2. НАПИСАНИЕ ПРОГРАММ В TURBO VISION.

     Сейчас, когда Вы увидели как выглядят программы  Turbo Vision,
внутри и снаружи, Вы, вероятно, захотите написать свою программу. В
этой главе Вы выполните это,  начиная с крайне простой программы  и
добавляя небольшие  фрагменты  кода на каждом шаге так,  чтобы было
видно что делает каждый фрагмент.
     Вероятно в  данный  момент  у  Вас много вопросов.  Как именно
работают видимые элементы?  Что я должен  делать  с  ними?  Как  их
настраивать в  моей  программе?  Если  бы Turbo Vision была обычной
библиотекой времени выполнения,  скорее всего Вы стали бы  смотреть
исходный код, чтобы получить эти ответы.
     Но Turbo  Vision  уже  работающая  программа.  Лучший   способ
ответить на  Ваши вопросы по Turbo Vision - это попробовать видимые
элементы. Как Вы увидите, Вы можете инициализировать их минимальным
кодом.



Ваша первая программа в Turbo Vision.


     Программа Turbo Vision всегда начинается с создания экземпляра
объекта, порожденного  от  TApplication.  В  следующем  примере  Вы
создадите порожденный от TApplication тип с именем TMyApp  и будете
перекрывать методы   TApplication.  От  нового  типа  Вы  создадите
экземпляр MyApp.

     Примечание: До конца этой главы мы  часто  будем  ссылаться  к
MyApp. Когда  Вы  пишите собственную программу в Turbo Vision,  Вы,
вероятно, назовете ее как-то иначе,  в соответствии  с  назначением
этой программы.  Мы  используем  MyApp,  поскольку это короче,  чем
сказать "экземпляр  объекта,  порожденного  от  TApplication".   (В
программе существует только 1 объект TApplication.)
     Начиная со следующего примера,  мы создадим программу.  Вместо
того, чтобы  приводить  листинг  программы  каждый  раз,  мы  будем
включать только добавляемые или изменяемые части в тексте.  Если Вы
создаете сами эту программу, Вы должны иметь хорошее представление,
что делается  в  каждом  изменении  функциональности.  Мы  так   же
рекомендуем Вам попробовать модифицировать примеры.

     Примечание: Некоторые стадии из создания примеров представлены
на Вашем дистрибутивном диске.  Имена файлов указаны вместе с кодом
примеров и   они  соответствуют  именам,  объявленным  в  операторе
program.

     Главный блок TVGUID01.PAS (и каждой программы в  Turbo Vision)
выглядит подобно:

     program TFirst;

     uses App;

     type
       TMyApp = object(TApplication)
       end;

     var
       MyApp: TMyApp;

     begin
       MyApp.Init;
       MyApp.Run;
       MyApp.Done;
     end.

     Заметим, что Вы  еще  не  добавили  никаких  новых  функций  в
TMyApp. Обычно  Вы  никогда не объявляете полностью новый объектный
тип без полей или методов.  Вы просто объявляете переменную  MyApp,
как экземпляр типа TApplication.  Поскольку Вы будете расширять его
позже, когда будете писать программу в Turbo Vision,  Вы установите
TMyApp для  гибкого  расширения.  По умолчанию TApplication создает
экран, как показано на рисунке 2.1.


            Рис. 2.1. Экран TApplication по умолчанию.

          +--------------------------------------+
          |                                      |
          +--------------------------------------|
          |**************************************|
          |**************************************|
          |**************************************|
          |**************************************|
          |**************************************|
          |**************************************|
          +--------------------------------------|
          |  Alt-X Exit                          |
          +--------------------------------------+

     Эта программа делает только одно:  она реагирует  на  Alt-X  и
завершает программу.  Чтобы  она  делала что-то еще,  Вам требуется
добавить дополнительные команды в строку  статуса  и/или  в  полосу
меню. В следующем разделе Вы сделаете это.



Панель экрана, полоса меню и строка статуса.


     Используемые объекты:  TView,  TMenuView,  TMenuBar, TMenuBox,
TStatusLine, TGroup, TDeskTop.
     Панель экрана, полоса меню и строка статуса в TFirst создаются
методами InitDeskTop, InitMenuBar и InitStatusLine из TApplication.
Эти 3 метода вызываются в TApplication.Init и Вам никогда  не нужно
вызывать их напрямую. Вместо этого метод Init Вашей программы будет
вызывать TApplication.Init в первой строке. Например

               procedure TMyApp.Init;
               begin
                 TApplication.Init;
                 { код инициализации для Вашей программы }
               end;

     Заметим, что Вам необходимо добавить  некоторые  модули  Turbo
Vision   в   оператор   uses   Вашей  программы.  Для  того,  чтобы
использовать меню, строку статуса и определения стандартных клавиш,
Вам необходимо  кроме  App  использовать Objects,  Menus и Drivers.
(Объекты и их модули описаны в главе 12.)
     Если Ваша   программа   не   требует   какой-либо  специальной
инициализации, Вы просто  используете  унаследованный  метод  Init.
Поскольку Init  и методы InitDeskTop,  InitMenuBar и InitStatusLine
виртуальные, вызов унаследованного  Init  вызывает  соответствующие
методы InitStatusLine и InitMenuBar. Вы увидите это в TVGUID02.PAS.
     InitDeskTop, InitMenuBar   и   InitStatusLine    устанавливают
зхначения  глобальных  переменных  DeskTop,  MenuBar  и  StatusLine
соответственно. Давайте посмотрим каждую из них.



Панель экрана.


     Панель экрана - это исключительно важный объект, но он требует
от Вас  очень  небольших  действий.  Вы   не   должны   перекрывать
унаследованный метод инициализации.  Пусть TApplication.InitDeskTop
обрабатывает его.  DeskTop  принадлежит   MyApp   и   когда   MyApp
устанавливает новый  видимый  элемент в ответ на ввод пользователя,
она должна подключить новый элемент пользователя к  DeskTop. Панель
экрана знает как управлять видимыми элемента.



Строка статуса.


     TApplication.InitStatusLine устанавливает   видимый    элемент
TStatusLine,  вызывая  StatusLine  для  определения  и  отображения
горячих клавиш.  StatusLine выводится, начиная с левого края экрана
и  любая  часть  нижней  строки экрана,  не требуемая для элементов
строки статуса,  свободна для других видимых элементов. TStatusLine
связывает горячие  клавиши  с  командами и сами элементы могут быть
отмечены мышкой.

     Примечание: Горячие клавиши - это комбинации  клавиш,  которые
действуют как элементы меню или строки статуса.

     TVGUID02.PAS создает      строку      статуса,      перекрывая
TApplication.InitStatusLine:

procedure TMyApp.InitStatusLine;
var R: TRect;                 { хранит границы строки статуса }
begin
  GetExtent(R);               { устанавливает R в координаты всего}
                              { экрана }
  R.A.Y := R.B.Y - 1;         { передвигает вершину на 1 строку }
                              { выше нижней }
  StatusLine := New(PStatusLine, Init(R,   { создает строку }
                                           { статуса }
    NewStatusDef(0, $FFFF,  { устанавливает диапазон контекстного }
                            { Help }
      NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, { определяет
                                                     элемент }
      NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,  { другой }
      nil)),           { больше нет клавиш }
    nil)               { больше нет определений }
  ));
end;

     Примечание: Не забудьте добавить

     procedure InitStatusLine; virtual;

     в объявление TMyApp.

     Инициализация -   это   последовательность  вложенных  вызовов
стандартных фунций  Turbo  Vision  NewStatusDef,   NewStatusKey   и
NewStatusBar (детально  описаны  в  главе 14).  TVGUID02 определяет
строку статуса для  отображения  диапазона  контекстной  справочной
информации от  0  до $FFFF и связывает стандартную команду cmQuit с
клавишей Alt-X,  а стандартную команду cmClose с  клавишей  Alt-F3.
(Команды Turbo Vision - это константы. Их идентификаторы начинаются
с cm.)
     Вы можете  заметить,  что  в  отличие  от  TMyApp.Init,  метод
InitStatusLine не  вызывает  метод,  который   он   перекрывает   -
TApplication.InitStatusLine. Причина    проста:    обе    программы
устанавливают строки   статуса,   которые   охватывают   одинаковый
диапазон контекстной  справочной  системы  и  назначают  его  одной
переменной. В TApplication.InitStatusLine нет ничего, что позволило
бы TMyApp.InitStatusLine  выполнить  работу  более просто и,  кроме
того, Вы потратите время и память на ее вызов.
     Последняя строка, выводимая в строке команд этой инициализации
- "Alt-F3  Close".  Часть  строки,   заключенная   в   "~",   будет
подсвечиваться на экране.  Пользователь может отметить мышкой любую
часть строки для активации команды.
     Когда Вы выполняете TVGUID02, Вы заметите, что элемент статуса
Alt-F3 не подсвечен и отметка его  мышкой  не  имеет  эффекта.  Это
происходит потому,  что  команда cmClose по умолчанию запрещена,  и
элементы, которые генерируют запрещенные команды, так же запрещены.
После того,  как Вы откроете окно,  cmClose и элемент статуса будут
активированы.
     Ваша строка   статуса   работает   сразу  после  инициализации
StatusLine, поскольку  Вы   используете   только   предопределенные
команды (cmQuit  и  cmClose.)  StatusLine  может  обрабатывать ввод
пользователя без Вашего вмешательства.



Создание новых команд.


     Заметим, что  команды  cmQuit и cmClose,  которые Вы связали с
элементами строки статуса,  являются стандартными  командами  Turbo
Vision, поэтому  Вам  не требуется определять их.  Для того,  чтобы
использовать собственные команды, Вы просто объявляете Ваши команды
как константные  значения.  Например,  Вы  можете  определить новую
команду, чтобы открыть новое окно:

     const
       cmNewWin = 199;

     Примечание: Turbo  Vision  резервирует некоторые константы для
собственных команд. См. "Определение команд" в главе 5.

     Затем Вы можете связать эту команду с  горячей  клавишей  и  с
элементом строки статуса.

     StatusLine := New(PStatusLine, Init(R,
       NewStatusDef(0, $FFFF,
         NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
         NewStatusKey('~F4~ New', kbF4, cmNewWin, { включение новой
                                                    команды }
         NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
         nil))),
       nil)
     ));

     Синтаксис инициализации  строки статуса - это хорошее введение
в инициализацию меню, которая более сложна.



Полоса меню.


     Переменная полосы  меню  MenuBar  инициализируется  вложенными
вызовами стандартных  функций  NewMenu,   NewSubMenu,   NewItem   и
NewLine.
     После того,  как  Вы   инициализируете   меню,   Ваша   работа
закончена. Полоса  меню  знает как обработать ввод пользователя без
Вашей помощи.
     Инициализируем простую   полосу   меню   с   одним  элементом,
содержащем один выбор:

       ## File #############
        +----------------+**
        |**Open F3*******|#*
        +----------------+#*
       **##################*
       *********************


     const
       cmFileOpen = 200; { определение новой команды }
     procedure TMyApp.InitMenuBar;
     var R: TRect;
     begin
       GetExtent(R);
       R.B.Y := R.A.Y + 1;
       MenuBar := New(PMenuBar, Init(R, NewMenu( { создать полосу с
                                                   меню }
         NewSubMenu('~F~ile', hcNoContext, NewMenu(    { определить
                                                         меню }
           NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
                                                     { элемент }
           nil)),          { больше нет элементов }
         nil)              { больше нет подменю }
       )));                { конец полосы }
     end;

     Меню, создаваемое этим кодом, называется 'File' и элемент меню
называется 'Open'.  "~" делает F символом короткого ввода в 'File',
а O - символом короткого ввода 'Open';  клавиша F3  устанавливается
как горячая клавиша для 'Open'.
     Все видимые  элементы   Turbo   Vision   могут   иметь   номер
контекстной подсказки,  связанный  с  ними.  Номер позволяет просто
реализовать контекстно-ориентированную справочную систему  в  Вашей
программе. По    умолчанию    видимые   элементы   имеют   контекст
hcNoContext - это специальный контекст, который не изменяет текущий
контекст.  Номера контекстов подсказки появляются при инициализации
полосы меню,  поскольку из-за  вложенной  структуры  этих  объектов
добавить  номера  позднее  будет  трудно.  Когда Вы готовы добавить
контекст  подсказки  в  полосу  меню,  Вы  можете  подставить  свои
значения для hcNoContext в коде Init.
     Чтобы добавить  второй  элемент  в  меню  'File',  Вы   просто
вкладываете другую функцию NewItem:

       ## File #############
        +----------------+**
        |**Open F3*******|#*
        |  New  F4       |#*
        +----------------+#*
       **##################*
       *********************

     MenuBar := New(PMenuBar, Init(R, NewMenu(
       NewSubMenu('~F~ile', hcNoContext, NewMenu(
         NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
         NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
         nil))),
       nil)
     )));

     Чтобы добавить  второе  меню,  Вы  вкладываете  другую функцию
NewSubMenu:

     ## File   Window###########
     ********+---------------+**
     ********|**Next F6******|#*
     ********|  Zoom F5      |#*
     ********+---------------+#*
     **********################*
     ***************************

     MenuBar := New(PMenuBar, Init(hcNoContext, NewMenu(
       NewSubMenu('~F~ile', hcNoContext, NewMenu(
         NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
         NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
         nil))),
       NewSubMenu('~W~indow', hcNoContext, NewMenu(
         NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
         NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
         nil)),
       nil)))      { закрывающая скобка для меню }
     )));

     Вы связали 2 стандартных команды Turbo Vision cmNext  и cmZoom
с элементами меню и горячими клавишами.
     Чтобы добавить горизонтальную линию  между  выборами  в  меню,
вставьте вызов NewLine между вызовами NewItem:

       ## File  Window######
        +----------------+**
        |**Open F3*******|#*
        |  New  F4       |#*
        +----------------+#*
        |  Exit  Alt-X   |#*
        +----------------+#*
       **##################*
       *********************

     { находится в TVGUID03.PAS }
     MenuBar := New(PMenuBar, Init(hcNoContext, NewMenu(
       NewSubMenu('~F~ile', hcNoContext, NewMenu(
         NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
         NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
         NewLine(
         NewItem('E~x~it', 'Alt-X', kbAltX, cmNewWin, hcNoContext,
         nil))))),
       NewSubMenu('~W~indow', hcNoContext, NewMenu(
         NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
         NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
         nil))),
       nil))
     )));

     Вы можете заметить, что версия TVGUID03.PAS на Вашем диске так
же добавляет клавишу статуса в строку статуса, связывая клавишу F10
с командой cmMenu.  cmMenu - это стандартная команда Turbo  Vision,
которая помогает  пользователям использовать полосу меню без мышки.
В этом случае клавиша F10 активирует полосу меню,  позволяя выбрать
меню и элементы меню, используя клавиши курсора.
     Вы можете так же заметить,  что элемент статуса  имеет  пустую
строку в качестве текста и для него ничего не появляется на экране.
Хотя можно предупредить пользователей,  что F10 будет  активировать
меню, они,  скорее  всего,  не будут указывать этот элемент мышкой.
Отметить полосу меню гораздо более удобно.



Замечания по структуре.


     В данный  момент  доступен  ряд команд,  но большинство из них
запрещены, а команды cmNewWin и cmFileOpen еще не выполнили никаких
действий.
     Если Ваша первоначальная реакция - одно  разочарование,  этого
не должно быть,  Вы сделали многое!  В действительности, Вы открыли
одно из больших достижений программирования управляемого событиями:
Вы  отделили  функции  получения  ввода  от функций отклика на этот
ввод.
     Традиционная техника программирования  требует  возвращения  в
написанный код и добавления кода для открытия окон и т.п.  Но Вы не
делали этого:  Вы получили законченную систему,  которая знает, как
генерировать команды.  Все,  что  Вам  требуется  -  это   написать
несколько программ,  которые  реагируют  на  эти команды.  Это Вы и
сделаете в следующем разделе.
     Оболочка программ   Turbo   Vision  делает  следующий  шаг  по
сравнению с традиционным модульным программированием.  Вы не только
разбиваете Ваш код на функциональные,  вновь используемые блоки, но
и эти  блоки  могут  быть  меньше,  более  независимыми   и   более
взаимозаменяемыми.
     Ваша программа  сейчас  имеет  несколько  различных   способов
генерации команды  (cmNewWin),  чтобы открыть окно:  элемент строки
статуса, элемент меню и горячая  клавиша.  Вы  видите,  как  просто
сказать Вашей  программе  открыть  окно,  когда  показана  команда.
Наиболее важно то,  что  программа  не  заботится  о  том,  ни  как
генерируется команда, ни как создается окно. Эти фукции независимы.
     Если позднее Вы захотите изменить связки команд  - переместить
выбор меню,  переназначить  горячие  клавиши - Вам не нужно об этом
беспокоиться и даже думать о том, как это будет влиять на остальной
код. Т.е.   программирование,   управляемое   событиями,   отделяет
проектирование пользовательского   интерфейса   от   работы   Вашей
программы и  позволяет  различным  частям программы функционировать
независимо.



Открытие окон.


     Используемые объекты:    TRect,    TView,   TWindow,   TGroup,
TScroller, TScrollBar.
     Если Вы  программист,  Вы можете сразу перейти на этот раздел,
как только Вы откроете книгу.  Кроме того,  что  может  быть  более
важно для написания оконных программ, чем создание окон?
     Это было  бы  так,  если  бы   Turbo   Vision   была   набором
традиционных библиотечных  программ.  В этом случае переход на этот
раздел и попытка начать работать была бы хорошей идеей.
     Но Turbo  Vision - не традиционная библиотека.  Если Вы читали
предыдущие разделы,  Вы  уже  знаете  об  этом.  Для  того,   чтобы
программировать в   Turbo  Vision  необходимо  выполнить  некоторые
действия до того,  как создавать окна. Вам необходимо понимать, что
такое  окно  Turbo  Vision  (а это объект!) и чем оно отличается от
окон,  которые Вы использовали раньше.  Когда Вы сделаете  это,  Вы
продвинитесь вперед гораздо дальше, чем Вы можете вообразить.
     Поэтому, если  Вы  открыли книгу в этом месте,  Вам необходимо
вернуться к предыдущим разделам и прочитать их.



Стандартное оформление окон.


     Окно Turbo  Vision  -  это  объект  со   встроенной   в   него
возможностью реагировать   на   ввод   пользователя  без  написания
специального кода.  Окна Turbo Vision уже  знают  как  открываться,
изменять размер, перемещаться и закрываться. Но Вы не пишите в окно
Turbo Vision.  Окно Turbo Vision содержит то,  что содержат  и  чем
управляют другие  объекты:  эти  объекты отображают себя на экране.
Окно управляет видимыми элементами и функции Вашей программы  - это
видимые элементы,  которые  окно  содержит  и  которыми  управляет.
Видимые элементы,  создаваемые Вами, предоставляют большую гибкость
в том,   где  и  как  они  появляются.  Как  же  Вам  комбинировать
стандартные окна с теми элементами,  которые Вы хотите поместить  в
них? Снова  и снова запомните,  что Вы получили мощную оболочку для
построения и использования.  Начните со  стандартного  окна,  затем
добавьте требуемые  Вам  возможности.  Как  только  Вы  просмотрите
несколько следующих примеров,  Вы увидите как  просто  наращивается
программа вокруг представленной Turbo Vision основы.
     Следующий код инициализирует окно и подсоединяет его  к панели
экрана. Не  забудьте добавить новые методы к объявлению Вашего типа
TMyApp. Заметим,  что Вы опять определяете новый тип  (TDemoWindow)
не добавляя  полей и методов к типу предка.  Как и раньше Вы просто
создаете основу, которую Вы сможете быстро достраивать. Вы добавите
новые методы при необходимости.

 {    TVGUID04.PAS }

uses Views;

const
  WinCount: Integer =   0;   { инициализация счетчика окон }

type
  PDemoWindow = ^TDemoWindow;   { заметим, что Вы всегда объявляете
                                  тип указателя для каждого нового
                                  объектного типа }
  TDemoWindow = object(TWindow)  { определение нового типа окна }
  end;

procedure TMyApp.NewWindow;
var
  Window: PDemoWindow;
  R: TRect;
begin
  Inc(WinCount);
  R.Assign(0, 0, 26, 7);       { установка начального размера и
                                 позиции }
  R.Move(Random(58), Random(16));  { случайное перемещение по
                                     экрану }
  Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
  DeskTop^.Insert(Window);     { вывести окно на панель экрана }
end;

procedure TMyApp.HandleEvent(var Event: TEvent);
begin
  TApplication.HandleEvent(Event);    { действует как предок }
  if Event.What = evCommand then
  begin
    case Event.Command of     { но откликается на дополнительные
                                команды }
      cmNewWin: NewWindow;    { определяет действие для команды
                                cmNewWin }
    else
      Exit;
    end;
    ClearEvent(Event);        { очищает событие после обработки }
  end;
end;

     Чтобы использовать   это  окно  в  программе,  Вам  необходимо
связать программу cmNewWin  с  опцией  меню  или  горячей  клавишей
строки статуса,  как  Вы делали ранее.  Когда пользователь вызывает
cmNewWin, Turbo Vision  пересылает  команду  в  TMyApp.HandleEvent,
который реагирует, вызывая TMyApp.NewWindow.



Инициализация окна.


     Вам необходимо передать  в  окно  Turbo  Vision  3  параметра,
чтобы оно  могло  себя  инициализировать:  его  размер и позицию на
экране, заголовок и номер окна.
     Первый параметр  TRect - прямоугольный объект в Turbo Vision -
определяет размер и позицию окна.  Его метод Assign дает его размер
и позицию,  основанную  на  верхнем  левом  и  нижнем правом углах.
Существует несколько способов  назначения  или  изменения  объектов
TRect. См.  главу  14  "Справочник  по  глобальным  элементам"  для
полного описания.

     Примечание: Объект TRect детально описан в  главе  4  "Видимые
элементы".

     В TVGUID04  R создается от начала DeskTop,  затем смещается на
случайное расстояние  на  панели  экрана.  "Нормальные"  программы,
вероятно, не будут выполнять такое случайное движение.  Это сделано
только для примера,  чтобы Вы могли открыть несколько окон и  чтобы
они не размещались в одном месте.
     Второй параметр   инициализации   -   это   строка,    которая
отображается как заголовок окна.
     Последний параметр хранится в поле окна Number. Если Number от
1  до  9,  он  выводится  в рамке окна и пользователь может выбрать
пронумерованное окно, нажав от Alt-1 до Alt-9.
     Если Вам  не  нужно  назначать  номер  окну,  просто передайте
константу wnNoNumber.



Метод Insert.


     Вставка окна  в  DeskTop  автоматически  приводит  к появлению
окна. Метод Insert используется, чтобы дать визуальный контроль над
видимым элементом. Когда Вы выполняете

     DeskTop^.Insert(Window);

     Вы вставляете Window в панель экрана. Вы можете вставить любое
число видимых  элементов  в  групповой  объект,  такой  как  панель
экрана. Группа,  в которую Вы вставляете видимый элемент называется
видимым элементом -  владельцем,  а  видимый  элемент,  который  Вы
вставляете,  называется видимым подэлементом.  Заметим, что видимый
подэлемент сам может  быть  группой  и  может  иметь  свои  видимые
подэлементы. Например,  когда  Вы  вставляете окно в панель экрана,
окно является подэлементом,  но окно может владеть рамкой, полосами
скроллинга и другими видимыми подэлементами.
     Этот процесс  установления  связей  между  видимыми  объектами
создает дерево   видимых  элементов.  (Взаимосвязи  между  видимыми
элементами объяснены в главе 4.)



Закрытие окна.


     Отметка закрывающей  кнопки  окна  генерирует такую же команду
cmClose, какую Вы связали с  клавишей  Alt-F3  и  элементом  строки
статуса. По умолчанию открытие окна (через F4 или выбор в меню File
/Open) автоматически разрешает команду cmClose и  видимые элементы,
которые генерируют  ее (а так же другие оконные команды,  такие как
cmZoom, cmNext).
     Вам не  требуется  писать  код  для того,  чтобы закрыть окно.
Когда пользователь отметил закрывающую кнопку  окна,  Turbo  Vision
сделает все  остальное.  По  умолчанию  окно  реагирует  на команду
cmClose вызовом своего дестрактора Done:

     Dispose(MyWindow, Done);

     Как часть метода окна Done,  он вызывает методы Done для  всех
своих подэлементов. Если Вы сами распределяли дополнительную память
в констракторе окна,  Вам требуется освободить  ее  в  методе  окна
Done.



Поведение окна.


     Давайте попробуем поработать с Вашей программой. Она уже имеет
ряд возможностей.   Она   знает   как  открыть,  закрыть,  выбрать,
переместить и изменить размеры множества  окон  на  панели  экрана.
Неплохо для менее, чем ста строк кода!
     После того, как TMyApp инициализирует окно, он вставляет его в
панель экрана.  Как Вы помните, DeskTop - это группа, что означает,
что его назначение - владеть и  управлять  видимыми  подэлементами,
такими как Ваше окно.  Если Вы откомпилировали и выполнили код,  Вы
заметите, что Вы можете изменять  размер,  перемещать  и  закрывать
новое окно.  Ваш  ввод  от  мышки  преобразуется  в серию событий и
направляется из панели экрана в  новое  окно,  которое  знает,  как
обработать их.
     Если Вы сохранили  вызов  cmNewWin,  на  панели  экрана  будет
появляться несколько  окон  с уникальными номерами.  Эти окна могут
изменять размеры,  выбираться и перемещаться.  Рис.  2.2 показывает
панель экрана, на котором открыто несколько окон.


       Рис. 2.2.  TVGUID04  с  несколькими открытыми окнами.

+-----------------------------------------------------------------+
|  File  Window                                                   |
|*****************************************************************|
|*********************+-- Demo Window 3----+**********************|
|*********************|                  +-- Demo Window 7--+*****|
|*********************|                  |                  |*****|
|*********************|                  |                  |*****|
|*********************|  +-- Demo Window 8--+               |*****|
|*********************|  |                  |               |*****|
|*********************+--|                  |               |*****|
|+-- Demo Window 1--+**  |                  |---------------+*****|
||                  |**  |                  |     |***************|
||                  |**  |                  |     |***************|
||    +-- Demo Window 4--+------------------+     |***************|
||    |                   |****|  +-- Demo Window 6--+Window 2--+*|
||    |                   |****|  |                  |          |*|
|+----|                   |****+--|                  |          |*|
|*****|                  +=[ю]= Demo Window 9=[ш]=+  |          |*|
|*****|                  |                        |  |          |*|
|*****+------------------|                        |  |          |*|
|************************|                        |--+----------+*|
|************************|                        |***************|
|************************|                        |***************|
|************************+=======================-+***************|
|*****************************************************************|
| Alt-X Exit  F4 New  Alt-F3 Close                                |
+-----------------------------------------------------------------+


     TWindow -  это  группа,  которая  первоначально  владеет одним
видимым элементом TFrame. Пользователь отмечает кнопки на рамке для
перемещения, изменения размера или закрытия окна.  Рамка отображает
заголовок, который был получен во время  инициализации  окна  и  он
рисуется фоновым цветом окна,  таким как TBackGround панели экрана.
Все это происходит без написания Вашего кода.



Просмотр в любом окне.


     Если Вы работали с традиционными окнами, то следующим шагом Вы
попытаетесь записать что-либо в него.  Но TWindow не  пустая  доска
для записи:  это  группа Turbo Vision,  объект TGroup без экранного
представления всего,  что лежит под ним. Чтобы поместить что-либо в
окно, Вам  необходимо сделать дополнительный шаг,  который вложит в
Ваши руки огромную мощь.
     Чтобы что-либо появилось в окне,  Вы создаете видимый элемент,
который знает как рисовать себя  и  вставляете  его  в  окно.  Этот
видимый элемент называется интерьером.
     Первый интерьер будет заполнять все окно,  но позже Вы узнаете
как легко  уменьшить  его  размер  и  освободить  место  для других
видимых элементов.  Окно может владеть  несколькими  интерьерами  и
любым числом  других  полезных  видимых элементов:  строками ввода,
метками, кнопками.  Вы также увидите как  просто  поместить  полосу
скроллинга в рамку окна.
     Вы можете перекрывать подэлементы в группе - видимые элементы,
с которыми Вы взаимодействуете,  являются верхними.  TDeskTop имеет
метод Tile,  который может перекрывать видимые подэлементы после их
инициализации, но этот метод используется только с панелью экрана.
     Вы создаете интерьер простым  наследованием  от  TView.  Любой
TView может иметь рамку, которая действует как рамка обычного окна.
Рамка TView,  которая не может быть отмечена, находится вне области
отсечения любого  вывода  для  этого  видимого элемента.  Эта рамка
просто окаймляет окно.
     Если интерьер  TView  заполняет  все окно владельца,  не имеет
значения имеет ли он рамку - рамка окна накрывает  рамку интерьера.
Если интерьер меньше,  чем окно,  рамка интерьера видима. Несколько
интерьеров внутри окна могут быть окружены рамками,  как Вы увидите
в примере.
     Следующий код выводит "Hello, World!" в демонстрационном окне,
как показано на рис. 2.3.

   { TVGUID05.PAS }

  PInterior = ^TInterior;
  TInterior = object(TView)
    constructor Init(var Bounds: TRect);
    procedure Draw; virtual;
  end;

constructor TInterior.Init(var Bounds: TRect);
begin
  TView.Init(Bounds);
  GrowMode := gfGrowHiX + gfGrowHiY;
end;

procedure TInterior.Draw;
begin
  TView.Draw;
  WriteStr(4, 2, 'Hello, World!');
end;

constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String;
                             WindowNo: Integer);
var
  S: string[3];
  Interior: PInterior;
begin
  Str(WindowNo, S);        { устанавливает номер окна в заголовке }
  TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
  GetClipRect(Bounds);
  Bounds.Grow(-1,-1);     { интерьер помещается внутри рамки окна }
  Interior := New(PInterior, Init(Bounds));
  Insert(Interior);    { добавляет интерьер к окну }
end;


               Рис. 2.3. TVGUID05 с открытым окном.

+-----------------------------------------------------------------+
|  File  Window                                                   |
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
|+=[ю]Demo Window 1 [ш]=+*****************************************|
||                      |*****************************************|
||                      |*****************************************|
||    Hello, World!     |*****************************************|
||                      |*****************************************|
||                      |*****************************************|
|+=====================-+*****************************************|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
| Alt-X Exit  F4 New  Alt-F3 Close                                |
+-----------------------------------------------------------------+



Что Вы видите?


     Все объекты  Turbo  Vision  рисуют  себя сами с помощью метода
Draw. Если  Вы  создаете  порожденный  видимый   объект   с   новым
представлением на  экране,  Вам  потребуется  перекрыть  метод Draw
предка и  научить  новый  объекта  представлять  себя  на   экране.
TInterior порожден от TView и он требует нового метода Draw.
     Заметим, что новый TInterior.Draw вначале вызывает Draw своего
предка, TView,  который  в этом случае просто очищает прямоугольник
видимого объекта.  Обычно Вам не требуется делать этого: метод Draw
интерьера   должен  использовать  всю  свою  область,  делая  вызов
TView.Draw ненужным.
     Если Вы   действительно   хотите   поместить   что-то  в  окно
интерьера, Вам не нужно вызывать унаследованный метод  Draw вообще.
Вызов TView.Draw  будет  приводить  к  миганию,  поскольку элементы
интерьера будут рисоваться более одного раза.
     В качестве  примера  Вы  можете  попробовать перекомпилировать
TVGUID05.PAS с   закомментированным   вызовом   TView.Draw.   Затем
передвиньте и измените размер окна.  Станет совершенно ясно, почему
видимый элемент должен покрывать всю свою область!

     Примечание: Turbo Vision вызывает метод Draw видимого элемента
когда пользователь  открывает,  закрывает,  перемещает или изменяет
размер видимого элемента. Если Вам требуется, чтобы видимый элемент
перерисовал себя  сам,  вызовите  DrawView  вместо  Draw.  DrawView
рисует элемент  только  если  он  этого  требует.  Это  важно:   Вы
перекрываете Draw,  но никогда не вызываете его прямо; Вы вызываете
DrawView, но никогда не перекрываете его!



Лучший способ для Write.


     Хотя Вы  можете выполнить процедуру Write в Turbo Vision,  это
неверный путь.  Во-первых,  если Вы просто пишете  что-нибудь,  нет
способа предотвратить случайное затирание окна или другого видимого
элемента. Во-вторых,  Вам требуется писать в локальных  координатах
текущего видимого  элемента и отсекать по его границам.  В-третьих,
встает вопрос об использовании цвета при выводе.
     Процедура WriteStr  Turbo  Vision не только знает как писать в
локальных координатах и как отсекать по границам видимого элемента,
но так  же  как  использовать  палитру  цветов  видимого  элемента.
Процедура WriteStr берет координаты X и  Y,  строку  для  записи  и
индекс цвета в качестве параметров.
     Аналогично WriteStr, процедура WriteChar определена:

     WriteChar(X, Y, Ch, Color, Count);

     Подобно WriteStr,  WriteChar  позиционирует   свой   вывод   в
координаты (X,  Y)  внутри  видимого  элемента  и пишет Count копий
символа Ch цветом,  указываемым элементом Color из палитры видимого
элемента.
     Каждый из этих методов должен вызываться только изнутри метода
Draw видимого элемента.  Это единственное место,  где Вам требуется
писать что-либо внутри Turbo Vision.



Простой просмотр файлов.


     В этом  разделе мы добавим несколько новых функций в Ваше окно
и поместим в интерьер что-нибудь реальное.  Мы добавим  методы  для
чтения текстового файла с диска и отображения его в интерьере.

     Примечание: Эта  программа  будет  выводить некоторые "лишние"
символы. Не беспокойтесь.

   { TVGUID06.PAS }

const
  MaxLines  = 100;        { это произвольное число строк }

var
  LineCount: Integer;
  Lines: array[0MaxLines - 1] of PString;

type
  PInterior = ^TInterior;
  TInterior = object(TView)
    constructor Init(var Bounds: TRect);
    procedure Draw; virtual;
  end;

procedure TInterior.Draw;      { это выглядит безобразно! }
var
  Y: Integer;
begin
  for Y := 0 to Size.Y - 1 do  { простой счетчик строк }
  begin
    WriteStr(0, Y, Lines[Y]^, $01);   { вывод каждой строки }
  end;
end;

procedure ReadFile;
var
  F: Text;
  S: String;
begin
  LineCount := 0;
  Assign(F, FileToRead);
  Reset(F);
  while not Eof(F) and (LineCount < MaxLines) do
  begin
    Readln(F, S);
    Lines[LineCount] := NewStr(S);
    Inc(LineCount);
  end;
  Close(F);
end;

procedure DoneFile;
var
  I: Integer;
begin
  for I := 0 to LineCount - 1 do
    if Lines[I] <> nil then DisposeStr(Lines[i]);
end;



Чтение текстового файла.


     Ваша программа вызывает ReadFile для загрузки текстового файла
в массив  Lines  и  DoneFile для освобождения памяти,  используемой
Lines, после выполнения.
     В ReadFile  глобальный  тип PString - это указатель на строку.
Turbo Vision так же предоставляет функцию NewStr, которая сохраняет
строку в  куче  и  возвращает  указатель  на нее.  Даже хотя NewStr
возвращает указатель,  не используйте Dispose для ее  освобождения.
Всегда используйте  процедуру  DisposeStr  для  удаления  строки из
кучи.



Буферизованный вывод.


     Вы заметили,  что  при  выполнении  этой  программы  на экране
появляется "мусор"  там,  где  должны  быть  пустые   строки.   Это
результат неполного  метода  Draw.  Он  возникает  из-за  нарушения
принципа, что метод Draw видимого  элемента  должен  покрывать  всю
площадь, за которую отвечает этот видимый элемент.
     Кроме того, текстовый массив Lines не является соответствующей
формой для отображения в видимом элементе.  Текст обычно состоит из
строк переменной длины,  многие из  которых  имеют  нулевую  длину.
Поскольку метод  Draw  должен  перекрывать  всю  область интерьера,
текстовые строки должны быть расширены до ширины видимого элемента.



Буфер вывода.


     Чтобы избежать  этого,  создайте новый Draw,  который включает
каждую строку в буфер до  ее  вывода  в  окне.  TDrawBuffer  -  это
глобальный тип:

     TDrawBuffer = array[0MaxViewWidth-1] of Word;

     Примечание: MaxViewWidth равен 132 символам.

     TDrawBuffer содержит байты с атрибутами и с символами.
     Новый TInterior.Draw имеет вид:

    { TVGUID07.PAS }

procedure TInterior.Draw;
var
  Color: Byte;
  Y: Integer;
  B: TDrawBuffer;
begin
  Color := GetColor(1);
  for Y := 0 to Size.Y - 1 do
  begin
    MoveChar(B, ' ', Color, Size.X); { заполняет строку пробелами }
    if (Y < LineCount) and (Lines[Y] <> nil) then
      MoveStr(B, Copy(Lines[Y]^, 1, Size.X), Color);
    WriteLine(0, Y, Size.X, 1, B);
  end;
end;

     Рис. 2.4 показывает TVGUID07 с несколькими открытыми окнами.

               Рис. 2.4. Просмотр нескольких файлов.

+-----------------------------------------------------------------+
|  File  Window                                                   |
|*****************************************************************|
|***********+--- Demo Window 3 ----+******************************|
|***********|{*********************|******************************|
|***********|{                     |******************************|
|***********|{   Turbo Pascal 6.0  |******************************|
|***********|{   Demo program from |******************************|
|***********|{                     |******************************|
|***********+----------------------+******************************|
|+--- Demo Window 1 ---+***+=[ю]Demo Window 5 [ш]=+***************|
||{********************|***|{*********************|***************|
||{                    |***|{                     |***************|
||{  Turbo Pascal 6.0  |***|{   Turbo Pascal 6.0  |4 ----+********|
||{  Demo program from |***|{   Demo program from |******|2 ----+*|
||{                    |***|{                     |      |******|*|
|+---------------------+***+=====================-+ 6.0  |      |*|
|*********************************|{   Demo program from | 6.0  |*|
|*********************************|{                     | from |*|
|*********************************+----------------------+      |*|
|*******************************************+-------------------+*|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
|*****************************************************************|
| Alt-X Exit  F4 New  Alt-F3 Close                                |
+-----------------------------------------------------------------+

     Draw вначале  использует  MoveChar  для   перемещения   Size.X
пробелов (ширина  интерьера)  соответствующего цвета в TDrawBuffer.
Сейчас каждая строка дополняется  пробелами  до  ширины  интерьера.
Затем Draw  использует  MoveStr  для копирования текстовой строки в
TDrawBuffer. Затем отображает весь буфер через вызов WriteLine.



Пересылка текста в буфер.


     Turbo Vision   предоставляет   4   глобальных   процедуры  для
пересылки текста в TDrawBuffer:  MoveStr,  которую  Вы  только  что
видели, и MoveChar, MoveCStr и MoveBuf, которые пересылают символы,
управляющие строки (строки с "~" для элементов меню  и  статуса)  и
другие буфера  в  буфер,  соответственно.  Эти  процедуры объяснены
детально в главе 14.



Вывод содержимого буфера.


     Turbo Vision  предоставляет 2 процедуры для вывода содержимого
буфера в видимый элемент.  Одна,  WriteLine(X,  Y, W, H, Buf), была
показана в TVGUID07.
     В TInterior.Draw,  WriteLine  выводит  TDrawBuffer  на   одной
строке. Если 4 параметр,  H (высота), больше 1, WriteLine повторяет
буфер на  последующих  строках.  Так,  если  Buf  содержит  "Hello,
World!", то WriteLine(0, 0, 13, 4, Buf) выводит

     Hello, World!
     Hello, World!
     Hello, World!
     Hello, World!

     Другая процедура WriteBuf(X,  Y,  W,  H,  Buf)  также  выводит
прямоугольную область  экрана.  W и H соответствуют ширине и высоте
буфера. Если Buf содержит "ABCDEFGHIJKLMNOP",  то WriteBuf(0, 0, 4,
4, Buf) выводит

     ABCD
     EFGH
     IJKL
     MNOP

     Вы видите,  что по сравнению с  небуферизованными  WriteStr  и
WriteChar здесь  не  указывается  элемент  в  палитре  цветов.  Это
связано с тем, что цвет задается когда текст пересылается в буфер -
это  означает,  что  текст  в  буфере  может  появляться  с разными
атрибутами. WriteLine и WriteBuf детально объяснены в главе 14.

                              Назад | Содержание | Вперед

 

 

\

Подписка на новости IT-портала citforum.ck.ua
(библиотека, citforum.ck.ua, CitCity)

Новые публикации:

12 марта

  • Восход и закат High Performance Fortran: наглядный урок истории (пересказ: С.Кузнецов)
  • citforum.ck.ua:

    Новые Блогометки:

  • Ccze: хорошее модульное средство подсветки логов
  • PWSafe - кроссплатформенное средство для работы с паролями
  • colordiff - подсветка для diff
  • psmisc: рассмотрим ближе стандартный пакет
  • Работа с сетью
  • xkb, узелок на память
  • ffmpeg-php
  • debiannotes:desktop:prettyfonts
  • 5 марта

    citforum.ck.ua:

  • Ричард Столлман в Москве
  • О мудром доценте замолвите слово... (Интенсификация Малаховна)
  • Новые Блогометки:

  • "Десктопизация" OpenBSD
  • weather: проверяйте сводку и прогноз погоды из командной строки
  • hpodder: клиент подкастов, который просто работает
  • bc: язык численных расчетов с произвольной точностью
  • Decibel: аудиоплеер для людей
  • GNU Wget: загрузите весь понравившийся сетевой контент на локальный компьютер
  • Deborphan: найдите ненужные пакеты
  • Kivio: мощный и простой в использовании редактор блок-схем
  • Cowsay: настраиваемая говорящая и думающая корова
  • Thoggen: основанная на GTK+ программа для извлечения видео с DVD
  • 28 февраля

  • Подбор и развитие команд
    Глава из книги «Руководство командой разработчиков программного обеспечения. Прикладные мысли» (С.Архипенков)
  • citforum.ck.ua:

    Дискуссия об анонимусах:

  • К комментаторам
  • Windows против Linux - психологический портрет участников форумов
  • Новые Блогометки:

  • Nokia N810 - Linux Inside
  • LiMo - стандарты Linux для сотовых телефонов
  • timer-applet: таймер для панели GNOME
  • Debfoster: удалите пакет и все его зависимости
  • GPW: генератор произносимых паролей
  • AMOR: общество для рабочего стола
  • 20 февраля

    citforum.ck.ua:

    Новые Блогометки:

  • Кое-что о приложениях KDE 4
  • Инструкция по установке KDE 4 в Ubuntu
  • Настоящие мужчины ставят KDE из SVN!
  • Начат переход Amarok на Qt 4.4
  • Marble
  • Dillo - сверхбыстрый браузер
  • Создаем резервные копии настроек программ и важных файлов в Ubuntu LInux
  • NTP: всегда вовремя
  • VYM - простое средство зарисовки мыслей и планирования
  • KBibTeX: простой и гибкий редактор библиографий для KDE
  • Дискуссия Windows vs Linux:

  • Жил-был Мальчик, или Сказочка о Том, Откуда Берутся "КУЛХАЦКЕРЫ", ненавидящие Линукс и Юникс
  • 13 февраля

  • Терминологический словарь Wi-Fi
  • Задача проектирования базы данных методом нормализации
  • CitCity:

  • Лучшие смартфоны начала 2008 года
  • citforum.ck.ua:

  • Первый взгляд на Firefox 3.0
  • Open Source на Белгородщине: семинар в Старом Осколе
  • Что такое KDE?
  • Цикл о Slackware:

  • Русский в консоли
  • Быстрая настройка Иксов
  • xorgconfig - консольный подход
  • 6 февраля

    citforum.ck.ua:

  • Мобильный Linux – вчера, сегодня, завтра
  • Чем записать диски в Linux? Попробуй Brasero!
  • Консольные команды
  • Рецепты. Кое-что о программе mplayer
  • Slackware:
    • Что такое Slackware?
    • Установка Slackware - Загрузка
    • Категории программного обеспечения
    • Структура файловой системы
    • Система инициализации Slackware Linux
    • Скрипты инициализации уровня запуска

    30 января

  • Обзор алгоритмов MOLAP
  • CitCity:

  • BI-технологии 2007. Итоги года
  • Рынок СУБД для Хранилищ данных 2007. Итоги года, тенденции
  • Обзор рынка BI (по результатам исследований IDC, OLAP Report, Gartner)
  • Модель зрелости BI
  • citforum.ck.ua:

  • Владимир Попов: За что я люблю Linux
  • Священные войны
  • 23 января

  • Data Mining от Oracle: настоящее и будущее
  • Комментарии к статье Ч.Бергера «Data Mining от Oracle: настоящее и будущее»
  • Байесовский классификатор и регрессионная модель в ORTD: практический пример
  • citforum.ck.ua:

    Дискуссия Windows vs Linux:

  • Программисты и фирмы: кто кого
  • О "чистых пользователях"
  • Новые Блогометки:

    • Почему Jabber, а не ICQ?
    • Archlinux install quick
    • Arch на IBM Z60m
    • Arch + IBM R50e
    • OpenBSD - сборка E17-cvs (или ещe одна маленькая победа разума)
    • OpenBSD - всe для Человека и ради Человека...
    • PekWM
    • E17 и "прозрачность"
    • E17 - приятные мелочи (multimedia)
    • SuSE + Enlightenment = угробил целый день

    16 января

  • Вьетнам компьютерной науки (пересказ - С.Кузнецов)
  • Пример построения автоматизированного управления дисками (ASM) (В. Пржиялковский)
  • CitCity:

  • 2008 год: антипрогноз
  • citforum.ck.ua:

    Новые Блогометки:

    Сети и Интернет:

    • Mozilla firefox. Шрифты в меню
    • Screen tips
    • Liferea: программа чтения RSS для GNOME
    • HTTrack: скачивание и зеркалирование сайтов
    • Clusterssh: работа с несколькими сеансами SSH через общий интерфейс

    Десктопы:

    • Fluxbox & xinitrc. Some new tips
    • Как я конфигурировал xdm

    Системы:

    • SuSE 10.2: zypper - еще один способ установки пакетов
    • cpipe: определите пропускную способность конвейера команд
    • gddrescue: средство восстановления данных с поврежденных носителей
    • VirtualBox: ваш виртуальный ПК

    Приложения:

    • MyTop: top для MySQL

    10 января

    citforum.ck.ua:

    Дискуссионный клуб:

  • Краткое руководство по общению с никсофилами (Интенсификация Малаховна Сергина-Гейтс)
  • О троллях
  • Пещера горного короля: заметки о троллинге
  • Новые Блогометки:

    Сети и Интернет:

    • Делаем блог на Drupal
    • Использование lftp
    • Устанавливаем FTP сервер ProFTPd с TLS шифрованием
    • Управляем файлами на FTP сервере с помощью FileZilla

    Десктопы:

    • fluxbox.autorun
    • 15 человек на сундук мертвеца! (или песнь о зарытых сокровищах)

    Системы:

    • Живой Debian или рабочее место в кармане
    • Разбивка hdd

    Приложения:

    • Cat Excel files
    • Vim: меню выбора кодировок

    26 декабря

    citforum.ck.ua:

  • В Блогометках открыты разделы:
    • Софт для Windows
    • Сети и Интернет
  • dwm. От статики к динамике
  • Установил Solaris
  • Новая Дискуссия:
    • Нужен ли русский Linux?

    19 декабря

  • SQL Anywhere: встраиваемая СУБД
  • citforum.ck.ua:

  • В разделе Блогометки появились рубрики:
    • Десктопы
    • Приложения
    • Системы
  • Подробно о разделе: Блоги и блогометки: открываем сезон промывки
  • 13 декабря

    CitCity:

  • Microsoft и Барселона: сюрреализм?
  • citforum.ck.ua:

  • Открыт новый раздел Блогометки
  • ZFS в подробностях. 1. Былое и ныне
  • 5 декабря

  • Архитектура предприятия: основные определения
  • Архитектуры для государственных ведомств. Примеры
  • Обзор журнала Computer:

  • Высокопроизводительные встроенные системы
  • citforum.ck.ua:

  • Продолжение цикла Linux для начинающих:
    • Пользовательские интерфейсы
    • Файлы
    • Системы настройки

    Все публикации >>>




IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей Пресс-релизы -
Послать комментарий
Информация для авторов
Rambler's Top100 хостинг от .masterhost This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2007 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...