Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual1.doc
Скачиваний:
8
Добавлен:
07.03.2016
Размер:
4.35 Mб
Скачать

8.2. Робота зі списками і комбінованими полями

Приклад роботи знаходиться у папці DISK\dialog\dialog2.

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

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

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

За допомогою AppWizard необхідно створити програму combos на базі діалогового вікна. Все готово до заповнення комбінованого поля даними.

Ініціалізація комбінованого поля

Комбіновані поля ініціалізуються в методі OnInitDialog():

BOOL CCombosDlg::OnInitDialog()

{

CDialog::OnInitDialog();

.............................................................

}

Тепер можна переходити до ініціалізації комбінованого поля. Вона виконується практично так само, як і в попередньому прикладі. За допомогою ClassWizard створюється змінна, що представляє комбіноване поле, і має назву m_combo. Вона повинна належати до класу CComboBox. Методи класу CComboBox перераховані в табл. 8.1.

Таблиця 8.1.

Методи класу CComboBox

Метод

Призначення

AddString

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

CComboBox

Конструює об'єкт класу CComboBox

Clear

Видаляє поточний виділений фрагмент у текстовому полі

CompareItem

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

Copy

Копіює поточний виділений фрагмент в буфер обміну

Create

Створює комбіноване поле як елемент Windows і пов'язує його з об'єктом CComboBox

Cut

Видаляє поточний виділений фрагмент і поміщає його в буфер обміну

DeleteItem

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

DeleteString

Видаляє рядок зі списку

Dir

Включає в список комбінованого поля імена файлів

DrawItem

Викликається, коли виникає необхідність у нестандартному промальовуванні комбінованого поля

FindString

Шукає у списку перший рядок із заданим префіксом

FindStringExact

Шукає у списку перший рядок, який точно співпадає із заданим

GetCount

Повертає кількість рядків у списку

Продовження таблиці 8.1

Метод

Призначення

GetCurSel

Отримує індекс поточного вибраного рядка списку (якщо він є)

GetDroppedControlRect

Отримує екранні координати видимої частини списку, що розкривається

GetDroppedState

Визначає, чи видно в даний момент список, що розкривається

GetDroppedWidth

Отримує мінімальну допустиму ширину списку, що розкривається

GetEditSel

Визначає позицію першого і останнього символів поточного виділеного фрагмента

GetExtendedUI

Визначає, який користувацький інтерфейс має комбіноване поле – стандартний або розширений

GetHorizontalExtent

Повертає кількість пікселів, на яку список може прокручуватися по горизонталі

GetItemData

Повертає 32-розрядну величину, пов'язану з рядком списку

GetItemDataPtr

Повертає 32-розрядну величину, пов'язану з рядком списку у вигляді вказівки

GetItemHeight

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

GetLBText

Отримує текст рядка зі списку

GetLBTextLen

Отримує довжину рядка в списку

GetLocale

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

GetTopIndex

Повертає перший індекс відображаємого рядка списку

InitStorage

Виділяє блоки пам'яті для зберігання рядків списку

InsertString

Вставляє рядок у список

LimitText

Обмежує довжину тексту, який може вводитися користувачем в текстове поле

MeasureItem

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

Paste

Вставляє в текстове поле вміст буфера обміну

ResetContent

Видаляє весь вміст списку і текстового поля

SelectString

Шукає і вибирає рядок у списку

SetCurSel

Вибирає рядок у списку

SetDroppedWidth

Задає мінімальну допустиму ширину списку, що розкривається

SetEditSel

Виділяє символи в текстовому полі

SetExtendedUI

Визначає користувацький інтерфейс комбінованого поля – стандартний або розширений

SetHorizontalExtent

Визначає кількість пікселів, на яку список може прокручуватися по горизонталі

SetItemData

Задає значення 32-розрядної величини, пов'язаної з рядком списку

SetItemDataPtr

Задає значення 32-розрядної величини, пов'язаної з рядком списку у вигляді вказівки

SetItemHeight

Задає висоту рядків списку або висоту текстового поля

SetLocale

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

SetTopIndex

Визначає індекс першого відображаємого рядка списку

ShowDropDown

Відображає або приховує список

Підказка. Ви також можете зв'язати змінну зі значенням комбінованого поля – ним вважається поточний зміст текстового поля.

Як і в попередньому прикладі, для занесення до списку необхідних рядків («Рядок 01» - «Рядок 12») ми скористаємося методом AddString():

BOOL CCombosDlg::OnInitDialog()

{

CDialog::OnInitDialog();

m_combo.AddString("Рядок 01");

m_combo.AddString("Рядок 02");

m_combo.AddString("Рядок 03");

m_combo.AddString("Рядок 04");

m_combo.AddString("Рядок 05");

m_combo.AddString("Рядок 06");

m_combo.AddString("Рядок 07");

m_combo.AddString("Рядок 08");

m_combo.AddString("Рядок 09");

m_combo.AddString("Рядок 10");

m_combo.AddString("Рядок 11");

m_combo.AddString("Рядок 12");

// Додати команду "About ..." в системне меню.

.............................................................

}

Крім того, необхідно вибрати зі списку перший рядок («Рядок 01»), щоб при першій появі комбінованого поля на екрані в текстовому полі відображався його зміст (у протилежному випадку текстове поле виявиться порожнім):

BOOL CCombosDlg::OnInitDialog()

{

CDialog::OnInitDialog();

m_combo.AddString("Рядок 01");

m_combo.AddString("Рядок 02");

m_combo.AddString("Рядок 03");

m_combo.AddString("Рядок 04");

m_combo.AddString("Рядок 05");

m_combo.AddString("Рядок 06");

m_combo.AddString("Рядок 07");

m_combo.AddString("Рядок 08");

m_combo.AddString("Рядок 09");

m_combo.AddString("Рядок 10");

m_combo.AddString("Рядок 11");

m_combo.AddString("Рядок 12");

m_combo.SetCurSel(0);

// Додати команду "About ..." в системне меню.

.............................................................

}

Перейдемо до обробки можливих дій користувача.

Визначення вибраного рядка

Наша програма повинна повідомляти, який рядок списку вибрав користувач. У цій ситуації комбіноване поле посилає програмі повідомлення CBN_SELCHANGE. Префікс CBN означає «Combo Box Notification», тобто «повідомлення від комбінованого поля». Це сімейство складається з повідомлень CBN_CLOSEUP, CBN_DBLCLICK, CBN_DROPDOWN, CBN_EDITCHANGE, CBN_EDITUPDATE, CBN_ERRSPACE, CBN_KILLFOCUS, CBN_SELCHANGE, CBN_SELENDCANCEL, CBN_SELENDOK і CBN_SETFOCUS. За допомогою ClassWizard зв’яжемо обробник з повідомленням CBN_SELCHANGE.

Підказка. Всі можливі повідомлення перераховані в ClassWizard на вкладці Message Maps у списку Messages.

ClassWizard пропонує присвоїти новому методу ім'я OnSelchangeCombo1(). Підтвердіть запропоноване ім'я та відкрийте код методу:

void CCombosDlg::OnSelchangeCombo1()

{

// ЗРОБИТИ: додайте код для обробки повідомлень

// від елемента

}

Виклик цього методу означає, що користувач вибрав зі списку комбінованого поля новий рядок; ми хочемо повідомити про це в текстовому полі, використовуючи змінну m_text. Робиться це так само, як і у випадку зі списком, – слід викликати метод GetCurSel(), після чого оновити вміст текстового поля методом UpdateData():

void CCombosDlg::OnSelchangeCombo1()

{

m_combo.GetLBText(m_combo.GetCurSel(), m_text);

UpdateData(false);

}

Підказка. Щоб перехопити зміни, що вносяться до вмісту текстової частини комбінованого поля, слід за допомогою ClassWizard організувати в програмі обробку повідомлення CBN_EDITCHANGE.

Запустимо програму. При виборі нового пункту вміст відповідного рядка з’являється в текстовому полі (рис. 8.4). Наша програма успішно працює і дозволяє вибирати з комбінованого поля нові рядки.

Рис. 8.4. Програма combos дозволяє вибирати рядки з комбінованого поля

Вихідний текст програми combos міститься у файлах combosDlg.h/combosDlg.cpp.

combosDlg.h і combosDlg.cpp

// CombosDlg.h: заголовочний файл

//

# if !defined(AFX_COMBOSDLG_H__ED674083_9309_11D0_8860_444553540000__INCLUDED_)

#define AFX_COMBOSDLG_H__ED674083_9309_11D0_8860_444553540000__INCLUDED_

#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000

/////////////////////////////////////////////////////////////////////////

// Діалогове вікно CCombosDlg

class CCombosDlg: public CDialog

{

// Створення

public:

CCombosDlg(CWnd* pParent = NULL); // Стандартний конструктор

// Дані діалогового вікна

//{{AFX_DATA(CCombosDlg)

enum { IDD = IDD_COMBOS_DIALOG };

CComboBox m_combo;

CString m_text;

//}}AFX_DATA

// Перевизначення віртуальних функцій, згенерованих ClassWizard

//{{AFX_VIRTUAL(CCombosDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // Підтримка DDX/DDV

//}}AFX_VIRTUAL

// Реалізація

protected:

HICON m_hIcon;

// Згенеровані функції схеми повідомлень

//{{AFX_MSG(CCombosDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand (UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

afx_msg void OnSelchangeCombo1();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

// {{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ буде вставляти додаткові

// оголошення перед попереднім рядком.

#endif

// !defined(AFX_COMBOSDLG_H__ED674083_9309_11D0_8860_444553540000__INCLUDED_)

// combosDlg.cpp: файл реалізації

//

#include "stdafx.h"

#include "combos.h"

#include "combosDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

////////////////////////////////////////////////// ///////////////////////

// Діалогове вікно CAboutDlg, виведене за командою About

class CAboutDlg: public CDialog

{

public:

CAboutDlg();

// Дані діалогового вікна

//{{AFX_DATA(CAboutDlg)

enum {IDD = IDD_ABOUTBOX};

//}}AFX_DATA

// Перевизначення віртуальних функцій, згенеровані ClassWizard

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // Підтримка DDX/DDV

//}}AFX_VIRTUAL

// Реалізація

protected:

//{{AFX_MSG(CAboutDlg)

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// Обробники повідомлень відсутні

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////

// Діалогове вікно CCombosDlg

CCombosDlg::CCombosDlg(CWnd* pParent /*=NULL*/)

: CDialog(CCombosDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CCombosDlg)

m_text = _Т("");

//}}AFX_DATA_INIT

// Зверніть увагу на те, що в Win32 LoadIcon

// не вимагає подальшого виклику DestroyIcon

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CCombosDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CCombosDlg)

DDX_Control(pDX, IDC_COMBO1, m_combo);

DDX_Text(pDX, IDC_EDIT1, m_text);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CCombosDlg, CDialog)

//{{AFX_MSG_MAP(CCombosDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////

// Обробники повідомлень CCombosDlg

BOOL CCombosDlg::OnInitDialog()

{

CDialog::OnInitDialog();

m_combo.AddString("Рядок 01");

m_combo.AddString("Рядок 02");

m_combo.AddString("Рядок 03");

m_combo.AddString("Рядок 04");

m_combo.AddString("Рядок 05");

m_combo.AddString("Рядок 06");

m_combo.AddString("Рядок 07");

m_combo.AddString("Рядок 08");

m_combo.AddString("Рядок 09");

m_combo.AddString("Рядок 10");

m_combo.AddString("Рядок 11");

m_combo.AddString("Рядок 12");

m_combo.SetCurSel(0);

// Додати команду "About ..." в системне меню.

// Значення IDM_ABOUTBOX має перебувати в діапазоні

// системних команд.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING,

IDM_ABOUTBOX, strAboutMenu);

}

}

// Поставити значок для діалогового вікна. Бібліотека

// робить це автоматично, якщо головне вікно програми

// не є діалоговим.

SetIcon(m_hIcon, TRUE); // Встановити великий значок

SetIcon(m_hIcon, FALSE); // Встановити малий значок

// ЗРОБИТИ: додайте додаткову ініціалізацію

return TRUE; // повернути TRUE, якщо тільки ви

// не передаєте фокус елементу

}

void CCombosDlg::OnSysCommand(UINT nID, LPARAM IParam)

{

if ((nID & OxFFFO) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, IParam);

}

}

// Якщо в діалоговому вікні присутня кнопка згортання,

// наведений нижче код знадобиться для малювання значка.

// У додатках MFC, які використовують модель документ / вид,

// це робиться автоматично.

void CCombosDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // контекст пристрою

// для малювання

SendMessage(WM_ICONERASEBKGND,

(WPARAM) dc.GetSafeHdc(), 0);

// Вивести значок у центрі клієнтського

// прямокутника

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

Cflect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// Намалювати значок

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// Викликається системою для отримання курсору,

// який відображається при перетягуванні згорнутого вікна.

HCURSOR CCombosDlg::OnQueryDragIcon()

{

return (HCURSOR) m.hIcon;

}

void CCombosDlg::OnSelchangeCombo1()

{

m_combo.GetLBText(m_combo.GetCurSel(), m_text);

UpdateData(false);

}

На наступному етапі розглянемо ускладнений приклад зі списками.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]