Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab_progr_Win / Lab5

.doc
Скачиваний:
9
Добавлен:
23.03.2015
Размер:
585.22 Кб
Скачать

Лабораторна робота №5.

Тема роботи: Створення дочірніх елементів керування: кнопки, прапорці, перемикачі, вікна редагування.

Ціль роботи: Придбання досвіду створення прикладного програмного забезпечення для Windows з використанням дочірніх елементів керування.

ТЕОРЕТИЧНА ЧАСТИНА

Будь-який стандартний додаток Windows використовує різні елементи керування, такі, як кнопки, смуги перегляду, редактори текстів і т.д, реалізовані у вигляді дочірніх вікон.

Тому що дочірні вікна розташовуються на поверхні вікна батька, “прилипаючи” до них, додаток може створити в будь-якому своєму вікні кілька елементів керування, що будуть переміщатися разом з вікном-батьком. Для цього досить створити потрібні дочірні вікна, указавши їхні розміри, розташування і деякі інші атрибути. Після цього додаток може взаємодіяти з елементами керування, передаючи чи одержуючи від них різні повідомлення.

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

Дочірнє вікно керування обробляє повідомлення миші і клавіатури і сповіщає батьківське вікно про те, що стан дочірнього вікна змінився. У цьому випадку дочірнє вікно стає для батьківського вікна пристроєм уведення. Воно інкапсулює особливі дії, зв'язані з графічним представленням вікна на екрані, реакцією на користувальницьке введення, і повідомлення іншого вікна при уведенні важливої інформації.

Можна створювати свої власні дочірні елементи керування, але є також можливість використовувати переваги декількох уже визначених класів вікна (і віконних процедур), за допомогою яких додаток може створювати стандартні дочірні вікна керування, що є присутні звичайно у всіх Windows-додатках.

Стандартні дочірні вікна керування мають вид кнопок, прапорців, вікон редагування, списків, комбінованих списків, рядків тексту і смуг прокручування. Додатку немає необхідності турбуватися про логіка обробки миші цими вікнами, чи про логіка їх відмальовування. Усе це робиться в Windows, а усе, що залишається додатку – це обробляти повідомлення WM_COMMAND, якими дочірні вікна інформують віконну процедуру про різні події.

Якщо створюється одне з визначених дочірніх вікон керування, то для цього дочірнього вікна клас вікна реєструвати не треба. Такий клас вже існує в Windows і має одне з наступних імен: “button”, ”edit”, “static”, “listbox”, “combobox” і “scrollbar”. Додаток лише використовує одне з цих імен як параметр у функції CreateWindow.

Параметр стилю вікна функції CreateWindow більш точно визначає вид і властивості дочірнього вікна керування. Константи, що ідентифікують стилі визначених класів елементів керування, визначені в заголовних файлах Windows і мають відповідно наступні префікси: BS_ - “button”, ES_ - ”edit”, SS_ - “static”, LBS_ - “listbox”, CBS_ - “combobox” і SBS_ - “scrollbar”.

Windows містить у собі віконні процедури, що обробляють повідомлення тих дочірніх вікон, що створені на основі перерахованих класів.

Викликая спеціальні функції, можна

  • динамічно переміщати елемент керування (MoveWindow - функція визначає нове розташування і розміри вікна в системі координат, зв'язаної з батьківським вікном),

  • робити його активним чи неактивним (EnableWindow, для визначення, чи є вікно заблокованим, використовується функція IsWindowEnabled),

  • ховати його чи відображати (ShowWindow),

  • змінювати заголовок вікна (SetWindowText),

  • знищити створений елемент керування (DestroyWindow).

Віконна процедура може посилати повідомлення дочірньому вікну керування. П'ять спеціальних повідомлень для кнопок визначені в заголовних файлах Windows, кожне з який починається з префікса "BM", що означає "button message" (повідомлення кнопки). От ці повідомлення:

BM_GETCHECK

BM_SETCHECK

BM_GETSTATE

BM_SETSTATE

BM_SETSTYLE

Повідомлення BM_GETCHECK і BM_SETCHECK посилаються батьківським вікном дочірньому вікну керування для установки і зняття (тобто одержання поточного стану) контрольних міток прапорців (check boxes) і перемикачів (radio buttons). Повідомлення BM_GETSTATE і BM_SETSTATE стосуються звичайного чи "натиснутого" стану вікна при щиглику чи мишею натисканні клавіші <Spacebar>. Повідомлення BM_SETSTYLE дозволяє вам змінювати стиль кнопки після її створення.

Відправлення повідомлень батьківському вікну дочірнім і навпаки, здійснюється за допомогою функції SendMessage(), що у загальному виді виглядає у такий спосіб:

LRESULT SendMessage(

HWND hWnd, // дескриптор вікна призначення

UINT Msg, // повідомлення, що відправляється

WPARAM wParam, // перший параметр повідомлення

LPARAM lParam // другий параметр повідомлення

);

Для приклада створимо додаток, що використовує такі дочірні елементи керування як кнопки, прапорці, перемикачі і вікна редагування. У вікні редагування буде вводитися рядок символів, що по натисканню кнопки «Результат», у залежності від обраних прапорців і перемикачів, буде піддаватися визначеним змінам.

Зовнішній вигляд програми буде наступним:

Рисунок 2.6 Зовнішній вигляд програми CONTROLS.

Створення додатка, що використовує діалоги.

  1. Створіть новий проект CONTROLS.

  2. Для початку створіть файл controls.cpp і скопіюйте в нього вміст файлу sample.cpp, що був створений у Лабораторній роботі №1.

  3. Крім заголовного файлу windows.h не знадобляться ніякі інші заголовні файли.

  4. Функцію WinMain варто піддати наступним незначним змінам:

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static char szAppName[] = " Controls" ;

MSG msg ;

WNDCLASS wndclass ;

RegisterClass (&wndclass) ;

hWnd = CreateWindow (szAppName, " Simple Controls ", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;

  1. Функцію WndProc необхідно піддати більш ретельній обробці. Дочірні елементи керування будуть створюватися відразу по створенню вікна. Отже, вони повинні створюватися при обробці повідомлення WM_CREATE. Створіть статичний елемент керування з текстом і вікно редагування для введення рядка символів, додавши до програми наступний код:

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

HWND hWnd, hStatic1, hWndEdit1;

UINT ID_edit1=1;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

char szAppName[]="Controls";

case WM_CREATE:

hStatic1=CreateWindow("static","Уведіть рядок символів: ", WS_CHILD|WS_VISIBLE |WS_CLIPSIBLINGS| ES_LEFT, 25,50,200,25,hwnd,NULL, ((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hWndEdit1=CreateWindow("edit",NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIB-LINGS|WS_BORDER|ES_LEFT,250,50,200,25,hwnd,(HMENU)ID_edit1,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

return 0;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

EndPaint (hwnd, &ps) ;

return 0 ;

  1. Для створення групи перемикачів, додайте до оброблювача події WM_CREATE наступний код:

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

HWND hWnd, hWndEdit1, hStatic1, hGroup1, hRadio1, hRadio2;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

char szAppName[]="Controls";

case WM_CREATE:

hStatic1=CreateWindow("static","Уведіть рядок символів: ", WS_CHILD|WS_VISIBLE |WS_CLIPSIBLINGS| ES_LEFT, 25,50,200,25,hwnd,NULL, ((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hWndEdit1=CreateWindow("edit",NULL,WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_BORDER| ES_LEFT,250,50,200,25,hwnd,(HMENU)ID_edit1,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hGroup1=CreateWindow("button","Група перемикачів:", WS_CHILD| WS_VISIBLE|BS_GROUPBOX,25,100,200,100,hwnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hRadio1=CreateWindow("button","Верхній регістр", WS_CHILD| WS_VISIBLE|BS_AUTORADIOBUTTON, 35,133,150,20,hwnd,NULL,((LPCREATE-STRUCT) lParam) -> hInstance,NULL);

SendMessage(hRadio1, BM_SETCHECK, 1, 0);

hRadio2=CreateWindow("button","Нижній регістр", WS_CHILD| WS_VISIBLE| BS_AUTORADIOBUTTON ,35,166,150,20, hwnd, NULL, ((LPCREATE-STRUCT) lParam) -> hInstance,NULL);

return 0 ;

  1. Для створення групи прапорців, додайте до оброблювача події WM_CREATE наступний код:

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

HWND hWnd, hWndEdit1, hStatic1, hGroup1, hRadio1, hRadio2, hGroup2, hCheckBox1, hCheckBox2,;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

char szAppName[]="Controls";

case WM_CREATE:

hRadio2=CreateWindow("button","Нижній регістр", WS_CHILD| WS_VISIBLE| BS_AUTORADIOBUTTON,35,166,150,20,hwnd,NULL, ((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hGroup2=CreateWindow("button","Група прапорців:", WS_CHILD|WS_VISIBLE| BS_GROUPBOX, 250,100,200,100,hwnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hCheckBox1=CreateWindow("button","Додати ~-!-~", WS_CHILD|WS_VISIBLE |BS_AUTOCHECKBOX, 260,133,150,20,hwnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hCheckBox2=CreateWindow("button","Додати ~_-_~", WS_CHILD| WS_VISIBLE| BS_AUTOCHECKBOX,260,166,150,20,hwnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

return 0 ;

  1. І нарешті створіть дві кнопок. Одну для одержання результату, а другу для виходу з програми.

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

HWND hWnd, hWndEdit1, hStatic1, hGroup1, hRadio1, hRadio2, hGroup2, hCheckBox1, hCheckBox2, hButton1, hButton2;

UINT ID_edit1=1, ID_button1=2, ID_button2=3;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

char szAppName[]="Controls";

case WM_CREATE:

hCheckBox2=CreateWindow("button","Додати ~_-_~", WS_CHILD| WS_VISIBLE| BS_AUTOCHECKBOX,260,166,150,20,hwnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hButton1=CreateWindow("button", "Результат", WS_CHILD|WS_VISIBLE| WS_CLIPSIBLINGS|BS_PUSHBUTTON, 100,250,100,25,hwnd,(HMENU)ID_button1, ((LPCREATESTRUCT) lParam) -> hInstance,NULL);

hButton2=CreateWindow("button","Вихід",WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|BS_PUSHBUTTON,300,250,100,25,hwnd,(HMENU)ID_button2, ((LPCREATESTRUCT) lParam) -> hInstance,NULL);

return 0 ;

  1. Т.к. головне вікно програми містить дочірні елементи керування, то в програмі потрібно обробляти повідомлення WM_COMMAND. Ідентифікатор дочірнього вікна елемента керування знаходиться в молодшому слові параметра wParam. По логіці програми, нас цікавлять тільки повідомлення головному вікну, що надходять від кнопок:

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {

switch (iMsg)

{

case WM_COMMAND:

if(LOWORD(wParam)==ID_button1) { … } // натиснуто кнопку «Результат»

if(LOWORD(wParam)==ID_button2) { … } // натиснуто кнопку «Вихід»

return 0 ;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

  1. У випадку, якщо натиснута кнопка «Результат», необхідно обробляти введений рядок:

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

HDC hdc ;

PAINTSTRUCT ps ;

char buf1[32] ="", buf2[32]="Результат: ", str1[4]="-!-", str2[4]="_-_";

int iCheck;

case WM_COMMAND:

if(LOWORD(wParam)==ID_button1) {

GetWindowText(hWndEdit1, buf1, 32);

if(iCheck=(int)SendMessage(hRadio1, BM_GETCHECK, 0, 0))CharUpper(buf1);

if(iCheck=(int)SendMessage(hRadio2, BM_GETCHECK, 0, 0))CharLower(buf1);

if(iCheck=(int)SendMessage(hCheckBox1, BM_GETCHECK, 0, 0)) strcat(buf1,str1);

if(iCheck=(int)SendMessage(hCheckBox2, BM_GETCHECK, 0, 0)) strcat(buf1,str2);

strcat(buf2,buf1);

MessageBox(hwnd, buf2,"Result", MB_ICONQUESTION|MB_OKCANCEL);

}

return 0 ;

У даному фрагменті коду відбувається наступне: для початку, зчитуємо поточний текст вікна редагування в змінну buf1 за допомогою функції GetWindowText(). Ця функція в загальному виді виглядає так:

GetWindowText (hwnd, pszBuffer, iMaxLength);

Параметр iMaxLength задає максимальне число символів для копіювання в буфер, що визначається покажчиком pszBuffer. Hwnd — дескриптор вікна з якого зчитується текст. Значенням функції, що повертається, є довжина скопійованого рядка.

Наступні п'ять рядків коду формують результуючий рядок.

Поточний стан прапорців і перемикачів можна довідатися за допомогою відправлення повідомлення BM_GETCHECK потрібному дочірньому вікну керування. Якщо обраний перший перемикач, то результуюча рядок буде виведена на екран у верхньому регістрі (функція CharUpper()), а якщо другий — у нижньому (функція CharLower ()). За допомогою прапорців до результату можна додати визначені рядки: якщо обраний перший прапорець, то додається «-!-», якщо другий — «_-_», а якщо обрані обидва прапорці, то додаються обидві ці рядки.

Потім за допомогою операції конкатенації в зміннії buf2 формується остаточний результат, що згодом виводиться на екран за допомогою функції MessageBox().

  1. У випадку, якщо натиснута кнопка «Вихід», необхідно здійснити вихід із програми. Але можна передбачити випадок, коли кнопка буде натиснута випадково. Для цього варто одержати від користувача підтвердження виходу:

case WM_COMMAND:

if(LOWORD(wParam)==ID_button1) {

MessageBox(hwnd, buf2,"Result", MB_ICONQUESTION|MB_OKCANCEL);

}

if(LOWORD(wParam)==ID_button2) if (MessageBox(hwnd, "Ви дійсно хочете вийти?", "Exit", MB_ICONQUESTION|MB_OKCANCEL)==IDOK)PostQuitMessage (0) ;

return 0 ;

Програма готова. Запустіть її на виконання.

ПРАКТИЧНА ЧАСТИНА

  1. Створіть програму controls, описану в лабораторній роботі.

  1. Написати програму, що має наступний зовнішній вигляд:

Рисунок 2.7 Зовнішній вигляд програми калькулятору

При натисканні ОК у поле редагування Edit3 заноситься відповідний результат обчислення.

Контрольні питання:

  1. Чи є елементи керування вікнами? Як вони створюються, чи можуть вони спілкуватися за допомогою повідомлень зі своїм батьківським вікном?

  2. На базі яких класів створюються стандартні елементи керування Windows?

  3. Для чого при створенні елемента керування додаток повинний повідомити Windows дескриптор батьківського вікна й ідентифікатор створюваного елемента керування?

  4. Що таке дескриптор елемента керування й ідентифікатор елемента керування?

  5. Яке повідомлення звичайне приходить батьківському вікну, якщо щось відбувається з елементом керування? Яку додаткову інформацію несе із собою це повідомлення?

  6. Що таке код повідомлення? Що він ідентифікує?

  7. Якими способами батьківське вікно може передавати повідомлення елементам керування? Чим вони відрізняються?

Соседние файлы в папке Lab_progr_Win