ТОП 10:

Розробка головної функції застосування



Win32-зacтocyвaння із підтримкою вікон відрізняються від консольних застосу­вань, описаних дотепер. Насамперед головну функцію таких застосувань визна­чають інакше. її називають WinMainO:

 

int WINAPI WinMain( HINSTANCE ih. HINSTANCE ip.

LPSTR cmdline. int cmd_show ) {

// код головної функції застосування

 

де: ih - дескриптор екземпляра застосування, який можна використати для іден­тифікації виконуваної копії застосування;

cmdline — командний рядок, заданий під час запуску застосування; cmdshow - код, що визначає, як передбачено відображати головне вікно засто­сування (SWMAXIMIZE, SW_MINIMIZE тощо).

У коді WinMainO насамперед потрібно зареєструвати клас головного вікна застосування. Клас вікна відображають структурою WNDCLASS, для якої потрібно задати ряд полів, зокрема:

I pszCl assName - ім'я класу, під яким він буде зареєстрований;

♦ lpfnWndProc — адресу процедури вікна, яку система викликатиме з появою по­відомлень, адресованих цьому вікну;

♦ hi соп — дескриптор піктограми цього вікна (вона відображатиметься у його заголовку або на панелі задач; для отримання такого дескриптора використо­вують функцію Load І соп О);

♦ hCursor — дескриптор курсору, що відображатиметься над вікном; для його от­римання використовують функцію LoadCursorO);

♦ hbrBackground — дескриптор спеціального об'єкта (пензля, brush), що визначає фоновий колір цього вікна (стандартний колір фону може бути заданий дода­ванням одиниці до наперед визначеної константи C0L0RWIND0W).

 

Ось приклад підготовки класу вікна:

 

WNDCLASS wc = { 0 }: wc.lpszClassName - "myclass";

wc.1pfnWndProc - wnd_proc: // визначення wnd_proc() див. нижче

// стандартна піктограма застосування

wc.hlcon = LoadlconCNULL. IDI_APPLICATION);

// стандартний курсор-стрілка

wc.hCursor = LoadCursor(NULL. IDC_ARR0W):

wc.hbrBackground = (HBRUSH)(C0L0R_WIND0W+1);

 

Після визначення цієї структури покажчик на неї передається у функцію

RegisterClassO:

RegisterClass(Swc)

 

Реєстрація класу вікна дає змогу розміщувати у пам'яті та відображати вікна такого класу. Для розміщення вікна у пам'яті використовують функцію Create-Wi ndowO:

 

HWND CreateWindow(LPCTSTR classname. LPCTSTR title. DWORD style,

int x. int y. int width, int height. HWND ph. HMENU mh.

HINSTANCE ih, LPVOID param );

 

де: classname — ім'я, під яким був зареєстрований клас цього вікна;

title - текст, відображуваний у заголовку вікна;

style - стиль вікна, який визначає спосіб його відображення (WSOVERLAPPED-

WIND0W - стандартне вікно із заголовком і керуючим меню);

х і у - координати лівого верхнього кута вікна, wi dth і hei ght - його ширина

і висота (ці величини задають у спеціальних віртуальних одиницях, які спро­щують масштабування);

і h - дескриптор застосування, що створює вікно (як значення передають від­-

повідний параметр WinMainO).

Ця функція повертає дескриптор вікна (значення типу HWND), за допомогою якого можна дістати доступ до розміщеного у пам'яті об'єкта вікна, наприклад для його відображення.

 

HWND hwnd = CreateWindowt"myclass". "Приклад застосування".

WS_OVERLAPPEDWINDOW. 0. 0. 300. 200. NULL, NULL, hinst, NULL );

 

Для відображення вікна використовують функцію

ShowWindowO: ShowWindowthwnd. cmd_show);

Після того як вікно було відображене, потрібно організувати цикл обробки повідомлень. У ньому необхідно отримати повідомлення за допомогою функції GetMessage(), перетворити його за допомогою функції TranslateMessage() і переда­ти у функцію вікна для подальшої обробки викликом DispatchMessage(). Усі ці функції використовують структуру повідомлення, що належить до типу MSG.

Використання функції TranslateMessageC) необхідне під час обробки повідомлень від клавіатури (натискання клавіш перетворюються у повідомлення, що містять введені символи).

Цикл завершується, коли в нього надходить повідомлення завершення (із ко­дом WMQUIT), внаслідок чого GetMessageO поверне нуль.

 

MSG msg;

While(GetMessage(&msg. NULL. 0. 0 )) {

TranslateMessaget&msg ):

DispatchMessageC&msg ):

}

Значенням, яке поверне WinMainO, має бути значення поля wParam структури повідомлення:

return (int)msg.wParam;

 

Розробка функції вікна

Функція вікна визначається так:

long CALLBACK wnd_proc(HWND hwnd. UINT msgcode. WPARAM wp. LPARAM Ip) {

// обробка повідомлень, адресованих вікну

 

де: hwnd - дескриптор відповідного вікна;

msgcode — код повідомлення, що надійшло;

wp, — додаткові дані, які можуть супроводжувати повідомлення (відпові-

­дають полям wParam і 1Param структури повідомлення).

У коді цієї функції перевіряють код повідомлення і залежно від його значення виконують дії.

 

switch (msgcode) {

case код-повідомленняі:

II дії з обробки повідомленняі

case код-повідомлення2:

// дії з обробки повідомлення2 і т. д.

 

Є багато різних повідомлень, тут реалізуємо виконання дій у разі одержання двох із них:

♦ WMPAINT — надходить вікну щоразу, коли його вміст потрібно перемалювати (у разі відображення, активізації, переміщення тощо);

♦ WMCL0SE — надходить у разі закриття вікна користувачем.

Про обробку WMPAINT ітиметься окремо, а поки що зупинимося на діях після

отримання WMCL0SE та обробці повідомлень за замовчуванням.

У разі отримання повідомлення WMCL0SE необхідно припинити виконання за­-

стосування, для чого потрібно перервати цикл обробки повідомлень. Стандартний спосіб реалізувати таке переривання - скористатися функцією PostQuitMessage(), яка поміщає в цикл повідомлення із кодом WMQUIT. Як параметр ця функція приймає значення, що стане кодом повернення застосування.

 

switch (msgcode) { case WM CLOSE:

case WM CLOSE:

PostQuitMessage(O):

return 0

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

 

switch (msgcode) {

// обробка відомих повідомлень

// обробка всіх інших повідомлень

return DefWindowProcChwnd,msgcode. wp, lp);

 







Последнее изменение этой страницы: 2017-02-06; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 34.231.21.160 (0.005 с.)