Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

Надежные VPS и выделенные серверы в Нидерландах

Storage VPS, High CPU VPS

Профессиональная техническая поддержка

Домены, SSL сертификаты, VPN

2005 г.

Как перестать беспокоиться и начать программировать. Часть II.

Андрей Кочетов, «Королевство Delphi»

Часть 1 Часть 2 Часть 3
Размышления старого программиста о жизни и о себе

План второго выпуска пришлось немножко подкорректировать, чтобы не оставить без внимания отзывы IceStudent’а на предыдущую статью. Разбор полётов будет в стиле "Цитата IceStudent’а (IS) – Ответ Андрея Кочетова (АК)".

IS: <…> идея повторного использования ресурсов очень хороша, при условии, что надёжность испольуемого кода очень высока

АК: Спасибо :) Смею надеяться, что код до некоторой степени отлажен, так как непрерывно шлифуется уже пятый год

IS: <…> Но дальнейшее обсуждение узкоспециализированных утилит несёт не много пользы

АК: Я уже говорил, что в статьях будут обсуждаться не столько конкретные блоки кода, сколько идеи. См. ниже

IS: <…> Класс TAskCursor - Маленькая фича, применяемая в отдельных случаях. В большинстве случаев, изменить курсор намного проще и быстрее, чем описано<…> А уж если сравнить объём генерируемого кода для класса и для<…>

АК: Вы забыли, что для "исключительного" случая (Exception) также придётся писать код, возвращающий курсор в прежний вид, а в случае использования класса (объект которого лежит в стеке), это выполнится автоматически – ведь при исключительной ситуации механизм обработки исключений нормально завершает процедуру, в т.ч. нормально завершат своё существование все локальные переменные и объекты; а в деструкторе класса, который непременно выполнится, и будет автоматически изменена форма курсора к прежнему виду. Так что с классом – писать меньше. К тому же во всех местах объявления класса будет подключаться один и тот же код, в то время, как при ручном написании обработки формы курсора каждый раз вновь пишется один и тот же код, который и увеличивает размер программы. Более того, по секрету напомню: реализация класса TAskCursor содержится в отдельной (статически линкуемой) DLL, что делает рассуждения о "разбухании" кода несостоятельными в принципе.

IS: Визуальные компоненты с дополнительными свойствами бывают полезны нередко, если не отличаются ненужными излишествами и глюкавостью :)

АК: Согласен. Именно функциональность, и никаких излишеств! Приглашаю к чтению второй статьи.

Итак, продолжаем рассмотрение визуальных компонентов с закладки "ASK Controls"

TAskPageControl

– наследник компонента TPageControl, который обладает одним, на мой взгляд, недостатком: если в "designtime" сфокусироваться на любую закладку, отличную от первой, именно эта (не первая!) закладка и будет показана во время выполнения программы ("runtime"). Приходится возвращаться к редактированию проекта только для того, чтобы устранить эту досадность. TAskPageControl избавлен от этого недостатка: в "runtime" при первом показе компонента активна первая закладка. Я уже акцентировал внимание, что мои инструменты нацелены на облегчение (моего) труда разработчика, даже в мелочах.

TAskDateEdit

– наследник компонента TDateEdit 1. Так уж получилось, что RX-компонент для ввода даты мне нравится больше стандартного; к тому же он более функционален. Ну а недостающую функциональность добирает производный компонент TAskDateEdit.

Отличается от предка следующим: если язык локализации Windows – русский или один из французских диалектов, то некоторые параметры компонента устанавливаются в значения, принятые для календаря во Франции, откуда, собственно, они и заимствованы Россией вместе с метрической системой мер и весов:

  • Неделя начинается в понедельник, а не в воскресенье, как в Пиндустане
  • Выходные – суббота и воскресенье, оба выделяются красным цветом.

Указанная доп. функциональность выполняет некие действия автоматически в "runtime", что позволяет не заморачиваться ручной установкой этих свойств в "designtime" для каждого компонента, брошенного на форму.

У этого компонента также есть дополнительное свойство "AskBegDateType", которому можно присвоить одно из следующих значений (в том числе и в "designtime", в "Инспекторе объектов"): ebdtNone, ebdtToday, ebdtBegPrevMonth, ebdtEndPrevMonth, ebdtBegPrevQuarter, ebdtEndPrevQuarter, ebdtBegCurMonth, ebdtEndCurMonth, ebdtYesterday

В зависимости от значения этого свойства, отображаемая дата будет:

  • Пустая
  • Текущая дата
  • 1-й день предыдущего месяца
  • Последний день предыдущего месяца
  • 1-й день предыдущего квартала
  • Последний день предыдущего квартала
  • 1-й день текущего месяца
  • Последний день текущего месяца
  • Вчерашняя дата

Как уже понял проницательный читатель, это свойство введено для того, чтобы исключить написание кода для задания даты или периодов (начальная и конечная даты) – например, при формировании отчётов за период.

Для полноты описания следует добавить, что существует свойство "DateToStr6", которое переводит дату в строку вида "ГГММДД", что достаточно часто бывает нужным при разработке деловых приложений.

TAskEdit, TAskMaskEdit, TAskRxCalcEdit, TAskCurrencyEdit, TAskComboBox, TAskMemo, и т.д.

– наследники соответствующих компонентов без префикса ASK. Обладают дополнительными свойствами, позволяющими выполнять предустановки статусов клавиатуры при получении компонентами фокуса ввода, и возвращающими всё в исходное состояние при потере компонентами фокуса ввода (при уходе с них). Если это выглядит чуточку заумно, дальше всё станет понятно.

Итак, свойства:

  • bool AskSaveKeyboardStatus – запоминать ли статус клавиатуры (состояние "Caps Lock", "Num Lock", языковая раскладка) перед его изменением (при получении фокуса ввода)
  • bool AskRestoreKeyboardStatus – восстанавливать ли статус клавиатуры при потере фокуса ввода (уходе с компоненты редактирования)
  • bool AskCapsLockOff – выключает "Caps Lock"
  • bool AskCapsLockOn – включает "Caps Lock"
  • bool AskNumLockOff – выключает "Num Lock"
  • bool AskNumLockOn – включает "Num Lock"
  • bool AskSwitchToWinLang – переключать ли раскладку клавиатуры на язык локализации Windows (для русских Windows – это русский язык)
  • bool AskSwitchToENU - переключать ли раскладку клавиатуры на английский язык.

Таким образом, только редактированием свойств компонентов, - без написания кода - можно разработать максимально удобный для пользователей режим ввода данных: в поле ввода ФИО – русский язык, в поле ввода суммы – английский, "Num Lock" включен, и т.д.

TAskSpeedButton

– наследник TRxSpeedButton (просто так исторически сложилось; можно было произвести и от TSpeedButton). О-о, TAskSpeedButton – это отдельная песня! Запеваем.

  • AnsiString AskNameDll, AskNamePic – свойства, позволяющие подгрузить на кнопку изображение, лежащее в библиотеке образов. По умолчанию используется библиотека AskImg.dll
  • bool AskAllowAllUp – Свойство времени проектирования. Пояснение. В "designtime", если на форме несколько (не дай бог, много!) подобных кнопок, бывает очень трудно не запутаться и правильно выставить свойство "GroupIndex". Так вот, "AskAllowAllUp, при установке значения "true" в "designtime", выполняет следующее: присваивает свойству "AllowAllUp" то же значение, а свойству "GroupIndex" присваивает уникальное значение, не совпадающее со свойствами "GroupIndex" прочих кнопок "SpeedButton", лежащих на форме.
рис. 1
рис 1.
TControl * PtrControl0… PtrControl9

(см. рис. 2). Опять лирическое отступление. Каждый из нас видел в программных продуктах реализацию таких вещей: при нажатии на "CheckBox" или одну из точек "RadioGroup", связанные (по логике приложения) поля появляются или исчезают, или становятся (не)доступными (свойство "Enabled"). Однажды мне опостылело писать похожий код всякий раз, когда надо сделать что-то подобное. И я придумал для себя концепцию интерфейса: если от компонента ожидается простое значение типа "да/нет", - это будет "CheckBox". Если же потребуется включать/выключать логически связанные элементы управления, пусть это будет "SpeedButton" со включенным свойством "AllowAllUp" (сохранение нажатого/отжатого состояния). См. рис. 1.

рис. 2
рис 2.

Соответственно, к кнопке можно прицепить до 10-и компонентов (поля ввода, кнопки, надписи, да что угодно!), которые будут появляться в случае, если Down=true, и исчезать в противном :) случае. Эти-то свойства и указывают на зависимые компоненты; значения им присваиваются во время проектирования.

Свойство EControl AskControl – может принимать значения "ecVisible" или "ecEnabled". Соответствующему свойству зависимых компонентов и будет присваиваться значение свойства "Down". То есть, при нажатии кнопки зависимые компоненты становятся видимыми (или доступными для редактирования), а при отжатой кнопке – невидимыми (нередактируемыми).

Осталась лишь одна проблема: следует сохранять и восстанавливать не только свойство "Down", но и свойства Visible/Enabled всех зависимых компонентов. Если мы автоматизируем и этот момент, мы сможем разрабатывать поведение довольно сложных интерфейсов без написания кода. Итак, знакомьтесь: свойство

bool AskDown. Следует присваивать значение true/false именно ему, а не "Down". Также следует сохранять в реестре (INI-файле) именно его. В этом случае поведение/состояние кнопки вместе со всеми зависимыми элементами управления будет ожидаемым и в момент работы, и при повторном запуске формы.

Для функционирования приведённых на примере ((рис. 1) кнопок и сохранения/восстановления настроек не написано ни строчки кода. P.S. на примере – настройки программы "DrwUpdater" - обновилки вирусных баз (*.vdb) для антивируса DrWeb. К слову, все проекты, представленные на этом сайте, реализованы с использованием "AskTools". Как и (закрытые) проекты на основной работе.

Более того, набор таких кнопок удобно использовать в качестве функционально расширенного заменителя RadioGroup – см. рис. 1. К каждой Speed-кнопке зависимого выбора можно "прицепить" до 10 зависимых компонентов, и получается довольно мощная конструкция – без единой строчки кода.

TAskSpdBtnGroup.

Для этого "изобретен" ещё один компонент: TAskSpdBtnGroup. И хотя он невизуальный, находится он также на закладке "ASK Controls". Он обладает следующими свойствами:

TAskSpeedBtn * PtrAskSpdBtn0… PtrAskSpdBtn9 – указатели на взаимозависимые кнопки, эмулирующие функциональность TRadioGroup.

У всех этих кнопок значение свойства "GroupIndex" должно быть одинаковым.

short ItemIndex – индекс нажатой кнопки (от 0 до n-1). Если сохранять это свойство в INI-файле или реестре (и восстанавливать), то при показе формы уже будет нажата одна из множества кнопок. Соответственно, зависимые от неё компоненты будут видимы (разрешены), в то время, как компоненты, зависимые от других зависимых кнопок (простите за тавтологию), будут невидимы (запрещены).

TAskSpeedBtn * ActiveControl – указатель на нажатую кнопку.

Для сохранения/восстановления свойств компонентов я использую компонент, производный от TFormStorage из RX Lib. Знающие люди подтвердят, что это чрезвычайно удобная штука.

Поэтому разработка интерфейса любой степени сложности с сохранением/восстановлением настроек, не занимает много времени и не требует написания программного кода.

TAskToolBar.

Последний компонент с закладки "ASK Controls". TAskToolBar – производен от TToolBar и предназначен для того, чтобы можно было с минимальными усилиями динамически формировать панель инструментов. Кнопки, располагающиеся на такой панели, связаны с элементами типа "TAction" из "TActionList". В целевом проекте это выглядит примерно так:

void __fastcall TFormMain::CreateButtons(void)
{
  AskToolBar1->CreateButton(AExit, "Exit32");
  AskToolBar1->CreateButton(AUpdate, "TwoComps");
  AskToolBar1->CreateButton(AOptions, "Tools32");
}

На панели создаются кнопки типа TAskSpeedButton; 1-й параметр задаёт TAction, с которым связана кнопка, 2-й – наименование картинки, которая подгружается из заданной библиотеки образов (по умолчанию – AskImg.dll).

Если TAction->Enabled == false, кнопка не появится на панели.

В следующей статье будет рассмотрена более интересная тема – расширенная обработка исключений.


1 - некоторые компоненты из пакета "ASK Tools" производны от компонентов из свободно распространяемой библиотеки для Delphi и BCB «RX Library»

Часть 1 Часть 3
Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

Спринтхост — хостинг от 129 ₽ в месяц

Бесподобная поддержка, тестовый период 30 дней и домены от 149 ₽

Промокод на 30% кешбэк — CITFORUM

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Новости мира IT:

Архив новостей

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

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