Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab_progr_Win / Lab6.doc
Скачиваний:
9
Добавлен:
23.03.2015
Размер:
1.04 Mб
Скачать

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

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

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

Теоретична частина

Існує два способи створення смуг прокручування у вікні додатка.

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

Цей метод дуже простий, але з його допомогою можна створити тільки одну горизонтальну й одну вертикальну смуги прокручування. Для того щоб у вікна з'явилися ці смуги прокручування, при створенні вікна в третьому параметрі функції CreateWindow необхідно вказати стиль вікна WS_VSCROLL чи WS_HSCROLL.

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

У цій лабораторній буде розглянутий перший спосіб створення смуг прокручування.

С допомогою класу “listbox” можна створювати одноколоночні і багатоколоночні списки, що мають вертикальну (для одноколоночних списків) і горизонтальну (для многоколоночних списків) смугу перегляду.

Список може бути як з одиночним вибором, так і з множинним. Останній дозволяє користувачу вибирати більш одного пункту списку.

Для створення списку додаток повинний викликати функцію CreateWindow, передавши їй як перший параметр покажчик на рядок “listbox”.

Вікно списку посилає повідомлення WM_COMMAND своєму батьківському вікну, коли в списку вибирається який-небудь пункт. Батьківське вікно може визначити, який пункт списку обраний.

Розглянемо стилі вікон списків

При стилі, що задається по умовчанню, вікна списку (тільки стиль WS_CHILD) повідомлення WM_COMMAND батьківському вікну не посилаються. Це означає, що програмі варто опитувати вікно списку за допомогою передачі йому повідомлень щодо обраних у списку пунктів.

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

Якщо додаток бажає мати можливість сортувати елементи списку, йому необхідно використовувати у вікні списку й інший часто використовуваний ідентифікатор стилю – LBS_SORT.

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

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

Для прокручування вмісту за допомогою миші і вертикальної смуги прокручування варто використовувати стиль WS_VSCROLL.

В заголовних файлах Windows визначається стиль списку, що називається LBS_STANDARD. Стиль LBS_STANDARD містить у собі найбільше часто використовувані стилі списку. Він визначається як комбінація

(LBS_NOTIFY|LBS_SORT|WS_VSCROLL|WS_BORDER)

Розглянемо повідомлення, що можуть посилати батьківські вікна вікнам списків для їхнього заповнення і подальшої роботи з ними

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

Специфічних повідомлень, що батьківське вікно може послати вікну списку за допомогою функції SendMessage, досить багато. Розглянемо найбільше часто уживані:

  • LB_ADDSTRING - для додавання рядка в кінець списку чи за алфавітним порядком (останнє - якщо використовується стиль LBS_SORT);

  • LB_INSERTSTRING - для вставки рядка на визначене порядкове місце в списку (якщо не використовується стиль LBS_SORT);

  • LB_DELETESTRING - для видалення рядка з деяким порядковим номером;

  • LB_RESETCONTENT - для повного очищення списку;

  • LB_GETCOUNT - для визначення загальної кількості пунктів списку;

  • LB_GETTEXTLENGTH - для визначення довжини будь-якого пункту списку;

  • LB_SETCURSEL - для установки елемента, обраного по умовчанню (для списків з одиничною вибіркою);

  • LB_SELECTSTRING - для вибірки (установки) елемента списку на основі його перших символів (для списків з одиничною вибіркою);

  • LB_GETCURSEL - для визначення індексу елемента, обраного в сучасний момент (для списків з одиничною вибіркою);

  • LB_SETSEL - для установки стану вибору конкретного елемента, при цьому не роблячи впливу на інші елементи, що могли б бути обраними(для списків із множинним вибором);

  • LB_GETSEL - для визначення, чи обраний конкретний елемент списку чи ні.

Самим могутнім повідомлення для вікон списку є повідомлення LB_DIR. Наступний оператор заповнює список переліком файлів каталогу, іноді з підкаталогами й іменами доступних дисків:

SendMessage(hWndList, LB_DIR, iAttr,(LPARAM)szFileSpec);

Параметр iAttr – це код атрибута файлу, він визначає атрибути відображуваних у списку файлів.

Параметр szFileSpec – це покажчик на рядок, що задає специфікацію файлів. Така специфікація не впливає на підкаталоги, що містяться в списку.

Розглянемо, які значення, об'єднані порозрядовим АБО, можна використовувати для завдання атрибутів файлів:

Як молодший байт використовується звичайний атрибут файлу: DDL_READWRITE – звичайний файл; DDL_READONLY – файл тільки для читання, DDL_HIDDEN – схований файл; DDL_SYSTEM – системний файл; DDL_DIRECTORY – підкаталог; DDL_ARCHIVE – файл із встановленим архівним бітом.

Старший байт забезпечує деякий додатковий контроль над виведеними іменами: DDL_DRIVES – включення імен дисків; DDL_EXCLUSIVE – включати тільки файли з зазначеними атрибутам.

От як буде, наприклад, виглядати виклик, що виводить у список імена усіх файлів поточного каталогу й імена всіх підкаталогів цього каталогу (у виді [subdir]):

SendMessage(hWndList,LB_DIR,

DDL_READWRITE| // звичайний файл

DDL_READONLY| // файл тільки для читання

DDL_HIDDEN| // схований файл

DDL_SYSTEM| // системний файл

DDL_DIRECTORY| // підкаталог

DDL_ARCHIVE, // файл із встановленим архівним бітом

(LPARAM) "*.*");

Якщо для списку не використовується стиль LBS_SORT, то імена файлів і каталогів виводяться упереміш, а імена доступних дисків виявляються наприкінці списку.

Зауваження. Коли користувач клацає мишею над вікном списку, вікно списку одержує фокус уведення. Якщо вікно списку має фокус уведення, то для вибору пунктів можна користатися як мишею, так і клавіатурою.

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

Вікно списку посилає батьківському вікну повідомлення WM_COMMAND, у старшому слові параметра wParam цього повідомлення міститься код повідомлення:

  • LBN_ERRSPACE - перевищений розмір пам'яті, відведений для списку;

  • LBN_SELCHANGE - змінений поточний вибір (підсвічування переміщається за списком);

  • LBN_DBLCLK - на пункті списку мав місце подвійний щелчок мишею.

Зауваження. Вікно списку посилає коди повідомлення LBN_SELCHANGE і LBN_DBLCLK тільки в тому випадку, якщо в стиль дочірнього вікна включений ідентифікатор LBS_NOTIFY.

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

case WM_COMMAND:

{ UINT idCtl=LOWORD(wParam); // ідентифікатор дочірнього вікна

UINT code=HIWORD(wParam); // код повідомлення

HWND hChild=(HWND)lParam; // дескриптор дочер. вікна

If(idCtrl==ID_listbox&&code==LB_SELCHANGE)

{

// поточний вибір у списку змінився

. . .

}

};

return 0;

Для приклада створимо додаток CONTROLS, що використовує такі дочірні елементи керування як списки і смуги прокручування, що є частиною вікна редагування. Створюваний додаток буде аналогом відомої в операційній системі UNIX утиліти head, що виводить на екран початкові рядки файлу. Однак, завдяки смугам прокручування, на екран буде виводитися файл цілком якщо його розмір не перевищує 8 кілобайт.

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

Рисунок 2.8 Зовнішній вигляд програми 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[] = " Head" ;

MSG msg ;

WNDCLASS wndclass ;

RegisterClass (&wndclass) ;

hWnd = CreateWindow (szAppName, " File Head ", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;

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

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

{

HDC hdc ;

PAINTSTRUCT ps ;

RECT rect ;

TEXTMETRIC tm ;

switch (iMsg)

{

case WM_CREATE :

hdc = GetDC (hwnd) ;

SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

GetTextMetrics (hdc, &tm) ;

ReleaseDC (hwnd, hdc) ;

rect.left = 20 * tm.tmAveCharWidth ;

rect.top = 3 * tm.tmHeight ;

При малюванні на екрані (у вікні) додатку не потрібно створювати контекст пристрою, використовуючи CreateDC. Замість цього воно може одержати дескриптор контексту пристрою, що представляє робочу область вікна за допомогою функції GetDC чи ціле вікно за допомогою функції GetWindowDC.

Потім вибираємо шрифт SYSTEM_FIXED_FONT у контекст відображення.

  1. Тепер створіть статичний елемент керування з текстом, список і вікно редагування для висновку вмісту файлів, додавши до програми наступний код:

#include <windows.h>

#include <direct.h>

#define MAXPATH 256

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

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

{

RECT rect ;

HDC hdc ;

PAINTSTRUCT ps ;

TEXTMETRIC tm ;

UINT ID_edit1=1;

static HWND hwndList, hwndText, hWndEdit;

switch (iMsg)

{

case WM_CREATE :

rect.left = 20 * tm.tmAveCharWidth ;

rect.top = 3 * tm.tmHeight ;

hwndList = CreateWindow ("listbox", NULL,

WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD,

tm.tmAveCharWidth, tm.tmHeight * 3,

tm.tmAveCharWidth * 13,

tm.tmHeight * 10,

hwnd, (HMENU) 1,

(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),

NULL) ;

hwndText = CreateWindow ("static", getcwd (szBuffer, MAXPATH),

WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,

tm.tmAveCharWidth, tm.tmHeight,

tm.tmAveCharWidth * MAXPATH, tm.tmHeight,

hwnd, (HMENU) 2,

(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),

NULL) ;

hWndEdit=CreateWindow("edit",NULL, WS_CHILDWINDOW|ES_MULTILINE| WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|ES_AUTOVSCROLL| ES_AUTOHSCROLL,

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