Отправляет email-рассылки с помощью сервиса Sendsay

Windows API в Delphi для начинающих

  Все выпуски  

Windows API в Delphi для начинающих


Информационный Канал Subscribe.Ru


Windows Api В Delphi для начинающих.

Выпуск 1.

Создание окон.

 

 

 

 

Я думаю, что начинать изучение Windows API следует с изучения операций с окнами. Сегодня я объясню, что такое окно, класс окна и стили окна, и рассмотрю создание окон.

Окно – USER-объект (еще существуют GDI-объекты и объекты ядра) для взаимодействия пользователя с программой. Все элементы управления, такие как кнопки, checkbox’ы, listbox’ы и т.д. являются окнами. Каждое окно (так как оно является USER-объектом) имеет свой дескриптор, через который можно им управлять.

Каждое окно имеет функцию, называющуюся оконной процедурой, которую Винда вызывает, когда окну послано сообщение. Сообщения – это специальные константы, которые служат для осуществления операций ввода с окнами. Каждое посылаемое сообщение имеет два параметра. Например, сообщение WM_KEYDOWN имеет два параметра: в одном содержится код клавиши, во втором – различные параметры, такие как скан-код, число повторений и др., а сообщение WM_CLOSE не имеет параметров.

 Кроме того, каждое окно имеет свой класс и один или несколько стилей. Каждый класс имеет определенные параметры, такие как имя класса, оконная процедура, значок и некоторые другие, которые будут рассматриваться позднее. Стили окна определяют его внешний вид. Например, если окно имеет стиль WS_VSCROLL, то у него есть вертикальная полоса прокрутки, если окно класса “BUTTON” имеет стиль BS_PUSHBUTTON, то оно будет выглядеть как обычная кнопка, а если BS_CHECKBOX, то будет выглядеть checkbox’ом. В WinAPI есть несколько стандартных классов: BUTTON, COMBOBOX, LISTBOX, MDICLIENT, SCROLLBAR, STATIC. В следующий раз я рассмотрю описание оконных  классов. Для этого нужна отдельная статья, так как их слишком много, а места, к сожалению, мало.

Перейдем к самому главному – к созданию окон. В WinAPI для создания окон существуют две функции: CreateWindow и CreateWindowEx, которые отличаются лишь тем, что вторая поддерживает расширенные оконные стили (начинающиеся на WS_EX_), поэтому рассматривать будем именно ее.

 

function CreateWindowEx(dwExStyle: DWORD; lpClassName: PChar;

  lpWindowName: PChar; dwStyle: DWORD; X, Y, nWidth, nHeight: Integer;

  hWndParent: HWND; hMenu: HMENU; hInstance: HINST; lpParam: Pointer): HWND; stdcall;

 

dwExStyle – задает расширенные (extended) стили окна;

lpClassName – имя зарегистрированного класса окна (класс регистрируется функцией                             RegisterClass или RegisterClassEx);                

lpWindowName – имя окна;

dwStyle – стили окна;

X – горизонтальное положение окна в координатах экрана или координатах родительского окна, для значения по умолчанию параметр можно задать как CW_USEDEFAULT;

Y –  вертикальное положение окна в координатах экрана или координатах родительского окна, для значения по умолчанию параметр можно задать как CW_USEDEFAULT;

nWidth – длина окна или CW_USEDEFAULT;

nHeight – ширина окна или CW_USEDEFAULT;

hWndParent – дескриптор родительского окна, если есть стиль WS_CHILD;

hMenu – дескриптор меню или идентификатор окна, если оно дочернее;

hInstanceinstance модуля, ассоциируемого с окном. Возвращается функцией GetModuleHandle;

lpParam – указатель на структуру, которая передается как параметр lParam сообщения WM_CREATE в которой возвращаются параметры окна. Используется редко.

Теперь о структуре WINDOWCLASSEX:

 

WNDCLASSEX = packed record

    cbSize: UINT;

    style: UINT;

    lpfnWndProc: TFNWndProc;

    cbClsExtra: Integer;

    cbWndExtra: Integer;

    hInstance: HINST;

    hIcon: HICON;

    hCursor: HCURSOR;

    hbrBackground: HBRUSH;

    lpszMenuName: PChar;

    lpszClassName: PChar;

    hIconSm: HICON;

  end;

 

cbSize – размер структуры. Должен быть равен sizeof(WNDCLASSEX);

style – стиль класса (не стиль окна!);

lpfnWndProc – указатель на оконную процедуру;

cbClsExtra – задает количество дополнительных байт, следующих за экземпляром структуры WNDCLASSEX;

cbWndExtra - задает количество дополнительных байт, связанных с каждым экземпляром окна указанного класса;

hInstanceinstance модуля,c которым связана оконная процедура;

hIcon – дескриптор значка окна. Может быть получен с помощью LoadIcon;

hCursor – дескриптор курсора. Может быть получен с помощью LoadСursor;

hbrBackground – дескриптор кисти (brush) или значение цвета (например, COLOR_APPWORKSPACE). Задает цвет рабочей области окна;

lpszMenuName – имя ресурса меню;

lpszMenuName – имя класса;

hIconSm – дескриптор маленького значка окна. Если 0, то используется тот же, что и в параметре hIcon;

Регистрация класса производится функцией RegisterClassEx.

Теперь немного слов об оконной процедуре. Оконная процедура, это процедура, которая обрабатывает оконные сообщения. Ее прототип таков:

 

function WindowProc(hWnd:HWND;uMsg:cardinal;wparam,lparam:integer):integer;stdcall;

 

hWnd – дескриптор окна;

uMsg – сообщение;

wparam,lparam – параметры сообщения;

 

В качестве возвращаемого значения функции желательно возвращаемое значение функции DefWindowProc, вызывающую стандартный обработчик.

Приведу пример программы, создающей окно, затем и дочернее окно в нем (кнопка, закрывающая его). Замечу, что в параметре hMenu при создании кнопки передается ее идентификатор, который используется при обработке сообщения WM_COMMAND, чтобы при нажатии на нее окно закрывалось. Для закрытия окна и завершения приложения используется функция PostQuitMessage, которая посылает потоку сообщение WM_QUIT. Функция GetMessage записывает сообщение из очереди сообщений потока в структуру TMsg. Функция TranslateMessage используется для преобразования сообщений WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN и WM_SYSKEYUP  в WM_CHAR, WM_DEADCHAR, WM_SYSCHAR и WM_SYSDEADCHAR соответственно. Функция DispatchMessage передает сообщение в оконную процедуру.

 

program createWindow;

uses

  Windows,Messages,SysUtils;

 

const

classname='MyFirstWindowClass';

BUTTON_ID=100;

 

var wc:WNDCLASSEX;Wnd,WndChild:HWND;msg:TMSG;

 

function WindowProc(hWnd:HWND;uMsg:cardinal;wparam,lparam:integer):integer;stdcall;

begin

case uMsg of

WM_DESTROY:PostQuitMessage(0);

WM_COMMAND:

if LOWORD(wparam)=BUTTON_ID then

   if HIWORD(wparam)=BN_CLICKED then PostQuitMessage(0);

end;

result:=DefWindowProc(hWnd,uMsg,wparam,lparam);

end;

 

begin

ZeroMemory(@wc,sizeof(wc));

wc.cbSize:=sizeof(WNDCLASSEX);

wc.style:=CS_HREDRAW or CS_VREDRAW;

wc.lpfnWndProc:=@WindowProc;

wc.hInstance:=GetModuleHandle(nil);

wc.hIcon:=LoadIcon(wc.hInstance,IDI_APPLICATION);

wc.hCursor:=LoadCursor(wc.hInstance,IDC_ARROW);

wc.hbrBackground:=COLOR_APPWORKSPACE;

wc.lpszClassName:=classname;

RegisterClassEx(wc);

Wnd:=CreateWindowEx(0,classname,'First WinAPI Window',

WS_OVERLAPPEDWINDOW and not WS_MAXIMIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,0,0,GetModuleHandle(nil),nil);

if Wnd=0 then

     Raise Exception.Create('Can''t create window');

ShowWindow(Wnd,SW_SHOWNORMAL);

UpdateWindow(Wnd);

CreateWindowEx(0,'BUTTON','Close',BS_NOTIFY or BS_PUSHBUTTON or WS_CHILD or WS_VISIBLE,200,150,200,50,Wnd,BUTTON_ID,GetModuleHandle(nil),nil);

While GetMessage(msg,0,0,0) do

 begin

   TranslateMessage(msg);

   DispatchMessage(msg);

 end;

end.

 

 

 На сегодня это все. В следующий раз я рассмотрю оконные стили и стили класса, а также функции SetWindowLong\GetWindowLong и SetClassLong\GetClassLong.

До свиданья. Если возникнут вопросы, пишите.

Автор рассылки, Сергей Дьячков aka Marouder, marouder@list.ru


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное