Зміст


  1. Введення
  2. Існуючі
    рішення
  3. Принципи
    побудови API-бібліотеки
  4. Бібліотека
    WinLite
  5. Приклад
    програми на основі бібліотеки WinLite

1. Введення


Будь-яку сучасну програму або програмну технологію можна представити як
сукупність програмних "шарів". Кожен з цих шарів виробляє свою
власну роботу, яка полягає у підвищенні рівня абстракції
вироблених операцій. Так, самий нижчий шар (шари) вводить поняття, які
дозволяють абстрагуватися від використовуваного обладнання; наступний шар (шари)
дозволяє програмісту абстрагуватися від складної послідовності викликів
функцій, вводячи таке поняття як протокол і т.д. Практично в будь-якому
сучасному програмному продукті можна знайти й виділити близько десятка
послідовних шарів абстракції.

Абстракція від устаткування і низькорівневих протоколів вводиться в ядра
операційних систем у вигляді бібліотек API (Application Program Interface). Однак
сучасні тенденції призводять до необхідності абстрагування і від самих
операційних систем, що дозволяє переносити програми з одного операційної
системи на іншу шляхом простої перекомпіляції (транслюються програми, в
основному, взагалі не вимагають ніяких дій з перенесення).

Абстракцію, яка доступна програмісту у вигляді бібліотек API можна назвати
базової. Це найнижчий рівень абстракції, який доступний для
прикладного програмування. На рівні ядра системи доступні і більш низькі
рівні абстракції, проте для їх використання необхідно розробляти
спеціалізовані програми (драйвера, модулі). Базовий рівень абстракції
(API) надає максимально широкі можливості для прикладного
програмування і є найбільш гнучким. Однак, програмування з
використанням API є набагато більш трудомістким і призводить до значно
більших обсягів вихідного коду програми, ніж програмування з використанням
додаткових бібліотек.

Додаткові бібліотеки поставляються з багатьма засобами розробки з
метою зменшення трудомісткості і термінів розробки програм, що в підсумку призводить
до підвищення їх конкурентоспроможності. Але застосування додаткових бібліотек
абстракцій призводить до різкого збільшення розмірів скомпільованих програм,
через те що в програму включається код використовуваних бібліотек, до того ж це
включення часто буває неефективним – у програму включаються невживані
ділянки коду. Крім того, чим більший рівень абстракції бібліотеки, тим складніше
її код, і тим більше труднощів виникає при вирішенні складних завдань. Доводиться
враховувати безліч взаємозв'язків та взаємних впливів окремих елементів і
процесів бібліотеки один на одного. Крім того, структура і функціональність
будь-якої бібліотеки звичайно розраховується на задоволення всіх потенційно
виникаючих завдань, що призводить до її громіздкості та неефективності.

У Delphi використовується дуже потужна і складна бібліотека VCL (Visual
Components Library), яка крім безпосередніх абстракцій вводить також і
безліч своїх функціональних класів. У цій бібліотеці знаходяться компоненти
для візуального відображення інформації, роботи з базами даних, із системними
об'єктами, компоненти для роботи з Internet-протоколами, класи для написання
своїх COM-об'єктів і багато чого іншого. Модулі бібліотеки підключаються до компіляції
у міру необхідності, однак базовий розмір найпростішого діалогового проекту з
однією формою перевищує 300кб (із статично скомпонована бібліотекою). І такий
розмір в багатьох випадках може виявитися дуже великим, особливо якщо
програма не вимагає великої функціональності в інтерфейсі.

Для вирішення цієї проблеми можна відмовитися від використання бібліотеки VCL, і
програмувати, використовуючи базовий набір функцій Win32 API. Однак, якщо при
розробці лінійних, недіалогових, нерезидентних програм не виникає жодних
труднощів, то розробка програм, що вимагають активної взаємодії з
користувачем або системою, стає трудомісткою. Структурне програмування,
рекомендований в таких випадках, виявляється неефективним і трудомістким.

Дана стаття присвячена проблемі створення і використання компактної
об'єктно-орієнтованої бібліотеки, яка б полегшила побудова невеликих і
ефективних програм на основі Win32 API.


2. Існуючі рішення


Автору відомі три об'єктно-орієнтовані бібліотеки, які можна
розглядати як альтернативу бібліотеці VCL при написанні компактних програм.
Це бібліотеки класів XCL, ACL і KOL. Всі бібліотеки безкоштовні і поставляються в
вихідних кодах.


















Бібліотека ACL (API control library)
Автор: Олександр Боковиков, Єкатеринбург, Росія
Сторінка: http://a-press.ur.ru/pc/bokovikov
E-Mail: abb@adx.ru
Класи і модулі: TFont, TFonts, TControl, TWinControl, TStdControl, TLabel, TEdit, TListBox,
TButton, TCheckBox, TComboBox, TGroupBox, TProgressBar,
TKeyboard


















Бібліотека XCL (Extreme class library)
Автор: Vladimir Kladov (Mr.Bonanzas)
Сторінка: http://xcl.cjb.net/
E-Mail: http://www.codenet.ru/progr/delphi/stat/bonanzas@xcl.cjb.net
Класи і модулі: XForm, XApplet, XCanvas, XPen, XBrush, XFont, ZDDB, ZHiBmp, ZDIBitmap,
ZBitmap, ZIcon, ZGifDecoder, ZGif, ZJpeg, XLabel, XButton, XBevel, XPanel,
XSplitPanel, XStatus, XGrep, XGroup, XCheckBox, XRadioBox, XPaint, XScroller,
XScrollBox, XScrollBoxEx, XEdit, XNumEdit, XCombo, XGrid, XListView, XMultiList,
XNotebook, XTabs, XTabbedNotebook, XCalendar, XGauge, XGaugePercents, XHysto,
XHystoEx, XImageList, XImgButton, XTooltip, XCustomForm, XDsgnForm,
XDsgnNonvisual, CLabel, CPaint, CButton, CEdit, CMemo, CCheckBox, CRadioBox,
CListBox, CComboBox, ZList, ZMenu, ZPopup, ZMainMenu, ZPopupMenu, ZTimer,
ZStrings, ZStringList, ZIniFile, ZThread, ZQueue, ZFileChange, ZDirChange,
ZOpenSaveDialog, ZOpenDirDialog, ZTree, ZDirList, ZDirListEx, ZRegistry,
ZStream, ZFileStream, ZMemoryStream, XStrUtils, XDateUtils, XFileUtils,
XWindowUtils, XPrintUtils, XShellLinks, XJustOne, XJustOneNotify, XPascalUnit,
XSysIcons, XCanvasObjectsManager, XRotateFonts, XFocusPainter,
XFormsStdMouseEvents, XFormsStdKeyEvents, XFormAutoSizer, XAligner,
XControlAutoPlacer, XMfcAntiFlicker, XSplitSizer, XResizeAntiFlicker,
XCaretShower, XEditMouseSelect, XEditClipboard, XEditUndo, XListMouseSel,
XListKeySel, XListEdit, ZNamedTags, XBtnRepeats, XBufLabels, XBackgrounds,
XWndDynHandlers


















Бібліотека KOL (Key object library)
Автор: Vladimir Kladov (Mr.Bonanzas)
Сторінка: http://xcl.cjb.net/
E-Mail: http://www.codenet.ru/progr/delphi/stat/bonanzas@xcl.cjb.net
Класи і модулі: TObj, TList, TGraphicTool, TCanvas, TControl, TTimer, TTrayIcon, TStream,
TStrList, TDirList, TIniFile

Як видно зі списку наведених для кожної бібліотеки класів, ці бібліотеки
предендуют скоріше не на допомогу при написанні програм з використанням Win32
API, а намагаються створити більш високий рівень абстракції ніж API, по крайней
мірою в графічної частини (особливо це відноситься до XCL). Більше того, ієрархія і
перелік об'єктів збігаються з відповідними структурами в бібліотеці VCL, що
швидше за все пов'язано з бажанням авторів забезпечити логічну сумісність з
VCL при побудові програм на основі цих бібліотек.

Дані бібліотеки не забезпечують мінімального розміру програми, за рахунок
того що надають більш високий рівень абстракції. Вони є
компромісом між програмуванням з використанням VCL і
програмуванням на чистому API.


3. Принципи побудови API-бібліотеки


тандартного виглядом API-програмування є структурне програмування.
Приклади такого програмування на Win32 API є практично в будь-якій книжці по
Borland Pascal, Borland C + +, Microsoft Visual C + + та інших систем розробки.
Безліч прикладів API-програмування на С міститься у постачанні Microsoft
Visual C++.

Структурне програмування з віконними функціями, процедурами обробки
команд, не в змозі забезпечити швидку і ефективну розробку програм. У
сучасної ситуації більшість програмістів звикло до
об'єктно-орієнтованого методу, з можливістю інкапсуляції, успадкування та
перевизначення методів об'єктів. Таке програмування виявляється найбільш
ефективним.

Крім того, для побудови ефективної API-бібліотеки перш за все потрібно
з'ясувати, які завдання при роботі з Win32 API є найбільш трудомісткими.
Практика показує, що найбільш незручним і трудомістким елементом є
реалізація основного диспетчера логіки програми – віконної функції. Реалізація
цієї функції в якості методу класу, а не простий глобальної функції,
дозволила б поліпшити структуру коду і полегшити програмування шляхом
інкапсулювання всіх змінних усередині віконного класу.

Програмування може бути ще більш полегшено, є возпользоваться
механізмом message-процедур мови Object Pascal. Виклик цих процедур повністю
лежить на компіляторі і кореневому об'єкті TObject і включає в себе методи
Dispatch, DefaultHandler, а також всі методи, оголошені з директивою message.
Таке рішення дозволить повністю відмовитися від громіздкого оператора case у
віконної функції.

З огляду на все перераховане вище автором була створена компактна бібліотека
віконних класів WinLite. Ця бібліотека є мінімальною, вона не вводить
більш високих рівнів абстракції ніж існують в Win32 API – вона тільки
полегшує роботу, перекладом програмування в об'єктно-орієнтоване русло.
Розмір бібліотеки дуже невеликий і вся вона поміщається в один модуль. Бібліотека
реалізує базовий клас TLiteFrame і побудовані на основі нього віконні класи:

Бібліотека може бути
використана спільно з VCL. На перший погляд, це можливість є
абсурдною і непотрібною, тому що про економію розміру в цьому випадку не може бути й
промови. Проте, іноді бувають моменти, коли реалізація специфічних віконних
елементів на основі об'єктів TWinControl або TCustomControl може бути
утруднена або неефективна через їх складності та неочевидного поведінки. У цьому
випадку, можна реалізувати такий елемент на базі класу TLiteWindow – він буде
вести себе стандартним чином, як і належить вести себе стандартному
віконному елементу Win32.

Завдяки своїй простій архітектурі бібліотека може бути використана в
многопоточной програмі. Звичайно, ви не зможете викликати методи класів одного
потоку з іншого потоку без відповідної синхронізації. Однак, ви можете
безперешкодно створювати віконні класи в різних потоках без блокування і
синхронізації, а також посилати повідомлення віконним класами в іншому потоці.

Практична порада: при API-програмуванні програміст винен сам стежити
за коректним звільненням численних ресурсів, які займає програма
під час виконання. Тому, для полегшення цього завдання використовуйте будь-яку
контролюючу утиліту, наприклад MemProof або Numega BoundsChecker. Коректне
звільнення зайнятих ресурсів вкрай необхідно!

Для редагування шаблонів діалогів можна використовувати будь-який редактор
ресурсів, наприклад Borland Resource WorkShop, правда він кілька незручний, а
остаточний результат все одно доводиться коригувати вручну.

Вся документація необхідна для API-програмування міститься в
поставляються компанією Microsoft компакт-дисках з документацією під загальним
назвою MSDN (Microsoft Developer "s Network). Існує online-версія
документації за адресою http://msdn.microsoft.com/. Урізана
версія MSDN, що містить основні файли допомоги, поставляється з Delphi.

Перш ніж ви вирішите працювати над своїм проектом в руслі Win32 API,
подумайте, а навіщо вам це потрібно? У переважній кількості випадків розмір програми
не має ніякого значення. Я не хочу сказати, що API-програмування складніше
ніж VCL-програмування. У багатьох випадках легше вивчити і написати 10 викликів
API з купою аргументів і розуміти, що відбувається, ніж написати 1 виклик простий,
на перший погляд, VCL-інструкції і потім довго досліджувати нетрі VCL в пошуках
відповіді. Просто API-програмування – це інша культура, до якої ви,
можливо, не звикли. І первинна робота може викликати у вас сильне
розчарування. API-програмування вимагає скрупульозності, ретельності і
уважного вивчення документації.

Ті ж, хто наважився програмувати на API, поряд з бібліотекою WinLite
можуть спільно використовувати невізуальні класи як зі складу VCL (модулі
SysUtils, Classes), так і багато сторонніх – природно, що розмір вашої
програми при цьому збільшиться.

Заслуговує
увагу робота Володимира Кладова по зміні функціональності обов'язкового
модуля system.pas. З часів перших версій Turbo Pascal цей модуль за замовчуванням
компонується у виконуваний код програми. Код модуля реалізує багато принципів і
рішення закладені в синтаксис і логіку мови Object Pascal, і зміна цього
модуля дозволяє модифікувати реалізацію цієї логіки. Таке рішення є
специфічним для мови Object Pascal на відміну, наприклад, від C / C + +, де
компілятор і абсолюдно всі модулі ніяк не пов'язані. Зміна модуля system.pas,
а саме його розбиття на блоки і скорочення рідко використовуваних ділянок коду
дозволило скоротити постійні (не змінні) витрати приблизно на 8 кб.
Звичайно, для великих проектів, таке скорочення може бути і непомітним, проте
цікавий сам принцип.

4. Бібліотека WinLite

 ////////////////////////////////////////////////// //////////////////////////////
/ / WinLite, бібліотека класів і функцій для роботи з Win32 API
/ / (C) Микола Мазуркін, 1999-2000
/ / _____________________________________________________________________________
/ / Віконні класи
////////////////////////////////////////////////// //////////////////////////////

unit WinLite;

interface

uses Windows, Messages;



Ініціалізаційний структури

Оголошення структур, які використовуються
для формування параметрів новостворюваних вікон і діалогів відповідно.

 ////////////////////////////////////////////////// //////////////////////////////
/ / Параметри для створення вікна
////////////////////////////////////////////////// //////////////////////////////
type
TWindowParams = record
Caption : PChar;
Style : DWord;
ExStyle : DWord;
X : Integer;
Y : Integer;
Width : Integer;
Height : Integer;
WndParent : THandle;
WndMenu : THandle;
Param : Pointer;
WindowClass : TWndClass;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Параметри для створення діалогу
////////////////////////////////////////////////// //////////////////////////////
type
TDialogParams = record
Template : PChar;
WndParent : THandle;
end;



Декларація базового класу TLiteFrame

Базовий клас для вікон і діалогів.
Інкапсулює в собі дескриптор вікна і оголошує загальну віконну процедуру.
Реалізує механізм message-процедур.

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteFrame
/ / _____________________________________________________________________________
/ / Базовий клас для об'єктів TLiteWindow, TLiteDialog, TLiteDialogBox
////////////////////////////////////////////////// //////////////////////////////
type
TLiteFrame = class(TObject)
private
FWndCallback: Pointer;
FWndHandle : THandle;
FWndParent : THandle;
function WindowCallback (hWnd: HWnd; Msg, WParam, LParam: Longint):
Longint; stdcall;
protected
procedure WindowProcedure(var Msg: TMessage); virtual;
public
property WndHandle: THandle read FWndHandle;
property WndCallback: Pointer read FWndCallback;
public
constructor Create(AWndParent: THandle); virtual;
destructor Destroy; override;
end;


Декларація віконного класу TLiteWindow

Створення унікального класу вікна
і створення вікна. Можливість субклассінга стороннього вікна.

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteWindow
/ / _____________________________________________________________________________
/ / Віконний клас
////////////////////////////////////////////////// //////////////////////////////
type
TLiteWindow = class(TLiteFrame)
private
FWndParams : TWindowParams;
FWndSubclass: Pointer;
protected
procedure CreateWindowParams (var WindowParams: TWindowParams); virtual;
public
procedure DefaultHandler(var Msg); override;
constructor Create(AWndParent: THandle); override;
constructor CreateSubclassed(AWnd: THandle); virtual;
destructor Destroy; override;
end;


Декларація діалогового класу TLiteDialog

Завантаження шаблону діалогу і
створення діалогу.

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteDialog
/ / _____________________________________________________________________________
/ / Діалоговий клас
////////////////////////////////////////////////// //////////////////////////////
type
TLiteDialog = class(TLiteFrame)
private
FDlgParams : TDialogParams;
protected
procedure CreateDialogParams (var DialogParams: TDialogParams); virtual;
public
procedure DefaultHandler(var Msg); override;
constructor Create(AWndParent: THandle); override;
destructor Destroy; override;
end;


Декларація модального діалогового класу TLiteDialogBox

Завантаження шаблону
діалогу і створення діалогу. Модальний показ діалогу.

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteDialogBox
/ / _____________________________________________________________________________
/ / Модальний діалоговий клас
////////////////////////////////////////////////// //////////////////////////////
type
TLiteDialogBox = class(TLiteFrame)
private
FDlgParams : TDialogParams;
protected
procedure CreateDialogParams (var DialogParams: TDialogParams); virtual;
public
procedure DefaultHandler(var Msg); override;
public
function ShowModal: Integer;
end;


Реалізація базового класу TLiteFrame

implementation

////////////////////////////////////////////////// //////////////////////////////
// TLiteFrame
/ / _____________________________________________________________________________
/ / Ініціалізація / фіналізація
////////////////////////////////////////////////// //////////////////////////////

////////////////////////////////////////////////// //////////////////////////////
/ / Конструктор
////////////////////////////////////////////////// //////////////////////////////
constructor TLiteFrame.Create(AWndParent: THandle);
begin
inherited Create;
/ / Запам'ятовуємо дескриптор батьківського вікна
FWndParent := AWndParent;
/ / Створюємо місце під блок зворотного виклику
FWndCallback: = VirtualAlloc (nil, 12, MEM_RESERVE or MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
/ / Формуємо блок зворотного виклику
asm
mov EAX, Self
mov ECX, [EAX].TLiteFrame.FWndCallback
mov word ptr [ECX+0], $6858 // pop EAX
mov dword ptr [ECX+2], EAX // push _Self_
mov word ptr [ECX+6], $E950 // push EAX
mov EAX, OFFSET(TLiteFrame.WindowCallback)
sub EAX, ECX
sub EAX, 12
mov dword ptr [ECX +8], EAX / / jmp TLiteFrame.WindowCallback
end;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Деструктор
////////////////////////////////////////////////// //////////////////////////////
destructor TLiteFrame.Destroy;
begin
/ / Знищуємо структуру блоку зворотного виклику
VirtualFree(FWndCallback, 0, MEM_RELEASE);
/ / Знищення за умовчанням
inherited;
end;

////////////////////////////////////////////////// //////////////////////////////
// TLiteFrame
/ / _____________________________________________________________________________
/ / Функції обробки повідомлень
////////////////////////////////////////////////// //////////////////////////////

////////////////////////////////////////////////// //////////////////////////////
/ / Функція зворотного виклику для отримання віконних повідомлень
////////////////////////////////////////////////// //////////////////////////////
function TLiteFrame.WindowCallback (hWnd: HWnd; Msg, WParam, LParam: Integer):
Longint;
var
WindowMsg : TMessage;
begin
/ / Запам'ятовуємо дескриптор вікна, якщо це перший виклик віконної процедури
if FWndHandle = 0 then FWndHandle := hWnd;
/ / Формуємо повідомлення
WindowMsg.Msg := Msg;
WindowMsg.WParam := WParam;
WindowMsg.LParam := LParam;
/ / Обробляємо його
WindowProcedure(WindowMsg);
/ / Повертаємо результат назад системі
Result := WindowMsg.Result;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Віртуальна функція для обробки віконних повідомлень
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteFrame.WindowProcedure(var Msg: TMessage);
begin
/ / Розподіляємо повідомлення по обробникам
Dispatch(Msg);
end;



Реалізація віконного класу TLiteWindow

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteWindow
/ / _____________________________________________________________________________
/ / Ініціалізація / фіналізація
////////////////////////////////////////////////// //////////////////////////////

////////////////////////////////////////////////// //////////////////////////////
/ / Конструктор
////////////////////////////////////////////////// //////////////////////////////
constructor TLiteWindow.Create(AWndParent: THandle);
begin
inherited;
/ / Формуємо параметри вікна
CreateWindowParams(FWndParams);
/ / Реєструємо клас вікна
RegisterClass(FWndParams.WindowClass);
/ / Створюємо вікно
with FWndParams do
CreateWindowEx(ExStyle, WindowClass.lpszClassName, Caption,
Style, X, Y, Width, Height,
WndParent, WndMenu, hInstance, Param
);
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Конструктор елемента з субклассінгом
////////////////////////////////////////////////// //////////////////////////////
constructor TLiteWindow.CreateSubclassed(AWnd: THandle);
begin
inherited Create(GetParent(AWnd));
/ / Зберігаємо віконну функцію
FWndSubclass := Pointer(GetWindowLong(AWnd, GWL_WNDPROC));
/ / Зберігаємо дескриптор вікна
FWndHandle := AWnd;
/ / Встановлюємо свою віконну функцію
SetWindowLong(FWndHandle, GWL_WNDPROC, DWord(WndCallback));
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Деструктор
////////////////////////////////////////////////// //////////////////////////////
destructor TLiteWindow.Destroy;
begin
/ / Наш об'єкт – об'єкт субклассиннга?
if FWndSubclass = nil then
begin
/ / Знищуємо клас вікна
UnregisterClass (FWndParams.WindowClass.lpszClassName, hInstance);
/ / Знищуємо вікно
if IsWindow(FWndHandle) then DestroyWindow(FWndHandle);
end
else
/ / Відновлюємо стару віконну функцію
SetWindowLong (FWndHandle, GWL_WNDPROC, DWord (FWndSubclass));
/ / Знищення за умовчанням
inherited;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Формування параметрів вікна за замовчуванням
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteWindow.CreateWindowParams (var WindowParams: TWindowParams);
var
WndClassName : string;
begin
/ / Формуємо ім'я класу
Str(DWord(Self), WndClassName);
WndClassName := ClassName+”:”+WndClassName;
/ / Заповнюємо інформацію про клас вікна
with FWndParams.WindowClass do
begin
style := CS_DBLCLKS;
lpfnWndProc := WndCallback;
cbClsExtra := 0;
cbWndExtra := 0;
lpszClassName := PChar(WndClassName);
hInstance := hInstance;
hIcon := LoadIcon(0, IDI_APPLICATION);
hCursor := LoadCursor(0, IDC_ARROW);
hbrBackground := COLOR_BTNFACE + 1;
lpszMenuName := “”;
end;
/ / Заповнюємо інформацію про вікно
with FWndParams do
begin
WndParent := FWndParent;
Caption := “Lite Window”;
Style := WS_OVERLAPPEDWINDOW or WS_VISIBLE;
ExStyle := 0;
X := Integer(CW_USEDEFAULT);
Y := Integer(CW_USEDEFAULT);
Width := Integer(CW_USEDEFAULT);
Height := Integer(CW_USEDEFAULT);
WndMenu := 0;
Param := nil;
end;
end;

////////////////////////////////////////////////// //////////////////////////////
// TLiteWindow
/ / _____________________________________________________________________________
/ / Функції обробки повідомлень
////////////////////////////////////////////////// //////////////////////////////

////////////////////////////////////////////////// //////////////////////////////
/ / Обробник повідомлень за замовчуванням
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteWindow.DefaultHandler(var Msg);
begin
/ / Наш об'єкт – об'єкт субклассиннга?
if FWndSubclass = nil then
/ / Викликаємо системну функцію обробки повідомлень
with TMessage(Msg) do
Result := DefWindowProc(FWndHandle, Msg, WParam, LParam)
else
/ / Викликаємо стару віконну функцію обробки повідомлень
with TMessage(Msg) do
Result: = CallWindowProc (FWndSubclass, FWndHandle, Msg, WParam, LParam);
end;



Реалізація діалогового класу TLiteDialog

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteDialog
/ / _____________________________________________________________________________
/ / Ініціалізація / фіналізація
////////////////////////////////////////////////// //////////////////////////////

////////////////////////////////////////////////// //////////////////////////////
/ / Конструктор
////////////////////////////////////////////////// //////////////////////////////
constructor TLiteDialog.Create(AWndParent: THandle);
begin
inherited;
/ / Формуємо параметри діалогу
CreateDialogParams(FDlgParams);
/ / Створюємо діалог
with FDlgParams do
CreateDialogParam (hInstance, Template, WndParent, WndCallback, 0);
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Деструктор
////////////////////////////////////////////////// //////////////////////////////
destructor TLiteDialog.Destroy;
begin
/ / Знищуємо діалог
if IsWindow(FWndHandle) then DestroyWindow(FWndHandle);
/ / Знищення за умовчанням
inherited;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Формування параметрів діалогу за умовчанням
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteDialog.CreateDialogParams (var DialogParams: TDialogParams);
begin
DialogParams.WndParent := FWndParent;
DialogParams.Template := “”;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Обробка повідомлень за замовчуванням
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteDialog.DefaultHandler(var Msg);
begin
/ / Значення, що повертаються за замовчуванням
with TMessage(Msg) do
if Msg = WM_INITDIALOG then Result := 1
else Result := 0;
end;



Реалізація модального діалогового класу TLiteDialogBox

 ////////////////////////////////////////////////// //////////////////////////////
// TLiteDialogBox
/ / _____________________________________________________________________________
/ / Ініціалізація / фіналізація
////////////////////////////////////////////////// //////////////////////////////

////////////////////////////////////////////////// //////////////////////////////
/ / Формування параметрів діалогу за умовчанням
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteDialogBox.CreateDialogParams (var DialogParams: TDialogParams);
begin
DialogParams.WndParent := FWndParent;
DialogParams.Template := “”;
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Активізація модального діалогу
////////////////////////////////////////////////// //////////////////////////////
function TLiteDialogBox.ShowModal: Integer;
begin
/ / Формуємо параметри діалогу
CreateDialogParams(FDlgParams);
/ / Показуємо діалог
with FDlgParams do
Result: = DialogBoxParam (hInstance, Template, WndParent, WndCallback, 0);
end;

////////////////////////////////////////////////// //////////////////////////////
/ / Обробка повідомлень за замовчуванням
////////////////////////////////////////////////// //////////////////////////////
procedure TLiteDialogBox.DefaultHandler(var Msg);
begin
/ / Значення, що повертаються за замовчуванням
with TMessage(Msg) do
if Msg = WM_INITDIALOG then Result := 1
else Result := 0;
end;

end.



5. Приклад програми на основі бібліотеки WinLite


У доданому прикладі, побудованому на основі розробленої автором бібліотеки
API-програмування WinLite, розглядаються такі проблеми:

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*