|  | 
|      | 
|   | 
| Создание компонентов для KOL и MCK - Часть 1 - Создание невизуального KOL компонентаDelphi , Технологии , KOL и MCKВведение: Дорога из желтого кирпича С появлением KOL, а после и MCK в программировании под Delphi началась новая эпоха - стало возможно создавать быстро, быстрый и легкий код, не отказываясь от любимого языка. Но среди достоинств этого, на данной стадии развития - есть и недостатки, нехватка компонентов, сравнимая почти с нехваткой воздуха, и что самое главное, нехватка людей, которые могут их написать. Данная статья ставит себе целью изменить ситуацию и перевести написание компонентов для KOL и MCK из разряда "для избранных" в разряд "для всех". При этом она не в коей мере не ставит себе целью обучением вас Delphi, KOL, MCK считается, что эти знания у вас уже есть. Материал преподносится в форме "от простого к сложному", и так начнем. Создание не визуального KOL компонента: Шапка невидимка 
TNewKOLUnVisual = object(TObj)
         private
         public
         end;Заметьте, что когда я сказал объект, я имел в виду именно объект, а не класс! Такова особенность модели наследования KOL, к ней придется привыкнуть. Данный переход на "устаревшую" модель обусловлен ее эффективностью и спецификой внутренней реализации, что дало возможность построить на ее основе KOL. Далее, чтобы наше повествование не было некой абстракцией, давайте перейдем на построение компонента, я взял за пример постройку AboutDialog.  unit KOLMHAboutDialog;
interface
uses
  KOL;
type
  PMHAboutDialog =^TMHAboutDialog;
  TKOLMHAboutDialog = PMHAboutDialog;
  TMHAboutDialog = object(TObj)
  private
  public
       
end;
implementation
end.Как можно заметить модуль называется, как и файл, знакомьтесь это шаблон компонента. После беглого просмотра можно увидеть две строки значение коих еще не объяснялось: PMHAboutDialog =^TMHAboutDialog; TKOLMHAboutDialog = PMHAboutDialog; Эти строки также результат специфики KOL, поскольку мы в KOL работаем не с самими объектами, а с указателями на них. Потому мы и написали первую строку. Вторая нужна для психологического успокоения нас и компилятора, поскольку механизм MCK, как мы увидим позже, использует именно этот тип.  unit KOLMHAboutDialog;
interface
uses
  KOL, Windows, ShellAPI;
type
  TIconType = (itShell, itApplication, itCustom);
  PMHAboutDialog =^TMHAboutDialog;
  TKOLMHAboutDialog = PMHAboutDialog;
  TMHAboutDialog = object(TObj)
    private
    FTitle: String;
    FCopyRight: String;
    FText: String;
    FIcon: HIcon;
    FIconType: TIconType;
    public
    property Title: String read FTitle write FTitle;
    property CopyRight: String read FCopyRight write FCopyRight;
    property Text: String read FText write FText;
    property Icon: HIcon read FIcon write FIcon;
    property IconType: TIconType read FIconType write FIconType;
end;
implementation
end.
Думаю, что никто для себя ничего нового не нашел. Но мог возникнуть вопрос, зачем все вынесено в свойства, когда в этом нет необходимости (чтение и запись идут напрямую), отвечу - как пример, и поскольку необходимости в этом действительно нет, мы переделаем код: unit KOLMHAboutDialog; interface uses KOL, Windows, ShellAPI; type TIconType = (itShell, itApplication, itCustom); PMHAboutDialog = ^TMHAboutDialog; TKOLMHAboutDialog = PMHAboutDialog; TMHAboutDialog = object(TObj) private public Title: String; CopyRight: String; Text: String; Icon: String; IconType: TIconType; end; implementation end. Если посмотреть размер, после этих несложных манипуляций уменьшился почти в 2 раза. Да, если кого удивило появление модулей Windows и ShellAPI, не пугайтесь, они понадобиться чуть позже. Ну что же пора вносить работоспособность в компонент, сделаем это добавив два метода Destroy и Execute: unit KOLMHAboutDialog;
interface
uses
  KOL, Windows, ShellAPI;
type
  TIconType = (itShell,itApplication,itCustom);
  PMHAboutDialog = ^TMHAboutDialog;
  TKOLMHAboutDialog = PMHAboutDialog;
  TMHAboutDialog = object(TObj)
    private
    public
      Title: String;
      CopyRight: String;
      Text: String;
      Icon: HIcon;
      IconType: TIconType;
      destructor Destroy; virtual;
      procedure Execute;
end;
implementation
destructor TMHAboutDialog.Destroy;
begin
  DestroyIcon(Icon);
  inherited;
end;
procedure TMHAboutDialog.Execute;
var
  HWndOwner: THandle;
  TMPIcon: HIcon;
begin
  if Assigned(Applet) then
    HWndOwner := Applet.Handle
  else
    HWndOwner := 0;
  case IconType of
    itShell: TMPIcon := 0;
    itApplication: TMPIcon := Applet.Icon;
    itCustom: TMPIcon := Icon;
  end;//case
  ShellAbout(HWndOwner, PChar(Title + '#' + Text), PChar(CopyRight), TMPIcon);
end;
end.
Начнем разбираться, Destroy (не забывайте virtual, а то компилятор не пустит). Фактически в нем идет освобождение ресурса иконки (Проверку на наличие иконки делать не надо, поскольку мы используем функцию DestroyIcon - если иконку уничтожить нельзя она вернет не нуль, но программа будет работать корректно), а далее выполнения Destroy предка. Метод Execute не должен вызывать испуга у людей знакомых с API. Вопрос может возникнуть только по поводу переменной Applet - это глобальная переменная из KOL типа PControl, аналог Application из Delphi. У наблюдательных читателей, возможно, возник вопрос: Destroy есть, а где Create? Будет, вот он: unit KOLMHAboutDialog;
interface
uses
  KOL, Windows, ShellAPI;
type
  TIconType = (itShell, itApplication, itCustom);
  PMHAboutDialog = ^TMHAboutDialog;
  TKOLMHAboutDialog = PMHAboutDialog;
  TMHAboutDialog = object(TObj)
    private
    public
      Title: String;
      CopyRight: String;
      Text: String;
      Icon: HIcon;
      IconType: TIconType;
      destructor Destroy; virtual;
      procedure Execute;
end;
function NewMHAboutDialog: PMHAboutDialog;
implementation
function NewMHAboutDialog:PMHAboutDialog;
begin
  New(Result, Create);
end;
destructor TMHAboutDialog.Destroy;
begin
  DestroyIcon(Icon);
  inherited;
end;
procedure TMHAboutDialog.Execute;
var
  HWndOwner: THandle;
  TMPIcon: HIcon;
begin
  if Assigned(Applet) then
    HWndOwner := Applet.Handle
  else
    HWndOwner := 0;
  case IconType of
    itShell: TMPIcon := 0;
    itApplication: TMPIcon := Applet.Icon;
    itCustom: TMPIcon := Icon;
  end;//case
  ShellAbout(HWndOwner, PChar(Title + '#' + Text), PChar(CopyRight), TMPIcon);
end;
end.
Те кто задавали этот вопрос, наверное, ждали нечто иное чем внешнюю функцию NewMHAboutDialog, но ничего не поделаешь KOL. Помните, я говорил, что нам придется работать с указателями, да и ООП модель у нас на базе объектов, а не классов. Сама функция как мы видим, выделяет память для объекта. uses … {$ENDIF}, KOLMHAboutDialog; …
var
 TMP: TKOLMHAboutDialog;
begin
  TMP := NewMHAboutDialog;
  TMP.Execute;
  TMP.Free;
end;
Запустили, посмотрели - работает. var TMP: TKOLMHAboutDialog; begin TMP := NewMHAboutDialog(0); TMP.Execute; TMP.Free; end; Замечаете, мы фактически задаем ненужный параметр, да к тому же сама функция New потолстела (правда несильно). Тут мы выигрываем не много (байты), но это принципиальный момент. Много помалу - много! В этой статье описывается создание компонента для KOL и MCK, начиная с невизуального KOL-компонента. Автор объясняет принципы работы с указателями на объекты в КОЛ, а также показывает пример создания компонента AboutDialog. Он подчеркивает важность исполь Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш  
 | ||||
|  ©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 | ||||