Пришла пора начать цикл статей по пограммированию, с использованием API. Надоело, знайте ли, создавать малофункциональные программы с огромным объемом. Проблема решилась одним из возможных способов- писать напрямую, через API. "Что это значит",- спросит неопытный читатель. А значит это следующее: вы не используйте никаких классов VCL, всё создаете сами!!!
Если кто-нибудь изучал программирование на Паскале, то он ,вероятно, вспомнит, что любая программа начинается с названия Program Так нужно делать и на API: ваша программа-это только один файл с расширением *.dpr (конечно вы можете подключать к нему как свои, так и другие модули). Общий вид его должен выглядеть так
Program Name; uses MyUnit; {$R *.RES} {По этой директиве в ваш проект будет включен ресурсный файл,где вместо * быдет имя вашего проекта} {$R NameRes.RES} {Другие файлы ресурсов с явным указанием имени} const MyConst=0; {Ваши константы} var MyVar:integer; {Ваши переменные} {Здесь находится описание и реализаия ваших функций} begin ..... {код программы} end;Таков вид вашего проекта. Теперь давайте перейдем к показу пробного окошка.Для этого нам надо будет вставить некоторый код между begin и end;
Чтобы показаь окно нужно изучить несколько функций:
RegisterClass(); CreateWindow(); ShowWindow();
Все эти функции должны присутствовать при создании любого приложения.
Первым делом на пути создания окна является регитрация класса окна, который несет в себе некоторую информацию об окне. Это делается с помощью функции
ATOM RegisterClass(CONST WNDCLASS *lpWndClass), которая регистрирует класс окна на основе структуры WNDCLASS
После того, как создан класс создаем на его основе окно. Это делается с помощью функции CreateWindow()
После того, как окно создано, его нужно показать, что делается функцией ShowWindow() Хочу заметить, что эту функцию нужно применять только для родительского окна, т.е. если ваше приложение содержит главное окно и дочерние компоненты, то делается показ только главного окна.Прием сообщений
Прием сообщений осуществляется с помощью нескольких функций:GetMessage(); TranslateMessage(); DispatchMessage(); DefWindowProc();
Сначала-теория. Сообщения-это такие коды команд, которые посылает ОС приложению, к примеру, WM_CLOSE- это константа, содержащая код сообщения, которое посылается программе, когда пользователь нажимает кнопку Close. Все эти константы определены в модуле Messages.
Итак, чтобы организовать получение сообщений нужно в первую очередь написать функцию окна, т.е. функцию, которая бдет совершать какие-то действия в ответ на сообщение (чаще всего её название - WndProc, но вы можете менять его на своё усмотрение, адрес этой функции мы заносим в структуру WNDCLASS: IpfnWndProc:=@WindowProc). Необходимо правильно описать функцию:
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
function WindowProc(hWnd: THandle; uMsg, wParam, lParam: Integer): Integer;
stdcall; export; -это на паскале
HWND-дискриптор окна, который вы получили после использования функции CreateWindow() uMsg - это и есть код сообщения (16 бит)(имеет место выражение типа: if uMsg=WM_CLOSE then) WPARAM,LPARAM - параметры, которые передаются вместе с сообщением.(16 бит)
while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end;Где HWnd -дискриптор окна, который вы получили после использования функции CreateWindow().Все функции объяснены здесь
program Dir; uses Windows, Messages, shellapi; const sClassName = 'sTaskBarHandlerWindow'; // Имя класса окна var hWnd: THandle; //индентификатор окна WndClass: TWndClass; //структура WndClass Msg: TMsg; //структура для принятия сообщений function WindowProc(hWnd: THandle; uMsg, wParam, lParam: Integer): Integer; {функция окна} stdcall; export; begin Result := 0; case uMsg of WM_DESTROY: //если uMsg равна WM_DESTROY(код закрытия окна) то закрываемся begin halt(0); end; end; Result := DefWindowProc(hWnd, uMsg, wParam, lParam); //удалить остальные сообщения end; begin FillChar(WndClass, SizeOf(WndClass), 0); //заполняем структуру нулями with WndClass do begin hInstance := SysInit.hInstance; //Обязательный параметр, индентификатор вашего приложения lpszClassName := sClassName; //имя класса lpfnWndProc := @WindowProc; //имя функции окна hbrBackground := GetStockObject(LTGRAY_BRUSH); //способ заливки клиентской области (об этом позже) end; RegisterClass(WndClass); //регистрируем класс hWnd := CreateWindow(sClassName, '', WS_OVERLAPPEDWINDOW, 200, 200, 300, 300, 0, 0, hInstance, NIL); //создаем окно if hWnd = 0 then begin //если произошла ошибка, то выходим MessageBox(0, 'Initialisation failed', NIL, ID_OK); Exit; end; ShowWindow(hWnd, SW_normal); //показываем окно while GetMessage(Msg, HWnd, 0, 0) do begin //получаем сообщение TranslateMessage(Msg); DispatchMessage(Msg); end; Halt(Msg.wParam); end.