Если хотите создать веб-сайт на WordPress вам стоит посетить www.internet-technologies.ru.

Быстрое написание программ на WinAPI

Автор: Алексей Шишкин

Все программисты делятся на две группы – oldschool и новую волну. Сыны старой школы помнят историю о 640 килобайтах, помнят о тысяче игр на одной дискете… Новая волна, чаще всего, даже не знает устройство компьютера, но так же считается – программистами. Использование IDE изменило представление о программистах. Посмотрим, что же может дать отказ от визуального программирования. В этой статье я опишу один из способов быстрого написания приложений с использованием функций WinAPI.

Вступление или «Кому это нужно?»

Вы можете задаться вопросом, зачем же насиловать свой мозг, если давным-давно изобретена VCL, MFC и прочие прелести визуального программирования? Для ответа на этот вопрос давайте посмотрим на плюсы и минусы визуального и низкоуровневого* программирования.

* Комментарий автора.

Здесь под низкоуровневым программированием я имею в виду программирование без использования графических компонентов — использование функций WinAPI напрямую для создания окон, работы с графикой и т.д.

Итак, рассмотрим плюсы визуального программирования:

быстрое написание программ (достаточно накидать кнопок на форму и написать их процедуры);

удобство использования (это удобнее, чем описывать каждый шаг на низком уровне, не нужно заботиться о памяти).

И минусы:

огромный размер приложений — «пустое» приложение на Delphi «весит» ~300 кб;

из-за огромного количества надстроек быстродействием приходится пренебречь, особенно в плане графики на Canvas.

И в противоположность, рассмотрим плюсы низкоуровневого программирования на WinAPI:

малый размер конечных файлов (согласитесь, что между 30 кб и 300 кб есть большая разница);

быстродействие на достаточно высоком уровне (быстрее получится только, если писать целиком на ассемблере – то еще удовольствие).

И минусы:

нет визуализации (труднее представить, что создать, что уничтожить, что где писать);

для создания обычного окна потребуется примерно 50 строк кода (создать и зарегистрировать само приложение, создать окно, заботиться о всех параметрах);

необходимо помнить о необходимости следить за использованием памяти — освобождением, взятием. Здесь обычным *.Free не обойдешься.

Но, если мы представим, что избавились о минусах программирования на WinAPI, чаша весов склонится в сторону низкоуровневого программирования. Так как же нам от них избавиться? Итак, взглянем в сторону фреймворков, которые это позволяют. За всю мою практику программирования на Delphi сталкивался с таким только единожды** – APIx 2 (Visual WinAPI). Но данное средство разработки не предполагает активное использование графики, только создание окон и кнопок. Поэтому я решил создать такую библиотеку, которая позволит не только быстро создавать окна, но и активно использовать графику.

Не хвастаясь особо, сообщу, что мне это удалось. И через три недели разработки GRAY FUR был готов.

** Комментарий автора.

Не сомневаюсь, что существуют и другие, но они остались вне моего поля зрения. Хотя я допускаю, что никто просто не думал о таком — все привыкли к визуальному программированию.

WTF… или что это даст?

Mon ami, это же элементарно: не нужно заботиться о расходе и приходе памяти, размышлениям о бренности окон. Да, мы по прежнему не имеем дела с визуальностью, но, согласитесь, что намного удобнее вызвать одну процедуру, чем записывать пару десятков с многочисленными параметрами. Так, например отрисовать текстуру на экране можно так:

 
Var
  Loc : HDC;
  TNum : Integer;
 Begin
  Loc := CreateCompatibleDC(DC);
  SelectObject(Loc, Bitmap);
  BitBlt(DC,
           X, Y,
            Width,
            Height,
            Loc,
            0, 0,
            SRCCOPY);
  DeleteDC(Loc);
End;

А можно и так:

 
Draw(Form1, Num, X, Y, FALSE);
BufferDraw;

Причем, если мы не подумаем о том, как создать двойную буферизацию в первом случае изображение будет мерцать при отрисовке. Во втором случае все это уже встроено в систему.

Panic button

Рассмотрим написание Panic button с использованием нашей системы. Для того, кто еще не читал моей статьи о создании Panic Button на WinAPI [1] поясню, что эта кнопка на экране будет сворачивать все окна по нажатию на нее.

Итак, скачаем *** FrameWork и посмотрим, как же это делается. По привычке, я буду делать это на Lazarus, но вы так же можете использовать Delphi, используя пакет для разработки под Delphi.

*** Комментарий автора.

Все ссылки представлены в конце статьи.

Для начала создадим то, что кнопка должна делать:

 
Procedure HideAll(Handle : HWND); // Эту процедуру будем использовать по клику левой кнопки мыши
Begin
 Keybd_event(VK_LWIN,0,0,0); // Эмулируем нажатие клавиши Win
 Keybd_event(VK_D ,0,0,0); // Эмулируем нажатие клавиши D
 Keybd_event(VK_D ,0,KEYEVENTF_KEYUP,0); // Отпустим D - все окна свернутся
 Keybd_event(VK_LWIN,0,KEYEVENTF_KEYUP,0); // Отпустим Win.
End;

Так же сделаем процедуру закрытия приложения:

 
Procedure KillMe(Handle : HWND); // Процедура жестокого убийства
Begin
 DestroyTimer(ID); // Удалим таймер, созданием которого мы еще займемся
 DestroyApplication; // Уничтожим приложение
End;

И для полного счастья сделаем так, чтобы кнопка всегда была наверху:

 
Procedure OnTop;
Begin
SetformOnTop(Form1, TRUE); // Установим её всегда сверху.
End;

Да, и еще создадим функцию для вычисления вертикальной позиции:

 
Function CalculateYp : Integer;
Var
R : Rect;
H : Handle;
W : Integer;
PH : Integer;
Begin
W := GetSystemMetrics(SM_CYSCREEN); // Получаем вертикальное разрешение
ZeroMemory(@R, SizeOf(R));
H := FindWindow('Shell_TrayWnd', Nil); // Найдем окно панели задач
GetWindowRect(H, R); // Его размеры
PH := R.Bottom - R.Top; // Вычислим высоту
Result := W - PH - Form1.Height; // И получим искомое
End;

Рассмотрим само тело программы:

 
program Project1;

{$mode delphi}{$H+} // Директивы для Lazarus

Uses
Windows, // Подключим Windows
Scow; // Подключим модуль-связку проекта

Var
Form1 : TForm; // Наше главное окно. Тип описан в Scow
ID : Integer; // ID таймера

// Здесь находятся процедуры, описанные выше
begin
CreateApplication; // Создаем приложение

SetApplicationReaction1(HN_LBUTTONDOWN, HideAll); // Назначим событие по левому клику
SetApplicationReaction1(HN_RBUTTONDOWN, KillMe); // Назначим событие по правому клику

CreateForm(Form1, FALSE); // Создадим форму FALSE - не показывать на панели задач
ShowForm(Form1, TRUE); // Покажем ее на экране
ResizeForm(Form1, 64, 64); // Назначим размеры
MoveForm(Form1, 0, CalculateYp); // И положение
LoadTexture(Form1, 'Button.bmp', 'Button'); // Загрузим текстуру в хранилище****
Draw(Form1, 'Button', 0, 0, FALSE); // Нарисуем текстуру на буфере
BufferDraw(Form1); // И выведем его на экран

ID := CreateTimer(1000, OnTop); // Создадим таймер для вызова процедуры OnTop

CollectMessages; // И организуем цикл сбора сообщений для корректной работы приложения
end. // That's all, folks!

**** Комментарий автора.

Все подробности управления графикой смотрите в документации к проекту.

Да, и это все, как и говорится в последней строке программы. Попробуйте поискать многочисленные работы с памятью и прочими непристойностями — их просто нет. Таким образом, мы избавились от главного минуса программ на WinAPI – скорости и сложности написания. И получили плюсы – размер проекта на Delphi всего ~20 кБ по сравнению с ~300 и 39 кБ в Lazarus по сравнению с ~900 кБ. Так же не пострадало и быстродействие – прямые работы с памятью в операциях с графикой и прямой вызов WinAPI функций в проекте. 

Вместо заключения

Итак, использование фреймворка дало свои плюсы. Быстрота написания (на это у меня ушло не более 3-х минут), малый размер и быстродействие – все это в одном флаконе. Так же, так как практически все функции имеют понятные названия и параметры то его можно запросто использовать для обучения основам управления программой на WinAPI. В общем, я надеюсь, что он, повторяя путь развития паскаля, перейдет в массы.

Вы можете ответить или разместить запись на вашем сайте.

Ответить

Powered by Procoder