У вас вопросы?
У нас ответы:) SamZan.net

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

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 29.12.2024

Лабораторна робота №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,

                             150,50,470, 400, hwnd,(HMENU)ID_edit1,

                             ((LPCREATESTRUCT) lParam) -> hInstance,

                             NULL);   

Кожне дочірнє вікно має дескриптор вікна і його ідентифікатор, що є унікальним серед інших. Знання одного з цих елементів дозволяє вам одержати іншиї. Якщо ви знаєте дескриптор дочірнього вікна, то можете одержати його ідентифікатор у такий спосіб:

id = GetWindowLong (hwndChild, GWL_ID);

Тут, при створенні статичного елемента керування, використовується функція getcwd(), що служить для одержання поточного робочого каталогу. Т.е. повний шлях до поточного робочому каталогу виводиться в статичному елементі керування.

Створення смуг прокручування у вікні редагування, здійснюється шляхом додавання наступних значень у завданні стилю вікна: WS_HSCROLL| WS_VSCROLL.

  1.  А тепер, щоб заповнити список іменами усіх файлів поточного каталогу, додайте до програми наступний код:

hWndEdit=CreateWindow("edit",NULL, WS_CHILDWINDOW|ES_MULTILINE|

WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL| ES_AUTOVSCROLL|ES_AUTOHSCROLL,

                             150,50,470, 400, hwnd,(HMENU)ID_edit1,

                             ((LPCREATESTRUCT) lParam) -> hInstance,

                             NULL);

SendMessage (hwndList, LB_DIR, DDL_READWRITE|DDL_READONLY| DDL_HIDDEN|DDL_SYSTEM|DDL_DIRECTORY, (LPARAM) "*.*") ;

              return 0 ;

  1.  При зміні розмірів вікна, необхідно динамічно обновляти вміст структури rect:

SendMessage (hwndList, LB_DIR, DDL_READWRITE|DDL_READONLY| DDL_HIDDEN|DDL_SYSTEM|DDL_DIRECTORY, (LPARAM) "*.*") ;

              return 0 ;

case WM_SIZE :

              rect.right  = LOWORD (lParam) ;

              rect.bottom = HIWORD (lParam) ;

              return 0 ;

  1.  При запуску додатка фокус уведення повинний одержувати список:

rect.bottom = HIWORD (lParam) ;

              return 0 ;

         case WM_SETFOCUS :

              SetFocus (hwndList) ;

              return 0 ;

  1.  Обробка повідомлення WM_COMMAND буде виглядати в такий спосіб:

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

    {

static char  szFile[MAXPATH], szBuffer[MAXPATH + 1] ;

static HWND     hwndList, hwndText, hWndEdit;

     static OFSTRUCT ofs ;

static BOOL     bValidFile ;

case WM_SETFOCUS :

              SetFocus (hwndList) ;

              return 0 ;

         case WM_COMMAND :

              if (LOWORD (wParam) == 1 && HIWORD (wParam) == LBN_DBLCLK)

                   {

                   if (LB_ERR == (i = SendMessage (hwndList,

                                                   LB_GETCURSEL, 0, 0L)))

                        break ;

                   SendMessage (hwndList, LB_GETTEXT, i, (LPARAM) szBuffer) ;

                   if (-1 != OpenFile (szBuffer, &ofs, OF_EXIST | OF_READ))

                        {

                        bValidFile = TRUE ;

                        strcpy (szFile, szBuffer) ;

                        getcwd (szBuffer, MAXPATH) ;

                        if (szBuffer [strlen (szBuffer) - 1] != '\\')

                             strcat (szBuffer, "\\") ;

                        SetWindowText (hwndText, strcat (szBuffer, szFile)) ;

                        }

                   else

                        {

                        bValidFile = FALSE ;

                        szBuffer [strlen (szBuffer) - 1] = '\0' ;

                        chdir (szBuffer + 1) ;

                        getcwd (szBuffer, MAXPATH) ;

                        SetWindowText (hwndText, szBuffer) ;

                        SendMessage (hwndList, LB_RESETCONTENT, 0, 0L) ;

                        SendMessage (hwndList, LB_DIR, 0x37, (LONG) "*.*") ;

                        }

                   InvalidateRect (hwnd, NULL, TRUE) ;

                   }

              return 0 ;

При обробці в WndProc повідомлення WM_COMMAND, для контролю обраного пункту, використовується функція Windows OpenFile. Ця функція в загальному виді виглядає так:

HFILE OpenFile(

   LPCSTR lpFileName,   // покажчик на ім'я файлу 

   LPOFSTRUCT lpReOpenBuff, // покажчик на буфер інформації про файл  

   UINT uStyle    // режим відкриття 

  );

Якщо функція OpenFile повертає помилку, значить обраний не файл, а, можливо, підкаталог і змінна bValidFile встановлюється в FALSE. Потім для зміни підкаталогу в програмі HEAD використовується функція chdir. Програма посилає вікну списку повідомлення LB_RESETCONTEXT для відновлення контексту і повідомлення LB_DIR для заповнення вікна списку переліком файлів нового підкаталогу.

  1.  При обробці повідомлення WM_PAINT в окно редагування буде виводитися уміст файлу, обраного в списку файлів. Для цього додайте до програми наступний код:

#include <windows.h>

#include <direct.h>

#define  MAXPATH     256

#define  MAXREAD    8192

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)

    {

static char     sReadBuffer[MAXREAD] ;

int             iHandle, i ;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

              SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

              SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT)) ;

              SetBkColor   (hdc, GetSysColor (COLOR_BTNFACE)) ;

              if (bValidFile && -1 != (iHandle =

                        OpenFile (szFile, &ofs, OF_REOPEN | OF_READ)))

                   {

                   i = _lread (iHandle, sReadBuffer, MAXREAD) ;

                   _lclose (iHandle) ;

                   SetWindowText(hWndEdit, sReadBuffer);

                    }

              else

                   bValidFile = FALSE ;

EndPaint (hwnd, &ps) ;

return 0 ;

При обробці повідомлення WM_PAINT у віконній процедурі відкривається файл із використанням функції Windows OpenFile.  Значенням функції, що повертається, є дескриптор файлу MS-DOS, що може бути переданий функціям Windows _lread і _lclose. Вміст файлу виводиться у вікно редагування за допомогою функції SetWindowText().

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

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

2. Створіть програму, аналогічну програмі завдання 2 Лабораторної роботи №5, але замість радіокнопок використовуйте список. Результат визначається в залежності від обраного рядка списку.

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

  1.  Які списки можна створити на базі визначеного класу “listbox”?
  2.  На базі якого класу створюється список, що випадає? Комбінацією яких інших елементів керування він є?
  3.  Як додаток може створити скількох завгодно смуг перегляду у своєму вікні? Який визначений клас при цьому використовується?
  4.  Для чого звичайний додаток використовує статичні елементи керування? Чи одержує батьківське вікно такого елемента від нього повідомлення?




1. Реферат- технологическая практика ПрограммаShower-конвертор табличных файлов
2. Тема Общая характеристика объектов недвижимости Сложность минимум
3. Лабораторная работа 7 Изучение явления внешнего фотоэффекта
4. Лабораторная работа ’ 3 по предмету Информатика на тему Структура данных ~ связный список Г
5. 1755; ~ многобуквенные адреса например CR10
6. Реферат Работу выполнил Нелин Александр Алексеевич Курс 2 группа
7. ВОСПАЛЕНИЕ МОЧЕВОГО ПУЗЫРЯ-Принимать 2 стол
8. х гг. XVI в. и их последствия.
9. Таблица. А в программе Word более современной версии 20072010 для того чтобы вставить таблицу нужно нажать
10. реферат дисертації на здобуття наукового ступеня доктора технічних наук
11. Витте Сергей Юлиевич
12. рефератов- Одиссея Гомера как источник знаний по истории Древней Греции.
13. потерянного поколения на примере одного из художественных произведений Трагедия потерянного поко
14. правовая информатика как уже отмечалось студенты должны приобрести знания об информационных процессах ю
15. Лекция 6 СЕЛЬСКОХОЗЯЙСТВЕННЫЕ ПРОИЗВОДСТВЕННЫЕ КООПЕРАТИВЫ План 1
16. Права военнослужащих- Защита Отечества является долгом и обязанностью гражданина Российской Федерации.html
17. тема эритроциты барана и гемолитическая сыворотка вторая система
18. бытовых нужд Загрязненная вода попадает в систему канализации и удаляется из гостиницы
19. тема крови включает в себя-кровь и лимфу;органы кроветворения и иммунопоэза; клетки крови выселившиеся из кр
20. Анаксагор