Лекції з WinApi

Тема №4 Вікна

4. Вікна
 4.1. Визначення вікна. Компоненти і параметри вікон

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

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

Коли Windows® завантажується, створюється вікно займаюче весь екран (desktop window). Кожен windows-додаток створює хоча б одне вікно, називаний головним вікном додатка. Багато додатків створюють ще додаткові вікна. Вікно додатка може складатися з наступних компонентів:

Просте вікно

Додатки можуть використовувати й інші типи вікон:

  • елементи керування (controls)
  • вікна діалогу (dialog boxes)
  • вікна повідомлень (message boxes)

Для породження вікна (у тому числі і головному вікні додатка) використовується функція CreateWindowEx. Додаток для створення вікна повинний визначити наступні параметри:

  • Клас вікна (Window class )
  • Ім'я вікна (Window name)
  • Стиль вікна (Window style)
  • Батьківське чи вікно вікно-хазяїн (Parent or owner window)
  • Розміри (Size)
  • Координати лівого верхнього кута (Location)
  • Місце в порядку розташування (Position in the Z-order)
  • Ідентифікатор дочірнього чи вікна описувач меню (Child-window identifier or menu handle)
  • Описувач екземпляра програми (Instance handle)
  • Додаткові дані (Creation data)
    1. Клас вікна

Кожне вікно в системі належить до якому або класу. Вікна одного класу працюють “однаково”. Це зв'язано з тим, що клас вікна визначає, по-перше, ряд зовнішніх атрибутів (форму курсору, параметри тла, ікону), а, по-друге, усі вікна одного класу працюють з однієї і тією же функцією вікна.

Функція вікна - спеціальна функція, що призначається класу вікна. Для посилки вікну повідомлення операційна система викликає цю функцію і передає їй як параметри код повідомлення й іншу уточнюючу інформацію.

Існує три типи класів вікна:

  1. Системні глобальні класи: класи, що реєструються при завантаженні операційної системи. До таких класів відносяться класи елементів керування (кнопки, списки, смуги прокручування і т.д.)
  2. Прикладні глобальні класи: класи, що реєструються бібліотеками, що динамічно зв'язуються, (DLL) і доступні всім додаткам системи
  3. Прикладні локальні класи: класи, що додатка реєструють для свого внутрішнього використання.

Для реєстрації класів використовується функція RegsterClass (RegisterClassEx).

1. Ім'я вікна

Ім'я вікна - послідовність символів, що іменують вікно. Ім'я вікна відображається в заголовку стандартного вікна, чи є текстом, написаним на кнопці і т.д.

2.  Стиль вікна

Кожне вікно має чи стиль кілька стилів. Стиль - це іменована константа, що задає додаткові параметри вікна усередині класу. Наприклад, вікно класу “смуга прокручування” може мати стилі SBS_HORZ чиSBS_VERT, що визначають напрямок прокручування: вертикальне чи горизонтальне. Докладний опис стилів приводиться в п.5.3.

3.Батьківське чи вікно вікно-хазяїн

Вікно може мати батьківське вікно (parent window). У такому випадку воно називається дочірнім вікном (child window) стосовно батьківського. Дочірнє вікно ніколи не виходить за границі батьківського. При згортанні батьківського вікна згортаються всі дочірні. При знищенні батьківського вікна всі дочірні знищуються. Дочірнє вікно не має меню.

Вікно може мати вікна-хазяїна. Це інший тип відносин між вікнами. Вікно завжди розташовується поверх хазяїна і звертається і знищується разом з ним.

4.Розміри і координати, місце в порядку розташування

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

5.  Ідентифікатор дочірнього чи вікна описувач меню

Дочірнє вікно може мати унікальний ідентифікатор, що дозволяє виділяти дочірнє вікно з безлічі дочірніх вікон. Не дочірньому вікну можна призначити меню.

6. Описувач екземпляра програми

Кожне процес у Windows має унікальний ідентифікатор. Цей ідентифікатор повідомляється системі при породженні вікна і може надалі використовуватися вікном.

7. Додаткові дані

Додаток може визначити будь-який блок даних, що буде переданий процедурі вікна при породженні в якості одного з параметрів.

 

4. Вікна.
 4.2. Ієрархія вікон

Ієрархія вікон

4. Вікна
 4.3. Стилі вікон

При створенні вікна його стиль задається в якості одного з параметрів функції CreateWindowEx.

  1.  Вікна, що перекриваються, (Overlapped windows)

Overlapped window - це вікно верхнього рівня, що має заголовок, границю, і клієнтську область. Вікна цього типу призначені для використання як головне вікно додатка.

Вікно типу WS_OVERLAPPED має тільки заголовок і границю

Вікно типу WS_OVERLAPPEDWINDOW додатково має системне меню, кнопки мінімізації і максимізації.

  1. Спливаючі вікна (Pop-up windows)

Pop-up window - це спеціальний тип overlapped window, використовуваний для створення вікон діалогу, вікон повідомлень і інших тимчасових вікон, що відображаються поза клієнтською областю головного вікна додатка.

Для породження спливаючого вікна використовується стиль WS_POPUP. Цей стиль може комбінуватися з WS_CAPTION, для наділення вікна заголовком. Стиль WS_POPUPWINDOW використовується для наділення спливаючого вікна додатково системним меню і границею.

  1. Дочірні вікна (Child windows)

Для породження дочірнього вікна використовується стиль WS_CHILD. Дочірнє вікно відображається в межах клієнтської області батьківського. Дочірнє вікно за замовчуванням має тільки клієнтську область. Додатково можна задати будь-які елементи крім меню. Дії, вироблені з батьківським вікном спричиняють дії, вироблені з дочірнім

Батьківське вікно

Дочірнє

Знищується

Знищується перед батьківським

Ховається

Ховається перед батьківським

Переміщається

Переміщається разом з батьківським

Відображається

Відображається після батьківського

Дочірнє вікно не вирізує автоматично з клієнтської області батьківського при отрисовці. Це означає, що батьківське вікно малює поверх дочірнього. Якщо необхідно уникнути цього, батьківське вікно повинне мати стиль WS_CLIPCHILDREN. Аналогічно, щоб уникнути отрисовці з боку братів, дочірнє вікно повинне мати стиль WS_CLIPSIBLINGS.

  1. Стилі границь вікна

WS_BORDER

Тонка рамка

WS_DLGFRAME

Подвійна рамка, використовувана при створенні вікон діалогу. Вікно з подібною границею не може мати заголовка

WS_EX_DLGMODALFRAME

Аналогічно WS_DLGFRAME, але може бути комбіноване з WS_CAPTION для створення заголовка

WS_EX_STATICEDGE

Заголовок, призначений для вікон, у які не можна робити введення. Наприклад незмінний текст у вікні діалогу (static)

WS_THICKFRAME

Толста рамка, що дозволяє змінювати розміри вікна

5.        WS_OVERLAPPED і WS_POPUPWINDOW мають стиль WS_BORDER за замовчуванням. Комбінацією з іншими стилями можна одержати інший тип рамки цих вікон. Вікна типів WS_POPUP іWS_CHILD узагалі не мають рамки за замовчуванням. Вікно типу WS_OVERLAPPEDWINDOW має товсту рамку (WS_THICKFRAME).

  1. Визначення компонентів вікна, що лежать за межами клієнтської області

Для створення вікон, що мають додаткові компоненти, що лежать за межами клієнтської області, використовуються наступні прапори:

WS_CAPTION

Заголовок вікна

WS_HSCROLL

Горизонтальна смуга прокручування

WS_MAXIMIZEBOX

Кнопка максимізації

WS_MINIMIZEBOX

Кнопка мінімізації

WS_SYSMENU

Системне меню

WS_VSCROLL

Вертикальна смуга прокручування

  1. Початковий стан вікна

При породженні вікна можна задати його початковий стан

WS_DISABLED

Вікно не одержує введення

WS_MAXIMIZE

Вікно одержує максимальний розмір

WS_MINIMIZE

Вікно породжується в мінімізованому виді

WS_VISIBLE

Вікно породжується видимим. Інакше, для відображення вікна необхідно викликати функціюShowWindow.

4. Вікна.
 4.4. Повідомлення і черги повідомлень.

На відміну від традиційних “консольних” додатків, Windows додаток ніколи не очікує введення шляхом виклику спеціальних функцій типу getchar(). Операційна система сама здійснює введення і приймає рішення, якому з вікон він призначений.

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

Виклик функції вікна називають передачею повідомлення цьому вікну. Як обов'язковий параметр у функцію вікна передається іменована константа, називана кодом повідомлення (message identifier)

Інші параметри визначають додаткові дані, зв'язані з даним повідомленням. Наприклад, при натисканні лівої кнопки миші в той момент, коли покажчик миші знаходиться над клієнтською областю вікна, вікну передається повідомлення WM_LBUTTONDOWN. При цьому як параметри передаються координати покажчика і стан інших кнопок миші і клавіш SHIFT і CTRL.

Windows використовує два способи для передачі повідомлень вікну

  1. Постановка повідомлення в чергу повідомлень
  2. Безпосередній виклик процедури вікна

1.   Черга повідомлень потоку

Кожен потік має свою чергу повідомлень. Потік повинний переглядати свою чергу повідомлень і направляти повідомлення на обробку відповідному вікну. Для цей потік повинний організувати цикл обробки повідомлень, що складає з функцій: GetMessage, TranslateMessage, і DispatchMessage.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

Функція GetMessage припиняє виконання потоку до одержання їм повідомлення. Функція повертає значення FALSE, якщо отримане повідомлення WM_QUIT. В всіх інших випадках повертається TRUE. Додаток може завершити себе посилкою повідомлення WM_QUIT. Для цього призначена функція PostQuitMessage. Звичайно вона викликається у відповідь на одержання головним вікном додатка повідомлення WM_DESTROY.

При натисканні клавіш Windows посилає активному вікну повідомлення WM_KEYDOWN і WM_KEYUP. Ці повідомлення містять деякі віртуальні коди клавіш, а не символи. Для аналізу натискань і породження повідомлень WM_CHAR, що містять символьні коди клавіш, використовується функція TranslateMessage.

Для того, щоб направити повідомлення на обробку відповідному вікну, використовується функція DispatchMessage.

Для постановки повідомлень у чергу використовується функція PostMessage. Першим параметром цієї функції є описувач вікна, якому передається повідомлення. Система визначає, який потік породив це вікно і ставить повідомлення йому в чергу. Потік, що викликав функцію PostMessage не чекає обробки повідомлення, а продовжує виповнюватися. Функцією PostThreadMessage повідомлення ставиться в чергу потоку, але в якості описувача вікна встановлюється NULL. Потік не повинний відправляти такі повідомлення на обробку своїм вікнам. Для цього в циклі обробці повідомлень повинний бути передбачений відповідний аналіз описувача вікна.

2.    Безпосередній виклик процедури вікна

Для безпосереднього виклику процедури вікна призначена функція SendMessage. Потік, що викликав SendMessage припиняється до завершення обробки повідомлення.

3.   Пересилання даних за допомогою повідомлень

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