Delphi World - Создание компонентов для KOL и MCK - Часть 2 - Создание невизуальных MCK объектов
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Создание компонентов для KOL и MCK - Часть 2 - Создание невизуальных MCK объектов

Ведущий раздела KOL и MCK: Анатолий aka XVeL
Автор: Жаров Дмитрий aka Gandalf
WEB-сайт: http://kol.mastak.ru

Полную версию библиотеки KOL и MCK можно скачать здесь

Создание невизуальных MCK объектов: Нечего на Mirror пенять коль…

Возможно, после завершения прошлой главы у вас осталось двоякое чувство, с одной стороны мы сделали KOL компонент, с другой не на йоту не пододвинулись к MCK и компонентом в палитре пока и не пахнет. Для того, что понять, как делать MCK компоненты, разберемся что это. Итак, если посмотреть на код нашего проекта (KOL и MCK ) мы увидим строку:
{$I Unit1_1.inc}
Посмотрев же сам файл, мы в нем увидим код, который фактически создает компоненты и настраивает их свойства и подобное в соответствии с нашими действиями во время разработки. Т.е. фактически MCK компонент это инструмент, который позволяет изменять свои свойства (аналогичные свойствам KOL компонента) и генерирует необходимые строки в выше указанном файле. Возможно, самые шустрые уже все поняли и побежали реализовать данный механизм вручную, но не торопитесь! Автор добавил в MCK базовые классы, которые, переопределив часть методов, позволят нам осуществлять этот механизм довольно просто. Приступим. Создадим файл MCKMHAboutDialog.pas:

unit MCKMHAboutDialog;

interface

uses
  KOL, KOLMHAboutDialog, Mirror, MCKObjs, Classes, Graphics;

type
  TKOLMHAboutDialog = class(TKOLObj)
  private
     FTitle: String;
     FCopyRight: String;
     FText: String;
     FIcon: TIcon;
     FIconType: TIconType;
     procedure SetTitle(const Value: String);
     procedure SetCopyRight(const Value: String);
     procedure SetText(const Value: String);
     procedure SetIcon(const Value: TIcon);
     procedure SetIconType(const Value: TIconType);

   protected
     function AdditionalUnits: string; override;
     procedure SetupFirst(SL: TStringList; const AName,AParent, Prefix: String);  override;
     function SetupParams(const AName, AParent: String): String;

   public
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;

   published
     property Title: String read FTitle write SetTitle;
     property CopyRight: String read FCopyRight write SetCopyRight;
     property Text: String read FText write SetText;
     property Icon: TIcon read FIcon write SetIcon;
     property IconType: TIconType read FIconType write SetIconType;
end;

procedure Register;

implementation

constructor TKOLMHAboutDialog.Create(AOwner: TComponent);
begin
  inherited;
  FTitle := 'О программе "Программа"';
  FCopyRight := 'CopyRight 1984-2001 Ваша Фирма';
  FText := 'Программа';
  FIcon := TIcon.Create;
  FIconType := itApplication;
end;

destructor TKOLMHAboutDialog.Destroy;
begin
  FIcon.Free;
  inherited;
end;

function TKOLMHAboutDialog.AdditionalUnits;
begin
  Result := ', KOLMHAboutDialog';
end;

procedure TKOLMHAboutDialog.SetupFirst(SL: TStringList; const AName, AParent, Prefix: String);
const
  IconType2Str: array [TIconType] of String = ('itShell', 'itApplication', 'itCustom');
var
  RsrcName, RsrcFile: String;
begin
  inherited;
  SL.Add(Prefix + AName + '.Title:=' + String2PascalStrExpr(Title) + ';');
  SL.Add(Prefix + AName + '.CopyRight:=' + String2PascalStrExpr(CopyRight) + ';');
  SL.Add(Prefix + AName + '.Text:=' + String2PascalStrExpr(Text) + ';');
  if Icon.Empty then
    SL.Add(Prefix + AName + '.Icon:=0;')
   else
   begin
     RsrcName := UpperCase(ParentKOLForm.FormName + '_' + Name);
     RsrcFile := ParentKOLForm.FormName + '_' + Name;
     SL.Add(Prefix + AName + '.Icon:=LoadIcon(hInstance,' + 
	   String2PascalStrExpr(RsrcName) + ')' + ';');
     SL.Add(Prefix + ' {$R ' + RsrcFile + '.RES}');
     GenerateIconResource(Icon, RsrcName, RsrcFile, fUpdated);
   end;
   SL.Add(Prefix + AName + '.IconType:=' + IconType2Str[IconType] + ';');
end;

function TKOLMHAboutDialog.SetupParams(const AName, AParent: String): String;
begin
  Result := '';
end;

procedure TKOLMHAboutDialog.SetTitle(const Value: String);
begin
  FTitle := Value;
  Change;
end;

procedure TKOLMHAboutDialog.SetCopyRight(const Value: String);
begin
  FCopyRight := Value;
  Change;
end;

procedure TKOLMHAboutDialog.SetText(const Value: String);
begin
  FText := Value;
  Change;
end;

procedure TKOLMHAboutDialog.SetIcon(const Value: TIcon);
begin
  FIcon.Assign(Value);
  Change;
end;

procedure TKOLMHAboutDialog.SetIconType(const Value: TIconType);
begin
  FIconType := Value;
  Change;
end;

procedure Register;
begin
  RegisterComponents('KOL Dialogs', [TKOLMHAboutDialog]);
end;

end.

Обратите внимания на названия файла, но более на название нашего класса (TKOLMHAboutDialog) оно должно соответствовать тому, что объявляли в KOL компоненте.
Теперь поясним код. Наследуемся мы от класса TKOLObj, он создан специально для создания не визуальных MCK компонентов - хотя ни кто не мешает делать по-другому, но думаю, ваш путь станет сложнее.
Обращаю ваше внимание на то, что ни одна строка кода их MCK части не попадет в исполняемый файл, то есть не гонитесь за оптимизацией - это ничего не даст, не ловите байты - это никому не нужно, и уж конечно не используйте ассемблер. Поймите, вы ни чем не улучшите ситуацию, а здоровье не вернешь. Так же забудь о классическом (для VCL) обороте:

procedure TKOLMHAboutDialog.SetIconType(const Value: TIconType);
begin
  if Value<>FiconType then
    FIconType:=Value;
  …


В MCK компоненте это не нужно, поскольку незаметно отражается на быстродействии, в KOL это не нужно тоже, кто-то может сказать, как же так, а вот так, довольно редко бывает так, чтобы эта проверка срабатывала, а код увеличивается, чуть ли не в двое, если уж у вас такая ситуация, что вы часто присваиваете одинаковые значения - вставьте проверку в код вашей программы перед присваиванием.
Я думаю, секции private и published вас не смущают, поэтому на них останавливаться не будем. Перейдем к процедурам из разделов protected и public. Первое что вам следует запомнить - не забывайте ставить override в описании методов, иначе у вас вряд ли что будет работать. Create и Destroy не получили нового смысла, в Create вы можете указать значения компонента по умолчанию, что я и сделал. Далее обратим взор к разделу protected. AdditionalUnits - этот метод возвращает строку с названиями тех модулей, которые необходимы для работы KOL компонента (тут только - KOLMHAboutDialog). Не забывайте запятые перед модулями, но в конце запятую ставить не надо.
Идем дальше SetupParams - возвращает строку с параметрами функции New, но поскольку у нас, их нет, мы вернули пустую строку. Если бы они были, нам надо было вернуть строку вида ' Param1, Param2 …,ParamN ' запятой в конце также нет.
SetupFirst - вызывается раньше всех предшествующих функций, в ней добавляем, необходимы строки, фактически устанавливаем значения свойств, которые мы установили во время разработки. Здесь мы использовали inherited, чтобы вызвать метод определенный у предка - он создаст вызов New функции, правда уже с нашими новыми параметрами, ведь мы переопределили метод SetupParams. Последний возможно непонятный момент:

        
if Icon.Empty then
  SL.Add(Prefix + AName + '.Icon:=0;')
else
begin
  RsrcName := UpperCase(ParentKOLForm.FormName + '_' + Name);
  RsrcFile := ParentKOLForm.FormName + '_' + Name;
  SL.Add(Prefix + AName + '.Icon:=LoadIcon(hInstance,' + String2PascalStrExpr(RsrcName) + ')' + ';');
  SL.Add(Prefix + ' {$R ' + RsrcFile + '.RES}');
  GenerateIconResource(Icon, RsrcName, RsrcFile, fUpdated);
end;


Но тут нет ничего страшного, просто создается файл ресурсов с иконкой, GenerateIconResource стандартная функция KOL и MCK специально для этого и созданная, она генерирует скрипт файл и компилирует ресурс. Главное это сделать уникальное имя файла, мы поступаем просто, создаем его из имени формы и имени компонента - уникальная комбинация.
Ну что же, добавим ресурс для иконки компонента, откомпилируем и получаем новый компонент уже KOL и MCK . Работает!

Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования