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

Friday, 14-Mar-2008 16:21:34 EET

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

ГЛАВА 5. ПРОГРАММИРОВАНИЕ УПРАВЛЯЕМОЕ СОБЫТИЯМИ.

     Цель Turbo Vision обеспечить Вас рабочей оболочкой  для  Ваших
прикладных программ,  так  чтобы  Вы  могли  сконцентрироваться  на
наращивании "мяса" Ваших программ.  Два главных  инструмента  Turbo
Vision -  это  поддержка  построения  окон  и управление событиями.
Глава 4  объясняет  видимые  элементы,  а   эта   глава   описывает
построение программ вокруг событий.


Воплощение Turbo Vision в жизнь.


     Мы уже описали программы Turbo Vision, управляемые событиями и
кратко определили как Ваша программа должна реагировать на события.



Чтение ввода пользователя.


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

     repeat
       B := ReadKey;
       case B of
         'i': InvertArray;
         'e': EditArrayParams;
         'g': GraphicDisplay;
         'q': Quit := true;
       end;
     until Quit;

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



Природа событий.


     События лучше всего  представить  себе  как  небольшие  пакеты
информации, описывающие отдельные случаи (ситуации) на которые Ваша
программа должна  реагировать.  Каждое  нажатие   клавиши,   каждое
действие мышки  и любое условие,  генерируемое другими компонентами
программы, это отдельное событие.  События не могут быть разбиты на
более мелкие части;  так когда пользователь набирает слово - это не
одно событие, а серия отдельных событий от клавиш.
     В объектно-ориентированном   мире  Turbo  Vision  Вы  вероятно
думаете, что события это тоже объекты.  Это не так. Сами события не
производят действий;  они  только  содержат  информацию  для других
объектов и поэтому представлены записями.
     Ядром каждой  записи  типа  событие  является  поле  What типа
слово. Числовое  значение  поля  What  описывает  вид  события,   а
оставшаяся часть   записи   типа   событие   содержит   специальную
информацию об этом событии.  Скан код  клавиатуры  для  события  от
клавиш, информация  о  позиции  мышки  и  состоянии  ее  кнопок для
события от мышки и т.д.
     Поскольку различные виды событий передаются предназначаемым им
объектам различными  способами,  давайте  вначале  рассмотрим  виды
событий распознаваемые в Turbo Vision.



Виды событий.


     Давайте посмотрим на возможные значения Event.What. Существуют
4 основных  базовых  класса событий:  события от мышки,  события от
клавиатуры, события сообщений  и  "пустые"  события.  Каждый  класс
имеет определенную   маску,   так   что  Ваш  объект  может  быстро
определить какой тип события случился, не заботясь о его конкретном
виде. Например,  вместо  того,  чтобы проверять на 4 различных вида
событий от мышки,  Вы можете просто проверить, есть ли флаг события
в маске. Вместо

     if Event.What and (evMouseDown or evMouseUp or evMouseMove or
       evMouseAuto) <> 0 then .

     Вы можете использовать

     if Event.What and evMouse  <> 0 then .

     Доступны следующие маски:  evNothing (для  "пустых"  событий),
evMouse, для   событий   от   мышки;  evKeyBoard,  для  событий  от
клавиатуры и evMessage для сообщений.
     Биты маски событий определены на рис.5.5.

                 Рис. 5.1. Биты поля TEvent.What.

     +--------- Event Flags ---------+
     msb                           lsb
      +-+-+-+-+-+-+-+------------------- evMessage   = $FF00
      | | | | | | | |       +----------- evKeyboard  = $0010
      | | | | | | | |       | +-+-+-+--- evMouse     = $000F
     +++++++++++++++++=+=+=+++++++++++
     +=+=+=+=+=+=+++++=+=+=+++++++++++
                  | |       | | | | +--- evMouseDown = $0001
                  | |       | | | +----- evMouseUp   = $0002
                  | |       | | +------- evMouseMove = $0004
                  | |       | +--------- evMouseAuto = $0008
                  | |       +----------- evKeyDown   = $0010
                  | +------------------- evCommand   = $0100
                  +--------------------- evBroadcast = $0200


События от мышки.


     Существуют 4 вида событий от  мышки:  нажатие  или  отпускание
любой кнопки,  изменение позиции или "авто" событие. При нажатии на
кнопку мышки  генерируется  событие   evMouseDown.   Когда   кнопка
отпускается генерируется   событие   evMouseUp.  Перемещение  мышки
генерирует событие evMouseMove.  Если Вы  держите  кнопку  нажатой,
Turbo Vision периодически генерирует событие evMouseAvto, позволяяя
Вашей программе такие действия  как  повторяющийся  скроллинг.  Все
записи событий  от  мышки  включают позицию мышки,  так что объект,
обрабатывающий событие знает где находилась мышка в этот момент.



События от клавиатуры.


     События от   клавиатуры  намного  проще.  Когда  Вы  нажимаете
клавишу, Turbo Vision генерирует событие evDown,  которое  содержит
информацию о нажатой клавише.



События сообщений.


     События сообщений бывают 3 видов:  команды,  общие сообщения и
пользовательские  сообщения.  Они  отличаются  обработкой как будет
объяснено позднее.  Команды помечаются в поле What через evCommand,
общие сообщения  через  evBroadcast  и  пользовательские  сообщения
константой определенной пользователем.



"Пустые" события.


     "Пустые" события  это в действительности мертвые события.  Оно
перестало быть событием,  поскольку полностью обработано. Если поле
What в записи события содержит значение evNothing, то эта запись не
содержит полезной информации, которая требует обработки.
     Когда объект  Turbo  Vision заканчивает обработку события,  он
вызывает  метод  ClearEvent,  который  устанавливает  поле  What  в
evNothing,  указывая  что  событие было обработано.  Объекты должны
просто игнорировать события evNothing, поскольку они уже обработаны
другим объектом.



События и команды.


     Большинство событий в конечном итоге преобразуются  в команды,
например, отметка  мышкой  элемента  в  строке  статуса  генерирует
событие от мышки.  Когда оно поступает в объект  "строка  статуса",
этот объект    откликается   на   событие   от   мышки,   генерируя
событие-команду со значением поля  Command,  определяемым  командой
связанной с элементом строки статуса.  Нажатие мышкой на Alt-X Exit
генерирует команду cmQuit,  которую  программа  интерпретирует  как
инструкцию закрытия системы и завершения.



Передача событий.


     Видимые элементы Turbo Vision  работают  по  принципу  "Говори
только  когда  к  тебе обратятся".  Это не похоже на активный поиск
ввода,  они скорее пассивно ожидают,  когда монитор событий  скажет
им, что произошло событие, на которое требуется отклик.
     Для того чтобы Ваша программа на Turbo Vision делала то что Вы
хотите,  Вы должны не только сказать видимым элементам, что делать,
когда случается определенное событие,  но  и  должны  понимать  как
события  передаются  в  Ваши видимые элементы.  Главное в получении
событий в нужном месте - это  правильная  маршрутиризация  событий.
Некоторые  события  передаются  всем  элементам  программы,  другие
направляются точно в определенные части программы.



Откуда приходят события.


     Как сказано в главе 1,  главный цикл обработки в TApplication,
метод Run вызывает TGroup.Execute, которая основана на цикле:

     var E: TEvent;
     E.What := evNothing; { указывает что нет событий }
     repeat
       if E.What <> evNothing then EventError(E);
       GetEvent(E);       { упаковывает запись события }
       HandleEvent(E);    { направляет событие в нужное место }
     until EndState <> Continue;

     По существу GetEvent смотрит вокруг и проверяет,  не случилось
ли что  либо,  что должно быть событием.  Если случилось,  GetEvent
создает соответствующую   запись   события.    Затем    HandleEvent
направляет событие в соответствующие видимые элементы. Если событие
не обработано (и не очищено) за время пока оно не вернется  в  этот
цикл,  то вызывается EventError, чтобы указать на ненужное событие.
По умолчанию EventError ничего не делает.



Куда идут события.


     События всегда   начинают  свой  путь  с  текущего  модального
видимого элемента.  Для нормальных  операций  это  обычно  означает
объект "Ваша  программа".  Когда Вы выполняете модальное диалоговое
окно, это диалоговое окно -  модальный  видимый  элемент.  В  любом
случае, модальный  видимый элемент начинает обработку события. Куда
событие пойдет дальше зависит от природы события.
     События передаются  одним  из трех способов,  в зависимости от
вида события. Возможны три вида передач: позиционировнные, активные
и общие. Важно понимать как передается каждый вид события.



Позиционированные события.


     Позиционированные события  это   всегда   события   от   мышки
(evMouse).
     Модальный видимый элемент получает  позиционированное  событие
первым и начинает просматривать свои подэлементы в Z-порядке до тех
пор  пока  не  найдет  подэлемент  содержащий  позицию,  в  которой
возникло событие.  (Z-порядок объяснен в главе 4).  Затем модальный
видимый элемент передает событие этому видимому элементу. Поскольку
видимые  элементы  могут  перекрываться,  возможно  что  эта  точка
принадлежит  более  чем  одному  видимому  элементу.  Следование  в
Z-порядке гарантирует что это событие получит самый верхний видимый
элемент, включающий эту позицию.
     Этот процесс продолжается до тех пор пока не может быть найден
видимый элемент для передачи события,  либо  из-за  того,  что  это
терминальный видимый  элемент  (не  имеет  подэлементов),  либо  не
существует подэлементов включающих позицию этого  события (например
отмечено пустое  пространство  в  диалоговом  окне).  В этот момент
событие достигло  объекта,  где  возникло   это   позиционированное
событие и объект обрабатывает событие.



Активные события.


     Активные события это нажатия клавиш  (evKeyDown)  или  команды
(evCommand) и  передаются  вниз  по  активной  цепочке.  (Детальное
описание активных видимых элементов и активной цепочки  приведено в
"Выбранные и активные видимые элементы" главы 4).
     Текущий модальный видимый элемент  получает  активное  событие
первым и передает его в выбранный подэлемент.  Если этот подэлемент
содержит выбранный подэлемент,  он передает  событие  ему.  Процесс
продолжается до  тех  пор  пока  не  будет  достигнут  терминальный
видимый элемент:  это активный видимый  элемент.  Активный  видимый
элемент получает и обрабатывает активное событие.
     Если активный видимый элемент не знает как обработать какое-то
из полученных  событий,  он  передает  событие  вверх  по  активной
цепочке своему владельцу.  Процесс  повторяется  до  тех  пор  пока
событие не  будет  обработано  или  снова  не  достигнет модального
видимого элемента.  Если модальный видимый  элемент  не  знает  как
обработать   вернувшееся   событие,  он  вызывает  EventError.  Эта
ситуация - ненужное событие.  (Неактивные  видимые  элементы  могут
обрабатывать активные события. См. раздел "Фаза".)
     События от клавиатуры иллюстрируют  принцип  активных  событий
совершенно ясно.  Например, в интегрированной среде Turbo Pascal Вы
можете открыть  несколько  файлов  в  окнах  редактора.  Когда   Вы
нажимаете клавишу,  Вы  знаете  какой  файл  получит  этот  символ.
Давайте посмотрим как Turbo Vision обеспечивает это.
     Нажатие клавиши    генерирует   событие   evKeyDown,   которое
поступает в   текущий   модальный   видимый   элемент   -    объект
TApplication. TApplication   посылает   событие  своему  выбранному
элементу - панели экрана (панель экрана - всегда  выбранный элемент
TApplication). Панель  экрана  посылает  событие  своему выбранному
видимому элементу  -  активному  окну  (с  двойной  рамкой).   Окно
редактора также  имеет  подэлементы - рамку,  интерьер скроллинга и
две полосы скроллинга.  Из них может быть выбран только интерьер (и
следовательно выбран  по умолчанию),  поэтому событие от клавиатуры
приходит в него. Интерьер - редактор не имеет подэлементов и должен
решать как обработать символ в событии evKeyDown.



Общие события.


     Общие события это обычно общие сообщения  или пользовательские
сообщения.
     Общие события  не  направляются  как   позиционированные   или
активные события.  По  определению  обшие  события  не знают своего
назначения и  посылаются   всем   видимым   подэлементам   текущего
модального видимого элемента.
     Текущий модальный видимый элемент получает событие  и начинает
передавать его   подэлементам  в  Z-порядке.  Если  любой  из  этих
пдэлементов - группа,  он также передает событие своим подэлементам
и также  в  Z-порядке.  Процесс  продолжается  до  тех пор пока все
видимые элементы  принадлежащие  (прямо  или  косвенно)  модальному
видимому элементу не получат сообщения.
     Общие сообщения обычно используются для взаимодействия видимых
элементов. Например,   когда   Вы  отмечаете  полосу  скроллинга  в
просмотре файла, полоса скроллинга должна сказать видимому элементу
просмотра, что он должен показать другую часть себя. Это значит что
когда видимый элемент выдает общее сообщение "Я изменился!", другие
видимые элементы,   включая   текст,  будут  получать  сообщение  и
реагировать на  него.  Дополнительные  детали  смотри   в   разделе
"Межэлементное взаимодействие".
     Примечание: Общие  сообщения  могут  быть  направлены  объекту
функцией Message.



События определенные пользователем.


     Как только Вы ознакомитесь с  Turbo  Vision  и  событиями,  Вы
захотите определить новую категорию событий, используя старшие биты
поля What записи события.  По  умолчанию  Turbo  Vision  направляет
такие события как общие события.  Но Вам может понадобиться сделать
общие события  активными  или  позиционированными  и  Turbo  Vision
предоставляет механизм, позволяющий сделать это.
     Turbo Vision  определяет  две  маски  Positional  и   Focused,
которые содержат  биты  соответствующие событиям в поле What записи
события, которые должны быть направлены как  позиционированные  или
активные соответственно.  По умолчанию Positional содержит все биты
evMouse, а Focused содержит evKeyBoard.  Если Вы определяете другой
бит в   новом   виде  события,  которое  Вы  хотите  направить  как
позиционированное или  активное,  Вы  просто  прибавляете   бит   к
соответствующей маске.  (Манипуляция  битами  в маске объясняется в
главе 10).



Маскирование событий.


     Каждый видимый  элемент имеет битовое поле EventMask,  которое
используется для  определения,  какие  события  будет  обрабатывать
видимый   элемент.   Биты   EventMask   соответствуют   битам  поля
TEvent.What.  Если бит для данного вида события установлен, видимый
элемент  будет  принимать этот вид события для обработки.  Если бит
для данного вида события очищен, видимый элемент будет игнорировать
этот вид событий.



Фаза.


     Возникают ситуации  когда  Вы  хотите  чтобы  видимый  элемент
отличный от  активного  обрабатывал  активные  события (особенно от
клавиш). Например,  при просмотре текста в скроллингуемом окне  Вам
может понадобиться  использовать клавиши для скроллинга текста,  но
поскольку текстовое окно это активный видимый элемент,  события  от
клавиш приходят  к нему,  а не к полосам скроллинга,  которые могут
скроллинговать видимый элемент.
     Однако Turbo Vision предоставляет механизм позволяющий видимым
элементам отличным от  активного  элемента  видеть  и  обрабатывать
активные события.  Хотя  передача  описанная  в  разделе  "Активные
события" абсолютно корректна,  существуют два исключения при точном
прохожденни активной цепочки.
     Когда модальный  видимый  элемент   получает   для   обработки
активное событие, передача выполняется в три "фазы":
     - Событие  посылается  всем  подэлементам  (В  Z-порядке),   у
которых установлен флаг ofPreProcess.
     - Если событие  не  очищено  ни  одним  из  них,  это  событие
посылается в активный видимый элемент.
     - Если событие все еще не очищено,  оно посылается в Z-порядке
всем подэлементам с установленным флагом ofPostProcess.
     Так в предыдущем примере,  если полосе  скроллинга  необходимо
видеть клавиши,    которые   предназначены   активному   текстовому
элементу, полоса  скроллинга   должна   быть   инициализирована   с
установленным флагом ofPreProcess.  Если Вы посмотрите на программу
TVDEMO09.PAS Вы  заметите  что  полосы   скроллинга   для   видимых
элементов интерьера  имеют установленными биты ofPostProcess.  Если
Вы модифицируете  код  так,  чтобы  эти  биты  не  устанавливались,
скроллинг от клавиатуры будет запрещен.
     Заметим также что в этом примере нет большой разницы,  что  Вы
установите -  ofPreProcess  или  ofPostProcess.  Поскольку активный
видимый элемент в этом случае  не  обрабатывает  это  событие  (сам
TScroller ничего  не делает с нажатиями клавиш),  полосы скроллинга
могут видеть эти события как до  так  и  после  того,  как  событие
передается в скроллер.
     Однако лучше  использовать  в  таких  случаях   ofPostProcess,
поскольку он   предоставляет  большую  гибкость.  Позже  Вы  можете
добавить в интерьер код,  который проверяет нажатие клавиш, но если
эти нажатия будут использованы полосой скроллинга,  до того как они
будут получены  активным  элементом  (ofPreProcess),  Ваш  интерьер
никогда не будет реагировать на них.

     Примечание: Хотя   Вам  может  требоваться  перехват  активных
событий до того как активный элемент получает  их,  хорошая  мысль,
оставить как можно больше доступных возможностей, поскольку Вы (или
кто-то еще) можете наследовать  нечто  новое  от  этого  объекта  в
будущем.



Поле Phase.


     Каждая группа  имеет  поле  Phase,   которое   принимает   три
значения:  phFocused,  phPreProcess и phPostProcess.  Проверяя флаг
Phase владельца,  видимый   элемент   может   сказать,   будет   ли
обрабатываться  событие  активное  событие  до,  во время или после
передачи. Это иногда необходимо,  т.к.  некоторые видимые  элементы
ожидают различные  события  или  реагируют на одинаковые события по
разному, в зависимости от фазы.
     Рассмотрим случай простого диалогового окна,  которое содержит
строку ввода и клавишу с меткой "All right" с коротким набором "A".
С управляющими  элементами  обычного   диалогового   окна   Вы   в
действительности не имеете  дело  с  фазой.  Большинство  элементов
управления имеют  ofPostProcess установленным по умолчанию, поэтому
нажатия клавиш (активные события) будут передаваться  им,  позволяя
перехватывать   активность,  если  была  нажата  короткая  клавиша.
Нажатие "А" передает активность кнопке "All right".
     Теперь предположим  что активна строка ввода,  так что нажатия
клавиш обрабатываются и вставляются строкой ввода.  Нажатие клавиши
"А" вставляет  "А"  в  строку  ввода и кнопка никогда не увидит это
событие, поскольку активный видимый элемент обработал ее.  Если  вы
зададите предварительную  обработку  клавиши  "А"  для кнопки,  она
сможет перехватывать короткую клавишу до  того  как  ее  обработает
активный видимый элемент. К сожалению это не даст Вам набрать букву
"А" в строке ввода!
     Решение очень просто: сделайте проверку в кнопке для различных
коротких клавиш до и после того  как  активный  элемент  обработает
событие. По  умолчанию кнопка просматривает свою короткую клавишу в
форме Alt-буква до процесса и в форме  буквы  после  процесса.  Вот
почему Вы можете использовать короткий набор Alt-буква в диалоговом
окне, но можете обрабатывать обычные буквы  только  когда  активный
элемент управления не "ест" клавиши.
     Это просто сделать.  По умолчанию кнопки  имеют  установленные
ofPreProcess и ofPostProcess, так что видят активные события и до и
после активного видимого элемента,  но  внутри  метода  HandleEvent
кнопка проверяет  некоторые  клавиши  только  если активный элемент
управления уже видел событие:

     evKeyDown: { это часть оператора case }
       begin
         C := HotKey(Title^);
         if (Event.KeyCode = GetAltCode(C)) or
            (Owner^.Phase = phPostProcess) and (C <> #0) and
            (upcase(Event.CharCode) = C) or
         (State and sfFocused <> 0) and (Event.CharCode = ' ') then
         begin
           PressButton;
           ClearEvent(Event);
         end;
       end;



Команды.


     Большинство позиционированных и активных событий транслируются
обрабатывающими их   объектами   в   команды.   Т.е.  объект  часто
откликается на  отметку  мышкой  или  клавишу  генерацией   события
команды.
     Например, отметив в строке статуса программы на  Turbo  Vision
Вы генерируете позиционное (от мышки) событие. Программа определяет
что отметка была  позиционирована  в  области  управляемой  строкой
статуса и передает событие в объект строки статуса StatusLine.
     StatusLine определяет какой из  элементов  управления  статуса
отмечен и  читает запись элемента статуса для этого элемента.  Этот
элемент обычно имеет связанную с ним команду и  StatusLine  создает
запись статуса  с  полем What,  установленным в evCommand и с полем
Command,  установленным в команду,  которая  была  связана  с  этим
элементом статуса. Затем она очищает событие от мышки, что означает
что  следующее  событие  обнаруженное  GetEvent  будет  только  что
сгенерированное событие команды.



Определение команд.


     Turbo Vision имеет ряд предопределенных  команд  и  Вы  можете
определить еще  больше  своих.  Когда  Вы  создаете  новый  видимый
элемент, Вы также создаете команду, которая используется для вызова
этого видимого элемента. Команды могут быть названы произвольно, но
по соглашениям Turbo Vision идентификатор команды должен начинаться
с "cm".  Механизм  создания  команд  прост  -  Вы  только  создаете
константу:

     const
       cmConfuseTheCat = 100;

     Turbo Vision  резервирует  команды  от 0 до 99 и от 256 до 999
для собственного использования.  Ваша программа может  использовать
под команды номера от 100 до 255 и от 1000 до 65535.
     Причина того что Вы имеете два диапазона для команд  только  в
том что  команды  от  0  до 255 могут быть запрещены.  Turbo Vision
резервирует некоторые  команды,  которые  могут  быть  запрещены  и
некоторые команды   которые  не  могут  быть  запрещены  для  своих
стандартных команд и внутренней работы.  Вы имеете полный  контроль
над оставшимися командами.

            Таблица 5.1. Диапазоны команд Turbo Vision.

     ------------------------------------------------
     Диапазон     Зарезервировано   Может быть
                                    запрещено
     ------------------------------------------------
     099                Да            Да
     100255             Нет           Да
     256999             Да            Нет
     100065535          Нет           Нет
     ------------------------------------------------



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


     Когда Вы  создаете  элемент  строки  статуса  или   меню,   Вы
связываете с ним команду. Когда пользователь выбирает этот элемент,
генерируется запись события с полем What установленным  в evCommand
и полем Command установленным в значение связанной команды. Команда
может быть  стандартной  командой   Turbo   Vision   или   командой
определенной Вами. В тот момент, когда Вы связываете Вашу команду с
элементом меню или строки статуса,  Вы также можете  связать  ее  с
горячей клавишей.  Т.о.  пользователь может вызвать команду,  нажав
клавишу короткого набора или мышкой.
     Примечание: Важно   запомнить   что   определение  команды  не
указывает какое  действие  должно  быть  выполнено,  когда  команда
появляется в  записи  события.  Вы  должны  сказать соответствующим
объектам, как откликаться на эту команду.



Разрешение и запрещение команд.


     Иногда необходимо,  чтобы  некоторые  команды  были недоступны
пользователю определенное  время.  Например,  нет  открытых   окон,
бессмысленно разрешать    пользователю   генерировать   стандартную
команду закрытия окна cmClose.  Turbo Vision  предоставляет  способ
запретить и разрешить набор команд.
     Для разрешения или запрещения Вы  используете  глобальный  тип
TCommandSet, который  является множеством из чисел в диапазоне от 0
до 255.  (Вот почему можно запретить  только  команды  в  диапазоне
0255). Следующий код запрещает группу из 5 оконных команд:

     var
       WindowCommands: TCommandSet;
     begin
       WindowCommands := [cmNext, cmPrev, cmZoom, cmResize,
                          cmClose];
       DisableCommands(WindowCommands);
     end;



Обработка событий.


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

     procedure NewDescendant.HandleEvent(var Event: TEvent);
     begin
       {Код, изменяющий или ограничивающий унаследованное
        поведение}
       Parent.HandleEvent(Event);
       {Код, выполняющий дополнительные функции}
     end;

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



Запись события.


     До этого   момента  в  этой  главе  обсуждались  теоретические
аспекты события.  Мы говорили о том,  как  различные  виды  событий
(мышка, клавиатура,  сообщения и "пустые") определяются в поле What
события. Мы так же кратко обсудили использование поля  Command  для
событий-команд.
     Теперь самое  время  обсудить  как  выглядит  запись  события.
Модуль DRIVERS.TPU  в Turbo Vision определяет тип TEvent как запись
с вариантами:

     TEvent = record
       What: Word;
       case Word of
         evNothing: ();
         evMouse: (
           Buttons: Byte;
           Double: Boolean;
           Where: TPoint);
         evKeyDown: (
           case Integer of
             0: (KeyCode: Word);
             1: (CharCode: Char; ScanCode: Byte));
         evMessage: (
           Command: Word;
           case Word of
             0: (InfoPtr: Pointer);
             1: (InfoLong: Longint);
             2: (InfoWord: Word);
             3: (InfoInt: Integer);
             4: (InfoByte: Byte);
             5: (InfoChar: Char));
     end;

     Эта запись с вариантами просматривается по значению поля What.
Так, если TEvent.What - это evMouseDown, то TEvent содержит:

     Buttons: Byte;
     Double: Boolean;
     Where: TPoint;

     Если TEvent.What -  это  evKeyDown,  компилятор  позволит  Вам
обратиться к данным как

     KeyCode: Word;

     или как

     CharCode: Char;
     ScanCode: Byte;

     Последний вариант в записи события может хранить значение типа
Pointer, LongInt,   Word,   Integer,   Byte   или  Char.  Это  поле
используется в Turbo Vision различными способами.  Видимые элементы
могут сами  генерировать  события  и  посылать  их  другим  видимым
элементам. В  этом  случае  они  часто  используют  поле   InfoPtr.
Взаимодействие видимых  элементов  и поля InfoPtr описаны в разделе
"Взаимодействие видимых элементов".



Очистка событий.


     Когда метод  Handle  видимого  элемента обработал событие,  он
заканчивает этот  процесс  вызовом  метода  ClearEvent.  ClearEvent
устанавливает поле  Event.What  равным  evNothing и Event.InfoPtr в
@Self, что указывает на очищенное событие.  Если это событие  будет
передано  другому  объекту,  то  он  должен  игнорировать  "пустое"
событие.



Ненужные события.


     Обычно каждое  событие  обрабатывается  каким-либо  из видимых
элементов Вашей программы.  Если ни один из  видимых  элементов  не
обработал событие,  модальный  видимый элемент вызывает EventError.
EventError вызывает EventError владельца видимого элемента и так до
тех пор, пока не будет вызван TApplication.EventError.
     TApplication.EventError по умолчанию  ничего  не  делает.  При
необходимости Вы можете перекрыть EventError для вызова диалогового
окна с ошибкой или подачи сигнала.  Поскольку конечный пользователь
Вашей программы  не  отвечает  за ошибки программы,  обрабатывающей
событие, такое диалоговое окно  вероятно  должно  быть  удалено  из
коммерческой версии программы.
     ClearEvent так же помогает видимым элементам взаимодействовать
друг с  другом.  Сейчас  запомните,  что  Вы не закончите обработку
события до тех пор, пока не вызовите ClearEvent.



Модификация механизма событий.


     Сердцем текущего  модального  видимого  элемента является цикл
типа:

     var
       E: TEvent;
     begin
       E.What := evNothing;
       repeat
         if E.What <> evNothing then EventError(E);
         GetEvent(E);
         HandleEvent(E);
       until EndState <> Continue;
     end;



Централизация сбора событий.


     Одно из наибольших  достижений  программирования  управляемого
событиями в  том,  что  Ваш  код  не  должен знать откуда поступают
события. Например,  объект окно должен только знать,  что когда  он
видит в  событии  команду  cmClose,  он  должен  закрыться.  Его не
интересует то ли эта команда поступила от отметки  его  закрывающей
кнопки, или  из  выбора  меню,  или от горячей клавиши,  или пришло
сообщение от другого объекта программы.  Он даже не беспокоиться  о
том, предназначалась ли эта команда ему. Он только должен знать как
обработать данное событие и обрабатывает его.
     Ключ к   этому   "черному  ящику"  событий  -  метод  GetEvent
программы. GetEvent - это  единственная  часть  программы,  которая
интересуется источником  событий.  Объекты  Вашей  программы просто
вызывают GetEvent и  получают  события  от  мышки,  клавиатуры  или
сгенерированные другими объектами.
     Если Вы хотите создать новые виды  событий  (например,  чтение
символов из   последовательного   порта)   Вы  просто  перекрываете
TApplication.GetEvent в Вашей программе.  Как Вы можете увидеть  из
TProgram.GetEvent в  APP.PAS  цикл  в  GetEvent  сканирует  мышку и
клавиатуру, а затем вызывает Idle.  Чтобы вставить  новый  источник
событий, Вы  можете  либо  перекрыть Idle для просмотра символов из
последовательного порта и генерации  событий,  основанных  на  этих
символах, либо    перекрыть    сам    GetEvent,    чтобы   добавить
GetComEvent(Event) в  цикл,  где  GetComEvent   возвращает   запись
события, если доступен символ от последовательного порта.



Перекрытие GetEvent.


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

     procedure TMyApp.GetEvent(var Event: TEvent);
     begin
       TApplication.GetEvent(Event);
     end;



Неиспользованное время.


     Другое преимущество центрального местонахождения TApplication.
GetEvent в том,  что он вызывает метод TApplication.Idle,  если нет
готовых событий.  TApplication.Idle - это пустой метод,  который Вы
можете перекрыть  для того,  чтобы выполнять параллельную обработку
одновременно с текущим видимым элементом.
     Например предположим, Вы определили видимый элемент, названный
THeapView, который  использует   метод   UpDate   для   отображения
доступной в  данный  момент  памяти  кучи.  (Пример  просмотра кучи
включен в  демонстрационные  программы  на   Ваших   дистрибутивных
дисках.) Если  Вы  перекрываете TApplication.Idle,  следующим кодом
пользователь сможет увидеть отображение доступной памяти в куче вне
зависимости от его нахождения в программе.

     procedure TMyApp.Idle;
     begin
       HeapViewer.Update;
     end;



Взаимодействие видимых элементов.


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



Посредники.


     Если программа спроектирована  правильно  и  видимые  элементы
требуют взаимодействия  между  собой,  один  из  способов - создать
промежуточный видимый элемент.
     Например, предположим,   что   Вы  имеете  объект  электронной
таблицы и объект текстового процессора и хотите  иметь  возможность
вставлять что-либо  из  электронной таблицы в текстовый процессор и
наоборот. В программе Turbo Vision Вы можете выполнить  это  прямым
взаимодействием видимых  элементов.  Но предположим,  что позже Вам
понадобится добавить к этой группе объектов,  скажем, базу данных и
вставлять в  и  из  базы  данных.  В  этом  случае  Вам потребуется
дублировать связь, установленную Вами между первыми двумя объектами
на все 3 объекта.
     Лучшее решение - это установить промежуточный видимый элемент.
В этом  случае,  скажем,  "карман".  Объект должен знать только как
копировать что-либо в  этот  карман  и  как  вставить  что-либо  из
кармана. Вне   зависимости  от  того,  сколько  новых  объектов  Вы
добавите в группу,  взаимодействие никогда не станет более сложным,
чем сейчас.



Сообщения между видимыми элементами.


     Если Вы тщательно проанализировали Вашу ситуацию,  решили, что
программа спроектирована правильно и что Вам не требуется создавать
промежуточные элементы,    Вы    можете     реализовать     простое
взаимодействие между двумя видимыми элементами.
     До того,  как один видимый  элемент  сможет  взаимодействовать
с другим, Вы можете определить где находится другой видимый элемент
и вероятно даже убедиться,  что другой видимый элемент существует в
данное время.
     Вначале пример.  Модуль  Stddlg   содержит   диалоговое   окно
TFileDialog (этот  видимый  элемент  открывается  в интегрированной
среде, когда Вы хотите загрузить  новый  файл).  TFileDialog  имеет
TFileList, который показывает справочник на диске, а файл InputLine
отображает текущий   файл   для   загрузки.   Каждый   раз,   когда
пользователь  выбирает  другой  файл  в  FileList,  FileList должен
сказать FilеInputLine вывести новое имя файла.
     В этом  случае  FileList может быть уверен,  что FileInputLine
существует, поскольку оба инициализированы  внутри  одного  объекта
FileDialog. Как   FileList   сможет   сказать   FileInputLine,  что
пользователь выбрал новое имя?
     FileList создает   и  посылает  сообщение.  FileList.FocusItem
посылает сообщение, а FileInputLine.HandleEvent получает его:

    procedure TFileList.FocusItem(Item: Integer);
    var
      Event: TEvent;
    begin
      TSortedListBox.FocusItem(Item);   { вначале вызывает
                                          наследуемый метод }
      Message(TopView, evBroadcast, cmFileFocused, List^.At(Item));
      { TopView указывает текущий модальный видимый элемент }
    end;

    procedure TFileInputLine.HandleEvent(var Event:TEvent);
    var
       Name: NameStr;
    begin
      TInputLine.HandleEvent(Event);
      if (Event.What = evBroadcast) and
        (Event.Command = cmFileFocused) and
        (State and sfSelected = 0) then
      begin
        if PSearchRec(Event.InfoPtr)^.Attr and Directory <> 0 then
           Data^ := PSearchRec(Event.InfoPtr)^.Name + '\' +
              PFileDialog(Owner)^.WildCard
        else Data^ := PSearchRec(Event.InfoPtr)^.Name;
        DrawView;
      end;
    end;

     Message - это функция,  которая генерирует событие сообщения и
возвращает указатель на объект (если есть),  который обработал  это
событие.
     Заметим, что   TFileList.FocusItem   использует    расширенный
синтаксис Turbo   Pascal   (директива   компилятора   $X+),   чтобы
использовать функцию Message как  процедуру,  поскольку  результат,
возвращаемый Message, не нужен.



Кто обрабатывает общие сообщения?


     Предположим, Вам требуется определить,  находится ли на панели
экрана открытое окно прежде,  чем выполнить некоторые действия. Как
это сделать?  Ваш код должен послать общее событие, на которое окна
знают как   ответить.   "Подпись",  оставленная  объектом,  который
обработал это событие, будет говорить Вам кто (если есть) обработал
его.



Есть ли кто-нибудь?


     Конкретный пример.  В  IDE  Turbo  Pascal, если   пользователь
запрашивает открыть  окно  просмотра,  код,  который открывает окно
просмотра, должен проверить не открыто ли уже окно  просмотра. Если
нет, он открывает его; если есть, переносит наверх.
     Передача общего сообщения проста:

     AreYouThere := Message(DeskTop, evBroadcast, cmFindWindow,
                            nil);

     В методе  HandleEvent  окна  просмотра есть проверка на отклик
(очистка события) на команду cmFindWindow:

     case Event.Command of
       .
       cmFindWindow: ClearEvent(Event);
       .
     end;

     Вспомним, что ClearEvent не  только  устанавливает  поле  What
записи события в evNothing,  но так же устанавливает поле InfoPtr в
@Self. Message читает эти поля и,  если  событие  было  обработано,
возвращает указатель на объект,  обработавший событие-сообщение.  В
данном случае это окно просмотра.  Так за строкой, которая посылала
сообщение, мы включим:

     if AreYouThere = nil then
       CreateWatchWindow
     else AreYouThere^.Select;

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



Кто сверху?


     Используя технику,  описанную ранее, Вы так же можете например
определить, какое окно является верхним из  видимых  элементов  его
типа на панели экрана. Поскольку общее сообщение посылается каждому
подэлементу модального  видимого  элемента  в  Z-порядке   (порядок
обратный вставке),  самый  последний  вставленный видимый элемент -
это "верхний" видимый элемент на панели экрана.
     Рассмотрим ситуацию,  возникающую  в  IDE,  когда пользователь
имеет окно просмотра,  открытое на вершине панели экрана  во  время
пошагового выполнения  кода в окне редактора.  Окно просмотра может
быть активным окном (двойная рамка),  но курсор выполнения  в  окне
кода требует  сохранения  трассы  выполнимого кода.  Если на панели
экрана открыто несколько окон редактора, они могут не перекрываться
вообще, но  IDE  должен знать какое из окон редактора предназначено
для трассировки.
     Ответ: конечно   самое   верхнее   окно   редактора,   которое
определено как последнее вставленное.  Для того,  чтобы определить,
какое из  окон "верхнее",  IDE посылает общее сообщение,  отклик на
которое знают только окна редактора. Первое окно редактора, которое
получает общее   сообщение   и  будет  последним  вставленным;  оно
обработает событие,  очищая  его,   и   IDE   узнает   какое   окно
использовать для  трассировки кода,  читая результат,  возвращенный
Message.



Вызов HandleEvent.


     Вы так  же можете создать или модифицировать событие,  а затем
вызвать HandleEvent напрямую. Вы можете сделать 3 типа вызовов:
     1. Вы  можете  иметь  видимый элемент,  вызывающий HandleEvent
равного подэлемента  прямо.  ("Равные"  видимые  элементы   -   это
подэлементы с  одним  владельцем).  Сообщение  не передается другим
видимым элементам.  Оно  идет  прямо  к  этому  HandleEvent,  затем
управление возвращается к Вам.
     2. Вы можете  вызвать  HandleEvent  владельца.  Событие  будет
затем распространяться вниз по цепочке видимых элементов.  (Если Вы
вызываете  HandleEvent  из  Вашего  собственного  HandleEvent,  Ваш
HandleEvent будет вызываться рекурсивно.) Управление передается Вам
после обработки события.
     3. Вы  можете  вызвать HandleEvent видимого элемента из другой
цепочки видимых элементов.  Событие будет передаваться вниз по этой
цепочке видимых   элементов.   Управление   передается   Вам  после
обработки события.



Контекстная помощь.


     Turbo Vision имеет встроенный инструмент, который помогает Вам
реализовать контекстно-ориентированную помощь в Вашей программе. Вы
можете назначить  номер  контекстной  подсказки видимому элементу и
когда видимый элемент станет активным,  номер его подсказки  станет
текущим номером контекстной подсказки в программе.
     Чтобы создать глобальную контекстно-ориентированную подсказку,
Вы можете  реализовать  HelpView,  который знает номера контекстных
подсказок, определенных Вами.  Когда  вызывается  HelpView  (обычно
нажатием F1 или другой горячей клавиши),  он должен спросить своего
владельца о текущем контексте подсказки,  вызвав метод  GetHelpCtx.
Затем HelpView  может  читать  и  отображать  соответствующий текст
подсказки. Пример HelpView включен  в  дистрибутивные  диски  Turbo
Pascal.
     Контекстно-ориентированная помощь -  это,  вероятно,  одна  из
последних  возможностей,  которую  Вы  будете реализовывать в Вашей
программе, поэтому  объекты   Turbo   Vision   инициализируются   с
контекстом hcNoContext по умолчанию,  что означает предопределенный
контекст, который не изменяет текущего контекста. При необходимости
Вы можете  разработать номера подсказок,  затем вставить правильный
номер в соответствующий видимый элемент,  вызвав  SetHelpCtx  сразу
после создания видимого элемента.
     Контекстная подсказка так же используется строкой  статуса для
определения, какие  видимые  элементы отображаются.  Вспомним,  что
когда Вы  создаете  строку  статуса,  Вы  вызываете   NewStatusDef,
который определяет  набор  элементов  статуса для данного диапазона
значений контекстной помощи. Когда новый видимый элемент становится
активным, контекст  помощи этого элемента определяет,  какая строка
статуса будет отображаться. 
                              Назад | Содержание | Вперед

 

 

\

Подписка на новости 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
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...