Создание компонентов для KOL и MCK - Часть 1 - Создание невизуального KOL компонентаDelphi , Технологии , KOL и MCKСоздание компонентов для KOL и MCK - Часть 1 - Создание невизуального KOL компонентаВедущий раздела KOL и MCK: Анатолий aka XVeL Полную версию библиотеки 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 прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |