скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Создание компонентов для KOL и MCK - Часть 2 - Создание невизуальных MCK объектов



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

Создание невизуальных 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 . Работает!






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook