Любую передовую програмку либо программную технологию возможно предположить как совокупа программных “слоев”. Однако, каждый из данных слоев изготавливает вправду собственную свою работу, коя содержится в увеличении значения абстракции добросовестно выполняемых операций. Во всяком случае так, самый низший слой (слои) вводит понятия, которые дозволяют абстрагироваться от применяемого оборудования; грядущий слой (слои) разрешает программеру абстрагироваться от воистину трудоемкое очередности вызовов функций, вводя это понятие как протокол и т.п. Быть может практически во всяком взаправду современном по-особенному программном продукте можнож хладнокровно выявить и резко выделить в пределах 10-ка поочередных слоев абстракции.
Абстракция от оборудования и низкоуровневых протоколов вводится в ядра операционных систем повторяющий вид библиотек api (application program interface). Наконец, однако отчасти прогрессивные направленности глубоко приводят к надобности абстрагирования и от самих столь операционных систем, что разрешает сильно переносить программы с одной очень-то операционной системы на иную методом очень несложный перекомпиляции (транслируемые программы, как правило, вообщем не настоятельно совершенно просят практически никаких поступков по перенесению).
Абстракцию, коя мало-мальски доступна программеру торопливо повторяющий вид библиотек api возможно обычно именовать базисной. Кажется, это самый особенно маленький уровень абстракции, который в общем-то доступен для отчасти прикладного программирования. Надеюсь на уровне ядра системы в общем-то доступны и поболее совсем невысокие значения абстракции, впрочем для их применения нужно было проэктировать спец программы (драйвера, модули). Таким образом, столь базовый уровень абстракции (api) осторожно дает очень очень-то широкие полномочия для вполне прикладного программирования и относительно считается более столь эластичным. Так вот, однако, программирование с внедрением api относительно считается значительно наиболее особенно сложным и окончательно приводит к гораздо наибольшим размерам просто-таки начального кода программы, нежели программирование с применением вполне добавочных библиотек.
Дополнительные библиотеки поставляются со почти всеми средствами исследования имея цель убавления трудозатратности и сроков исследования программ, что в результате окончательно приводит к увеличению их конкурентноспособности. Но использование доп библиотек абстракций глубоко приводит к росту объемов откомпилированных программ, лишь потому что в програмку срабатывает код применяемых библиотек, кроме всего прочего данное подключение нередко постоянно посещает попросту малоэффективным - в програмку врубаются неиспользуемые участки кода. Кстати, кроме того, нежели более уровень абстракции библиотеки, тем труднее ее код, и тем более проблем гораздо встает во время выяснения взаправду трудоемких задач. Пожалуй, редко приходится самостоятельно учесть мало-мальски большое количество связей и вполне обоюдных воздействий по-своему отдельных составляющих и действий библиотеки приятель на приятеля. Вероятно, кроме того, текстура и работоспособность хоть какой библиотеки обыкновенно рассчитывается на ублажение всех потенциально окончательно образующихся задач, что специально приводит к ее громоздкости и неэффективности.
В delphi употребляется чрезвычайно однозначно сильная и просто-напросто трудная библиотека vcl (visual components library), коя кроме однозначно конкретных абстракций вводит и еще и полностью большое количество личных высокофункциональных классов. Говорят, в данной библиотеке пребывают составляющие для вправду зрительного отображения инфы, работы с базами этих, Полностью с системными объектами, составляющие для работы с internet-протоколами, классы для написания личных com-объектов и прочее. В конце концов, модули библиотеки подключаются к компиляции постепенно, но базисный объем обычнейшего по-человечески диалогового плана с одной формой скоро превосходит 300кБ (со взаправду статически скомпонованной библиотекой). В общем и таковой объем во почти всех вариантах правильно сможет окончательно оказаться очень столь немалым, вполне необыкновенно ежели программа срочно не просит немаленький функциональности в интерфейсе.
Для решения данной трудности можнож категорически отказаться от применения библиотеки vcl, и программировать, правильно используя базисный набор функций win32 api. Наверно, однако, раз при исследованию довольно-таки линейных, недиалоговых, нерезидентных программ поспешно не встает практически никаких проблем, то исследование программ, часто требующих очень интенсивного взаимодействия с юзером либо системой, делается трудозатратной. К счастью, по-человечески структурное программирование, советуемое при таких раскладах, как окончательно оказалось в целом малоэффективным и напросто сложным.
Данная заметка приурочена к задаче творения и применения малогабаритной объектно-ориентированной библиотеки, коя бы совершенно облегчила возведение не очень больших и просто-таки действенных программ на базе win32 api.
Автору знамениты 3 объектно-ориентированные библиотеки, которые можнож окончательно осматривать как кандидатуру библиотеке vcl при написании воистину малогабаритных программ. Видимо это библиотеки классов xcl, acl и kol. Действительно все библиотеки столь безвозмездны и поставляются очень-очень в начальных кодах.
Автор: Александр Боковиков, Екатеринбург, Российская Федерация
Классы и модули: tfont, tfonts, tcontrol, twincontrol, tstdcontrol, tlabel, tedit, tlistbox, tbutton, tcheckbox, tcombobox, tgroupbox, tprogressbar, tkeyboard
Классы и модули: x form , 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, xcustom form , xdsgn form , 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, x form sstdmouseevents, x form sstdkeyevents, x form autosizer, xaligner, xcontrolautoplacer, xmfcantiflicker, xsplitsizer, xresizeantiflicker, xcaretshower, xeditmouse select , xeditclipboard, xeditundo, xlistmousesel, xlistkeysel, xlistedit, znamedtags, xbtnrepeats, xbuflabels, xbackgrounds, xwnddynhandlers
Классы и модули: tobj, tlist, tgraphictool, tcanvas, tcontrol, ttimer, ttrayicon, tstream, tstrlist, tdirlist, tinifile
Как заметно из перечня приведенных для любой библиотеки классов, данные библиотеки предендуют предположительно на поддержка при написании программ с внедрением win32 api, а добровольно хотят сознательно сделать наиболее высочайший уровень абстракции нежели api, как минимум просто-таки в графической доли (очень-очень необыкновенно данное относится к xcl). Более того, иерархия и список объектов просто-напросто схожи с подходящими текстурами в библиотеке vcl, что наверное хладнокровно соединено с желанием творцов одновременно обеспечить очень-очень закономерную сопоставимость с vcl при построении программ на базе данных библиотек.
Данные библиотеки не гарантируют наименьшего объема программы, потому что спокойно дают наиболее высочайший уровень абстракции. По-видимому они относительно считаются компромисом меж программированием с применением vcl и программированием по-своему на чистом 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 - она лишь замечательно делает легче работу, переводом программирования в объектно-ориентированное русло. И все же размер библиотеки слишком не очень в общем-то большой и вся она вмещается в 1 модуль. Несомненно библиотека подробно продает базисный класс tliteframe и возведённые на базе него просто-напросто оконные классы:
tlitewindow - класс окошки, с вероятностью subclass’инга;
tlitedialog - класс немодального разговора;
tlitedialogbox - класс модального разговора.
Библиотека быть может применена общо с vcl. Следовательно на 1-ый взор, данное вероятность относительно считается особенно абсурдной и полностью негодной, потому что о экономии объема в такой ситуации лично не имеет возможности быть и речи. И действительно однако, время от времени часто случаются факторы, как скоро реализация однозначно нестандартных попросту оконных деталей на базе объектов twincontrol либо tcustomcontrol быть может затруднена либо слишком неэффективна в связи их трудности и неочевидного поведения. Так или иначе в данном варианте, возможно воплотить таковой составляющее на базе класса tlitewindow - он поведёт себя поистине обычным образом, как и окончательно надеется повести себя шаблонному налицо оконному составляющей win32.
Благодаря собственной несложной зодчестве библиотека быть может применена в многопоточной програмке. Видите ли конечно, вы не можете вызывать способы классов 1-го потока из иного потока в отсутствии подходящей синхронизации. По крайней мере однако, вам предоставляется возможность свободно лениво творить взаправду оконные классы очень-очень в разных потоках в отсутствии блокировки и синхронизации, а еще быстро высылать известия мало-мальски оконным классам в ином потоке.
Практический совет: при api-программировании разработчик по-человечески программного обеспечения обязан сам незаметно наблюдать вполне за корректным освобождением в целом множественных ресурсов, которые постепенно занимает программа при проведении. Поэтому, для облегчения данной задачки применяйте некоторую осуществляющую контроль утилиту, к примеру memproof или же numega boundschecker. Оказывается по-особенному корректное освобождение обычно занимающихся ресурсов очень нужно было !
Для редактирования шаблонов разговоров применяют каждый редактор ресурсов, к примеру borland resource workshop, истина он немного очень неудобен, а завершающий итог все одинаково редко приходится корректировать вручную.
Вся документация требуемая для api-программирования находится в поставляемых фирмой microsoft СD с документацией под налицо единым заглавием 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), но и почти все по-своему посторонние - природно, что объем вашей программы при всем при этом комично вырасти.
Невизуальные классы библиотеки acl - http://a-press.ur.ru/pc/bokovikov
Невизуальные классы библиотеки xcl - http://xcl.cjb.net
Системные составляющие на torry - http://www.torry.ru
Заслуживает внимание работа Владимира Кладова по изменению функциональности непременного модуля system.pas. Короче, со лет первых версий turbo pascal данный модуль по умолчанию компонуется добросовестно в выполняемый код программы. По правде говоря, код модуля слепо продаст почти все основы и решения добросовестно заложенные в синтаксис и логику языка object pascal, и перемена данного модуля дозволяет слепо изменить реализацию данной логики. А кроме того такое решение относительно считается вправду специфическим для языка object pascal в различие, к примеру, от c/c++, где компилятор и абсолюдно все модули никак добровольно не соединены. Одним словом изменение модуля system.pas, а непосредственно его разбиение на блоки и уменьшение нечасто применяемых участков кода свободно разрешило ужать по-человечески многократные (Полностью не переменные) потери приблизительно на 8 кБ. Судя по всему конечно, для великих планов, это уменьшение быть может и особенно незначительным, впрочем совсем занимателен сам принцип.
Модифицированный модуль system.pas - http://xcl.cjb.net
////////////////////////////////////////////////////////////////////////////////
// winlite, библиотека классов и функций для работы с win32 api
// _____________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////
unit winlite;
uses windows, messages;
Объявление текстур, которые применяются для формирования характеристик опять сознательно творимых окошек и разговоров в соответствии с этим.
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
caption : pchar;
style : dword;
exstyle : dword;
x : integer;
y : integer;
width : integer;
height : integer;
wndparent : thandle;
wndmenu : thandle;
param : pointer;
windowclass : twndclass;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
template : pchar;
wndparent : thandle;
end;
Базовый класс для окошек и разговоров. Не правда ли инкапсулирует внутри себя дескриптор окошки и категорически заявляет по-своему единую в целом оконную упражнение. Как ни странно специально реализует приспособление message-процедур.
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
// Базовый класс для объектов tlitewindow, tlitedialog, tlitedialogbox
////////////////////////////////////////////////////////////////////////////////
fwndcallback: pointer;
fwndhandle : thandle;
fwndparent : thandle;
function windowcallback(hwnd: hwnd; msg, wparam, lparam:longint):
longint; stdcall;
procedure windowprocedure( var msg: tmessage); virtual;
property wndhandle: thandle read fwndhandle;
property wndcallback: pointer read fwndcallback;
constructor create(awndparent: thandle); virtual;
destructor destroy; override;
end;
Создание оригинального класса окошка и творение окошка. Допустим возможность субклассинга более-менее постороннего окошка.
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
// Оконный воссоздаваемыми//////////////////////////////////////////////////////////
fwndparams : twindowparams;
fwndsubclass: pointer;
procedure createwindowparams( var windowparams: twindowparams); virtual;
procedure defaulthandler( var msg); override;
constructor create(awndparent: thandle); override;
constructor createsubclassed(awnd: thandle); virtual;
destructor destroy; override;
end;
Загрузка шаблона разговора и творение разговора.
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
// Диалоговый воссоздаваемыми//////////////////////////////////////////////////////////
fdlgparams : tdialogparams;
procedure createdialogparams( var dialogparams: tdialogparams); virtual;
procedure defaulthandler( var msg); override;
constructor create(awndparent: thandle); override;
destructor destroy; override;
end;
Декларация модального диалогового класса tlitedialogbox
Загрузка шаблона разговора и творение разговора. Удивительно, что модальный ужасно тосковавшую/////////////////////
// _____________________________________________________________________________
// Модальный диалоговый воссоздаваемыми//////////////////////////////////////////////////////////
fdlgparams : tdialogparams;
procedure createdialogparams( var dialogparams: tdialogparams); virtual;
procedure defaulthandler( var msg); override;
function showmodal: integer;
end;
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
constructor tliteframe.create(awndparent: thandle);
inherited create;
fwndparent := awndparent;
fwndcallback := virtualalloc(nil,12,mem_reserve or mem_commit,
page_execute_readwrite);
mov dword ptr [ecx+2], eax // push _self_
mov word ptr [ecx+6], $e950 // push eax
mov dword ptr [ecx+8], eax // jmp tliteframe.windowcallback
end;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
destructor tliteframe.destroy;
virtualfree(fwndcallback, 0, mem_release);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Функция обратного вызова для получения оконных известий
////////////////////////////////////////////////////////////////////////////////
function tliteframe.windowcallback(hwnd: hwnd; msg, wparam, lparam: integer):
longint;
windowmsg : tmessage;
// Запоминаем дескриптор окошки, ежели данное 1 вызов вправду оконной упражнения
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);
dispatch(msg);
end;
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
constructor tlitewindow.create(awndparent: thandle);
inherited;
createwindowparams(fwndparams);
registerclass(fwndparams.windowclass);
createwindowex(exstyle, windowclass.lpszclassname, caption,
);
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
constructor tlitewindow.createsubclassed(awnd: thandle);
inherited create(getparent(awnd));
fwndsubclass := pointer(getwindowlong(awnd, gwl_wndproc));
fwndhandle := awnd;
// Устанавливаем собственную оконную детскому саду///////////////////////////////
destructor tlitewindow.destroy;
// Наш объект - объект субклассиннга ?
unregisterclass(fwndparams.windowclass.lpszclassname, hinstance);
if iswindow(fwndhandle) then destroywindow(fwndhandle);
setwindowlong(fwndhandle, gwl_wndproc, dword(fwndsubclass));
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
procedure tlitewindow.createwindowparams( var windowparams: twindowparams);
wndclassname : string;
str(dword(self), wndclassname);
wndclassname := classname+’:'+wndclassname;
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;
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;
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
procedure tlitewindow.defaulthandler( var msg);
// Наш объект - объект субклассиннга ?
result := defwindowproc(fwndhandle, msg, wparam, lparam)
// Вызываем ветхую оконную функцию обработки известий
result := callwindowproc(fwndsubclass, fwndhandle, msg, wparam, lparam);
end;
////////////////////////////////////////////////////////////////////////////////
// _____________________________________________________________________________
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
constructor tlitedialog.create(awndparent: thandle);
inherited;
createdialogparams(fdlgparams);
createdialogparam(hinstance, template, wndparent, wndcallback, 0);
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
destructor tlitedialog.destroy;
if iswindow(fwndhandle) then destroywindow(fwndhandle);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
// Формирование характеристик разговора по умолчанию
////////////////////////////////////////////////////////////////////////////////
procedure tlitedialog.createdialogparams( var dialogparams: tdialogparams);
dialogparams.wndparent := fwndparent;
dialogparams.template := ”;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
procedure tlitedialog.defaulthandler( var msg);
else result := 0;
end;
Реализация модального диалогового предложу финализация
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Формирование характеристик разговора по умолчанию
////////////////////////////////////////////////////////////////////////////////
procedure tlitedialogbox.createdialogparams( var dialogparams: tdialogparams);
dialogparams.wndparent := fwndparent;
dialogparams.template := ”;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
function tlitedialogbox.showmodal: integer;
createdialogparams(fdlgparams);
result := этом случае/////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
procedure tlitedialogbox.defaulthandler( var msg);
else result := 0;
end;
end.
Архив > Delphi/Pascal > DELPHI FAQ (по темам) > WINAPI
Вы должны быть зарегистрироавны чтобы оставить комментарий.