Порядок выполнения работы. Создать указанное в задании приложение с использованием модального диалога с
Создать указанное в задании приложение с использованием модального диалога с запуском его из главного меню.
Оттранслируйте и постройте задачу, запустите ее.
Проанализируте полученный код. Обратите внимание на таблицу сообщений. Найдите макросы DECLARE_MESSAGE и таблицы сообщений.
Добавьте проверку данных, вводимых в диалоге.
Добавьте новый диалог. Используя новый пункт меню, запустите его как немодальный.
Добавьте возможность в программе запускать несколько немодальных диалогов одновременно.
Исправьте диалог About. Замените иконку, а также выводимый текст.
Поэкспериментируйте с различными диалоговыми элементами, применяемыми в диалогах. Добейтесь обмена данными между диалоговыми элементами и переменными и покажите значения переменных, используя AfxMessage.
Попробуйте добавить динамически один из элементов Windows.
Вопросы для самопроверки.
Как строятся диалоговые окна с использованием Visual C++?
Какие существуют типы диалоговых панелей? Какие классы MFC обеспечивают работу (представляют) эти дилоговые панели?
Чем отличаются модальные и немодальные диалоговые окна?
Каковы этапы создания и отображения модальной диалоговой панели?
Каковы этапы создания и отображения немодальной диалоговой панели?
Для чего предназначен механизм автоматического обмена данными (DDX) и механизм автоматической проверки данных (DDV)?
Какой виртуальный метод класса CDialog должен быть переопределен для реализации механимов DDX и DDV?
Имеет ли право приложение напрямую вызывать метод DoDataExchange? Как обеспечить обмен данными между элементами управления диалоговой панели и переменными класса, представляющего эту диалоговуюпанель?
Вызов какого метода (и с каким параметром) обеспечивает инициализацию диалоговой панели, при которой информация из переменных класса отображается в элементах управления диалоговой панели?
Вызов какого метода (и с каким параметром) обеспечивает копирование информации из элементов управления диалоговой панели в переменные класса?
Создается ли Windows-окно диалога при создании объекта класса CDialog?
Каким методом создается Windows-окно модального диалога и когда этот метод возвращает управление? Удаляется ли при этом: 1) Windows-окно диалога, 2) объект класса CDialog?
Каким методом создается Windows-окно немодального диалога? Что необходимо сделать для удаления (для закрытия) этого окна? Удаляется ли при этом объект класса CDialog?
Для чего предназначены следующие средства автоматизации разработки приложения: 1) MFC AppWizard, 2) MFC ClassWizard, 3) редактор ресурсов?
Какой класс является родительским для всех классов диалоговых панелей?
Какие параметры передаются констуктору класса диалоговой панели? В какой блок констуктора средство ClassWizard добавляет код инициализации переменных класса диалога, присоединенных к элементам управления панели?
Где размещаются вызовы методов, обеспечивающих процесс обмена и проверки данных
Вызов каких методов класса диалога приводит к созданию Windows-окна диалога?
Какой метод класса диалога вызывается в ответ на создание Windows-окна панели диалога? Когда это происходит?
Как с помощью средства ClassWizard можно: 1) создать новый класс, 2) добавить в класс новые методы, 3) включить в класс новые переменные, связанные с элементами управления панели диалога?
Какие классы создает средство AppWizard при создании приложения, основанного на диалоге? В каких файлах проекта располагаются их объявление и реализация?
Почему метод InitInstance класса приложения, основанного на диалоге, возвращает значение FALSE?
Как разрешить использование русского текста в меню и диалогоах?
Какие стандартные элементы Windows вы научились использовать в диалогах?
Как создать переключатель?
Как динамически задать появление элемента в диалоге?
6 Приложение I
6.1 Описание классов стандартных элементов Windows.
Рассмотрим некоторые классы элементов управления Windows:
Класс | Элемент управления |
CStatic | Статический текст или изображение |
CButton | Командные кнопки |
CListBox | Список |
CComboBox | Комбинированный список |
CEdit | Поле редактирования |
CScrollBar | Полоса прокрутки |
6.2 Создание элементов
Все элементы управления могут быть созданы с помощью редактора ресурсов ( см. лаб. раб. № 3,4) или динамически во время выполнения приложения. Создание элементов с использованием редактора ресурсов и связь их с переменными класса диалоговой панели рассмотрено подробно в теоретических сведениях к лаб. раб. 3,4. При создании элементов задаются стили и их комбинации через логическую функцию |. Для каждого вида элемента наборы стилей свои, хотя есть стили, общие для всех окон, например, WS_VISIBLE или WS_DISABLE.
Для создания элемента динамически сначала создается объект данного класса, а затем вызывается функция-член его Create. Для диалога это действие выполняется в функции OnInitDialog. Ниже приводится пример создания элемента поле редактирования в диалоге. Текст вводится вручную в файлы, созданные AppWizard и ClassWizard.
class CMyDialog:public CDialog
{
…
protected:
CEdit m_Edit;
…
public:
BOOL OnInitDialog();
…
}
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitialog();
…
CRect rect(20,20,100,50);
m_Edit.Create(WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL|
WS_BORDER,rect,this,IDC_EDIT);
m_Edit.SetFocus();
…
return FALSE;//так как выполнена установка фокуса, то должно
//возвращаться значение FALSE
}
6.3 Элемент статического типа - CStatic.
Класс CStatic позволяет выводить текст, пиктограммы, курсоры, битовые массивы. Обычно статические элементы не требуют ввода, но они могут уведомлять родительское окно о нажатии клавиши, но вэтом случае при их создании должен быть установлен стиль SS_NOTIFY.
Конструктор не создает объект Windows: CStatic::CStatic();
Инициализация выполняется функцией Create:
BOOL CStatic::Create(LPCTSTR lpszText, // текст в элементе управления
DWORD dwStyle, // стиль статического элемента
const RECT & rect, // положение и размер элемента
CWnd *pParentWnd, // родительское окно, не равен NULL
UINT nID=0xffff); // идентификатор для ссылки на него
Стиль статического элемента | Описание |
WS_CHILD | Указывается всегда, т.к. элемент не может быть окном верхнего уровня |
WS_VISIBLE | Чтобы элемент был виден сразу же после создания |
WS_DISABLE | Элемент недоступен для использования |
SS_BLACKFRAME | Прямоугольник цвета рамки окна |
SS_BLACKRECT | Закрашенный прямоугольник с цветом рамки окна |
SS_CENTER | Определяет прямоугольник и выводит текст в центре |
SS_GRAYFRAME | Прямоугольник с рамкой цвета фона клиентской области родительского окна |
SS_GRAYRECT | Закрашенный прямоугольник с цветом фона клиентской области родительского окна |
SS_ICON | Задает пиктограмму для отображения, lpszText - имя пиктограммы из файла ресурсов |
SS_LEFT | Определяет прямоугольник и выводит текст по левому краю |
SS_LEFTNOWORDWRAP | Словы не переносятся на следующую строку |
SS_NOPREFIX | Если этот стиль не определен, то за знаком & идет символ-акселератор, тогда при выводе текста символ подчеркивается, при этом стиле символ & выводится |
SS_RIGHT | Определяет прямоугольник и выводит текст по правому краю |
SS_SIMPLE | Определяет прямоугольник и выводит текст по левому краю |
SS_USERITEM | Элемент определяется пользователем |
SS_WHITEFRAME | Прямоугольник с рамкой белого цвета |
SS_WHITERECT | Закрашенный прямоугольник белого цвета |
SS_BITMAP | Для битового массива |
SS_ICON | Для курсоров и пиктограмм |
SS_ENHMETAFILE | Для расширенных метафайлов |
SS_CENTERIMAGE | Для трех предыдущих расположение в центре |
Если элемент создается в редакторе ресурсов, то функция Create не вызывается пользователем, но все стили можно задать в диалоге свойств элемента.
6.3.1 Некоторые функции для работы со статическим элементом.
HICON CStatic::SetIcon(HICON hIcon);- вывод пиктограммы с идентификатором hIcon. Возвращает NULL или прежний идентификатор пиктограммы.
HICON CStatic::GetIcon();- возврат идентификатора пиктограммы, связанной с элементом.
Если идентификатор статического элемента, созданного в редакторе ресурсов и предназначенного для отображения пиктограммы - ID_MYICON, а идентификатор иконки, созданной там же - IDR_MYICON, то для загрузки пиктограммы можно применить код в одном из методов диалогового родительского класса:
CStatic * pWnd = (CStatic *)GetDlgItem(ID_MYICON);
pWnd->SetIcon(IDR_MYICON);
HBITMAP CStatic::SetBitmap( HBITMAP hBitmap ); указывает идентификатор битового массива, созданного, например, в редакторе ресурсов.
HBITMAP CStatic::GetBitmap( ) const; возаращает идентификатор битового массива, связанного с данным элементом.
6.4 Кнопки - CButton
Кнопки определяют и командные кнопки (PUSHBUTTON), и кнопки - флажки (CHECKBUTTON), и кнопки - переключатели (RADIOBUTTON), и кнопки с изображениями, и т. д.
Стили кнопок могут быть заданы при создании кнопки.
Стиль кнопки | Описание |
WS_CHILD | Всегда задается при создании кнопки |
WS_VISIBLE | Следует указывать, чтобы кнопка сразу отображалась, иначе для нее надо будет вызывать ShowWindow() |
WS_DISABLED | Кнопка изначально недоступна |
WS_GROUP | Объединение кнопок в группу, обязательно применяется для первого переключателя и после последнего в группе, переход от кнопки к кнопке при помощи клавиш перемещения курсора |
WS_TABSTOP | Переход от кнопки к кнопке по клавише TAB |
BS_PUSHBUTTON | Простая кнопка, посылает сообщение WM_COMMAND окну- владельцу |
BS_CHECKBOX | Определяет флажок с двумя состояниями |
BS_RADIOBUTTON | Определяет переключатель для выбора из нескольких кнопок |
BS_GROUPBOX | Прямоугольная рамка для объединения других кнопок |
BS_DEFPUSHBUTTON | Кнопка "по умолчанию" для диалога, именно она посылает сообщение по нажатии клавиши ENTER |
BS_AUTOCHECKBOX | то же самое, что и BS_CHECKBOX, но смена состояния производится автоматически при выборе кнопки |
BS_AUTORADIOBUTTON | то же самое, что и BS_RADIOBUTTON, но смена состояния производится автоматически при выборе кнопки |
BS_3STATE | то же самое, что и BS_CHECKBOX, но элемент имеет 3 состояния |
BS_AUTO3STATE | то же самое, что и BS_3STATE, но смена состояния производится автоматически при выборе кнопки |
BS_LEFTTEXT | Расположение текста слева от кнопки, применяется вместе сос стилями BS_CHECKBOX и BS_RADIOBUTTON |
BS_OWNERDRAW | Кнопка рисуется пользователем, для этого надо переопределить CButton::DrawItem |
BS_TEXT | Кнопка с текстом |
BS_ICON | Кнопка с иконкой или курсором |
BS_BITMAP | Кнопка с рисунком |
BS_LEFT | Выравнивание по левому краю |
BS_RIGHT | Выравнивание по правому краю |
BS_CENTER | Выравнивание по центру |
BS_TOP | Выравнивание по верхнему краю |
BS_BUTTOM | Выравнивание по нижнему краю |
BS_VCENTER | Выравнивание по центру по вертикали |
BS_PUSHLIKE | Кнопка отображается как обычная, но для переключателей и флажков |
BS_MULTILINE | Текст может занять несколько строк |
BS_NOTIFY | Кнопка посылает сообщение уведомление родительскому окну. Стиль не важен для MFC |
BS_FLAT | Кнопка отображается плоской |
BS_RIGHTBUTTON | Расположение текста справа от кнопки, применяется вместе сос стилями BS_CHECKBOX и BS_RADIOBUTTON |
Кнопки посылают два вида сообщений родительскому окну:
ON_BN_CLICKED - одинарное нажатие на кнопку,
ON_BN_DOUBLECLICKED - двойное нажатие на кнопку.
6.4.1 Некоторые функции для работы с кнопками.
Инициализация выполняется функцией Create:
BOOL CButton::Create(LPCTSTR lpszCaption, // текст на кнопке
DWORD dwStyle, // стиль кнопки
const RECT & rect, // положение и размер кнопки
CWnd *pParentWnd, // родительское окно, не равен NULL
UINT nID); // идентификатор кнопки
Определение состояния кнопок выполняется функциями:
UINT CButton::GetState( ) const; - возвращает состояние кнопки.
Полученное значение надо обработать через маску:
0003 - кнопка включена - 1, нет - 0, неопределенное состояние - 2
0004 - выделена кнопка - 1 или нет - 0
0008 - имеет ли кнопка фокус
void CButton::SetState( BOOL bHighlight ); - выделяет кнопку, параметр принимает значения: TRUE - выдеоить, FALSE - нет.
int CButton::GetCheck( ); - состояние кнопки типа флажок и переключатель:
0 - не выбрана;
1 - выбрана;
2 - не определено.
void CButton::SetCheck(int nCheck ); - состояние кнопки типа флажок и переключатель
Изменение стиля кнопки производится функциями:
UINT CButton::GetButtonStyle( );
void CButton::SetButtonStyle(UINT nStyle, BOOL bRedraw=TRUE);
Параметр nStyle задает стиль кнопки, а bRedraw-указывает, надо ли перерисовывать кнопку сразу же.
Для кнопок со стилями BS_ICON, BS_BITMAP, возможна установка пиктограмм, курсоров и битовых массивов. Изображение на кнопке при нажатии на нее сдвигается вниз и вправо.
HICON CButton::GetIcon( ) const;
HICON CButton::SetIcon( HICON hIcon );
HBITMAP CButton::GetBitmap( ) const;
HBITMAP CButton::SetBitmap( HBITMAP hBitmap );
HCURSOR CButton::GetCursor( );
HCURSOR CButton::SetCursor( HCURSOR hCursor );
Если кнопка имеет стиль BS_OWNERDRAW, то требуется обязательное создание класса на основе CButton с переопределенной функцией DrawItem. В файле triangle_button.zip приводится пример, позволяющий нарисовать треугольные кнопки с разными направлениями.
Когда вы связываете элемент типа кнопка с переменной диалогового класса, то тип переменной определяется стилем кнопки: для кнопки - флажка - тип значения -BOOL, а для типа переключатель значение устанавливается типа int, причем значение задает индекс ( начиная с нуля ) выбранного переключателя.
6.5 Поле редактирования CEdit.
Обычно этот элемент используется для реализации поля ввода. Элемент может включать как одну, так и несколько строк. Приложение не контролирует процесс ввода информации. Но можно добавить обработчики в родительское окно для следующих уведомляющих сообщений:
Сообщение | Описание |
ON_EN_CHANGE | Изменился текст в окне |
ON_EN_ERRSPACE | Не хватает памяти для размещения текста |
ON_EN_HSCROLL | Пользователь сделал горизонтальную прокрутку |
ON_EN_KILLFOCUS | Редактор потерял фокус |
ON_EN_MAXTEXT | Текст превысил максимально допустимую длину |
ON_EN_SETFOCUS | Редактор получил фокус ввода |
ON_EN_UPDATE | Редактор собирается отобразить изменения текста, например, можно по этому сообщению изменить размер элемента |
ON_EN_VSCROLL | Пользователь выполнил вертикальную прокрутку |
Стили элемента редактирования показаны в таблице.
Стиль элемента редактирования | Описание |
WS_CHILD | Всегда задается при создании кнопки |
WS_VISIBLE | Следует указывать, чтобы кнопка сразу отображалась, иначе для нее надо будет вызывать ShowWindow() |
WS_DISABLED | Кнопка изначально недоступна |
WS_GROUP | Объединение кнопок в группу, обязательно применяется для первого переключателя и после последнего в группе, переход от кнопки к кнопке при помощи клавиш перемещения курсора |
WS_TABSTOP | Переход от кнопки к кнопке по клавише TAB |
ES_AUTOHSCROLL | Автоматическая прокрутка текста вправо |
ES_AUTOVSCROLL | автоматическая прокрутка текста на одну строку вверх |
ES_CENTER | Центрирует текст |
ES_LEFT | Выравнивание по левому краю |
ES_LOWERCASE | Все символы преобразуются в строчные |
ES_MULTILINE | Задает многострочный редактор |
ES_NOHIDESEL | Редактор снимает выделение с текста при потере фокуса и устанавливает при получении, стиль снимает эту возможность |
ES_OEMCONVERT | Текст конвертируется в набор OEM |
ES_PASSWORD | Выводимые символы заменяются на *. Символ можно заменить, используя функцию SetPasswordChar() |
ES_RIGHT | Выравнивание по правому краю |
ES_UPPERCASE | Все символы преобразуются в прописные |
ES_READONLY | Текст нельзя редактировать |
ES_WANTRETURN | Отсутствие этого стиля приведет при нажатии на ENTER к выполнению команды, связанной с кнопкой по умолчапнию для диалога |
6.5.1 Некоторые функции для работы с элементом редактирования.
Инициализация выполняется функцией Create:
BOOL CEdit::Create(DWORD dwStyle, // стиль элемента
const RECT & rect, // положение и размер кнопки
CWnd *pParentWnd, // родительское окно, не равен NULL
UINT nID); // идентификатор кнопки
DWORD CEdit::GetSel( ) const;
void CEdit::GetSel( int& nStartChar, int& nEndChar ) const; эти функции возвращают позиции выделенного фрагмента.
void CEdit::ReplaceSel( LPCTSTR lpszNewText, BOOL bCanUndo = FALSE ); - функция выполняут замену выделенного фрагмента на указанный в качестве параметра текст.
Для замены всего текста лучше пользоваться функцией CWnd::SetWindowText().
void CEdit::SetSel( DWORD dwSelection, BOOL bNoScroll = FALSE );
void CEdit::SetSel( int nStartChar, int nEndChar, BOOL bNoScroll = FALSE );- функции изменяют выделение текста. Если начальная позиция 0, а конечная -1, то выделяется весь текст, если же начальная позиция -1, то выделение снимается.
void CEdit::Clear( ); - удаление выделенного текста.
void CEdit::Copy( ); - копирование выделенного текста в буфер обмена.
void CEdit::Cut( ); - вырезание выделенного текста в буфер обмена.
void CEdit::Paste( ); - вставка текста из буфера обмена.
BOOL CEdit::Undo( ); - восстановление удаленного текста и отмена последней операции с текстом.
BOOL CEdit::CanUndo( ) const; - определяет, можно ли отменить почледнюю операцию.
void CEdit::EmptyUndoBuffer( ); - отмена действия отмены последней операции.
BOOL CEdit::GetModify( ) const; - возвращает TRUE, если содержимое редактора изменилось.
void CEdit::SetModify( BOOL bModified = TRUE ); - устанавливает или сбрасывает флаг модификации текста.
BOOL CEdit::SetReadOnly( BOOL bReadOnly = TRUE ); - устанавливает режим "только чтение"
TCHAR CEdit::GetPasswordChar( ) const;
void CEdit::SetPasswordChar( TCHAR ch ); - функции для управления символом, выводимым в поле пароля.
int CEdit::GetFirstVisibleLine( ) const; - функция возвращает индекс самой первой видимой строки.
int CEdit::LineLength( int nLine = –1 ) const; возвращает длину указанной строки.
void CEdit::LineScroll( int nLines, int nChars = 0 ); - прокручивает текст в редакторе, nLines - число строк, nChars - число позиций по горизонтали. Параметры могут иметь разные знаки: - -прокпутка вверх и влево, + - вниз и вправо.
int CEdit::LineFromChar( int nIndex = –1 ) const; - получить номер строки, где содержится символ с указанным от начала текста индексом. Если параметр -1, то возвращается номер строки, где содержится первый выделенный символ.
void CEdit::GetRect( LPRECT lpRect ) const; - получить границы форматирования редактора.
void CEdit::LimitText( int nChars = 0 ); - устанавливает максимальную длину текста. При параметре, равном -1, длина текста равна UINT_MAX.
int CEdit::GetLineCount( ) const; возвращает общее число строк в редакторе.
int CEdit::GetLine( int nIndex, LPTSTR lpszBuffer ) const;
int CEdit::GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const; эти функции возвращают число символов в текущей строке и саму строку в указанный буфер.
int CEdit::LineIndex( int nLine = –1 ) const; возвращает индекс текущей строки.
BOOL CEdit::FmtLines( BOOL bAddEOL );
void CEdit::SetTabStops( );
BOOL CEdit::SetTabStops( const int& cxEachStop );
BOOL CEdit::SetTabStops( int nTabStops, LPINT rgTabStops );
void CEdit::SetRect( LPCRECT lpRect ); - изменить размеры прямоугольника, в котором форматируется текст.
DWORD CEdit::GetMargins( ) const; - получить границы полей редактора в пикселах для левого и правого краев.
void CEdit::SetMargins( UINT nLeft, UINT nRight ); - установить границы полей редактора в пикселах.
UINT CEdit::GetLimitText( ) const; - получить значение максимальной длины текста.
void CEdit::SetLimitText( UINT nMax ); - установить максимальную длину текста.
int CEdit::CharFromPos( CPoint pt ) const; - возвращает номер символа ( в младшем слове )и номер строки (в старшем слове ) по указанным координатам.
CPoint CEdit::PosFromChar( UINT nChar ) const; - но номеру символа возвращает его координаты.
6.6 Список CListBox.
Список - элемент, включающий несколько строк текста, позволяющий выбрать из них одну или несколько. Список посылает родительскому окну различные сообщения-извещения. Для них предусмотрены макросы, добавляемые в карту сообщений. Большинство сообщений посылается родительскому окну тогда, когда список является текущим элементом управления. Первые три макроса будут обеспечивать вызов соответствующих функция только, если стиль элемента списка - LBS_NOTIFY.
Сообщение | Описание |
ON_LBN_DBLCLK | Обработчик двойного щелчка |
ON_LBN_SELCANCEL | Обработчик снятия выбора из списка |
ON_LBN_SELCHANGE | Обработчик смены выбора из списка |
ON_LBN_SETFOCUS | Обработчик получения фокуса списком |
ON_WM_CHARTOITEM | Обработчик сообщения для owner-draw списков, не имеющих строковых элементов при получении сообщения WM_CHAR |
ON_WM_VKEYTOITEM | Обработчик сообщения для списков со стилем LBS_WANTKEYBOARDINPUT при получении сообщения WM_KEYDOWN |
ON_LBN_ERRSPACE | Обработчик сообщения о нехватке памяти |
ON_LBN_KILLFOCUS | Обработчик при потере фокуса списком |
Стили списка показаны в таблице.
Стиль списка | Описание |
WS_CHILD | Всегда задается при создании кнопки |
WS_VISIBLE | Следует указывать, чтобы кнопка сразу отображалась, иначе для нее надо будет вызывать ShowWindow() |
WS_DISABLED | Кнопка изначально недоступна |
WS_GROUP | Объединение кнопок в группу, обязательно применяется для первого переключателя и после последнего в группе, переход от кнопки к кнопке при помощи клавиш перемещения курсора |
WS_TABSTOP | Переход от кнопки к кнопке по клавише TAB |
WS_HSCROLL | Добавление горизонтальной полосы прокрутки |
WS_VSCROLL | Добавление вертикальной полосы прокрутки |
LBS_EXTENDESEL | Можно выбирать несколько записей по клавишам Shift и мышке |
LBS_HASSTRINGS | Список содержит произвольные строки. Для получения строк можно использовать функцию GetText() |
LBS_MULTICOLUMN | Список отображается в несколько столбцов. Ширина столбцов задается функцией SetColumnWidth() |
LBS_MULTIPLESEL | Список множественного выбора |
LBS_NOINTEGRALHEIGHT | Размер элемента точно соответствует заданному при создании. Обычно размер выравнивается так, чтобы помещалось целое число строк. |
LBS_NOREDRAW | Изменения в списке не отображаются автоматически. Стиль может быть изменен посылкой сообщения WM_SETREDRAW |
LBS_NOTIFY | Родителбское окно будет получать извещения при некоторых событиях |
LBS_OWNERDRAWFIXED | Элементы списка имеют одинаковую ширину, но отрисовка возлагается на родительское окно |
LBS_OWNERDRAWVARIABLE | Элементы списка могут иметь разную высоту но отрисовка возлагается на родительское окно |
LBS_SORT | Строки списка сортируются по алфавиту |
LBS_STANDARD | Строки сортируются поалфавиту и родительское окно получает сообщение при одинарном и двойном щелчке на строке списка |
LBS_USETABSTOPS | При отображении строк можно использовать символы табуляции |
LBS_WANTKEYBOARDINPUT | Родительское окно получает сообщение WM_VKEYTOITEM или WM_CHARTOITEM, если пользователь нажимает клавишу при фокусу на списке |
LBS_DISABLENOSCROLL | Список показывает вертикальную полосу прокрутки всегда, даже если строк немного |
6.6.1 Некоторые функции для работы с элементом списка.
С каждой строкой списка можно связать не только текст, но и некоторое численное значение типа DWORD. Можно также связать с каждой строкой (элементом списка) не только численное значение, но и элемент любого типа, но тогда сохраняется указатель на этот элемент. Для этого применяются функции GetItemData и SetItemData, GetItemDataPtr и SetItemDataPtr.
Некоторые функции в случае неудачного выполнения возвращают код ошибки -LB_ERR.
Инициализация выполняется функцией Create:
BOOL CListBox::Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
int CListBox::GetCount( ) const; - возвращает число строк в списке
int CListBox::GetHorizontalExtent( ) const;- возвращает ширину списка в пикселах, в пределах которой он может прокручиваться
void CListBox::SetHorizontalExtent( int cxExtent ); - устанавливает ширину списка в пикселах, в пределах которой он может прокручиваться
int CListBox::GetTopIndex( ) const;- возвращает индекс первой отображаемой строки в списке, индекс меняется от 0
int CListBox::SetTopIndex( int nIndex ); - устанавливает первой отображаемой в списке строку с заданным индексом.
DWORD CListBox::GetItemData( int nIndex ) const; - получить численное значение, связанное с указанной строкой
void* CListBox::GetItemDataPtr( int nIndex ) const; - - получить численное значение, связанное с указанной строкой как указатель на void
int CListBox::SetItemData( int nIndex, DWORD dwItemData ); - связать с указанной строкой значение dwItemData
int CListBox::SetItemDataPtr( int nIndex, void* pData ); - связать с указанной строкой значение указателя на void
int CListBox::GetItemRect( int nIndex, LPRECT lpRect ) const; - в lpRect возвращается размер и координаты прямоугольника, ограничивающего запись с индексом nIndex
UINT CListBox::ItemFromPoint( CPoint pt, BOOL& bOutside ) const; - возвращает индекс ближайшего элемента списка по отношению к точке pt в клиентской зоне списка. bOutside устанавливается в TRUE, если точка лежит вне области списка.
int CListBox::SetItemHeight( int nIndex, UINT cyItemHeight ); - если список имеет тип LBS_OWNERDRAWVARIABLE, то эта функция устанавливает высоту строки в пикселах cyItemHeight с индексом nIndex.
int CListBox::GetItemHeight( int nIndex ) const; - функция, "обратная" предыдущей.
int CListBox::GetSel( int nIndex ) const; - возвращает не 0, если указанная строка с индексом nIndex выбрана.
int CListBox::GetText( int nIndex, LPTSTR lpszBuffer ) const; - пересылает в буфер lpszBuffer содержимое текста в строке с индексом nIndex.
void CListBox::GetText( int nIndex, CString& rString ) const; - функция выполняет те же действия, что и предыдущая, но текст пересылается в объек типа CString.
int CListBox::GetTextLen( int nIndex ) const; - возврвщает длину текста в строке с индексом nIndex.
void CListBox::SetColumnWidth( int cxWidth ); - устанавливает ширину столбцов для списка со стилем LBS_MULTICOLUMN.
void CListBox::SetTabStops( ); - задает позиции табуляции в списке с шагом 32.
BOOL CListBox::SetTabStops( const int& cxEachStop ); - изменяет позиции табуляции на новое значение cxEachStop.
BOOL CListBox::SetTabStops( int nTabStops, LPINT rgTabStops ); - позиции табуляции устанавливаются из массива значений rgTabStop, размер массива - nTabStop.
LCID CListBox::GetLocale( ) const; - для правильной обработки списка, например, сортировки, задается 32-битовое значение - параметр локализации. По умолчанию этот параметр задается операционной системой. Это значение может меняться средствами операционной системы ( установка языка ) или программно. Данная функция возвращает значение этого параметра.
LCID CListBox::SetLocale( LCID nNewLocale ); - функция устанавливает значение параметра локализации.
int CListBox::GetCurSel( ) const; - возвращается индекс выбранной строки.
int CListBox::SetCurSel( int nSelect ); - сделать строку с индексом nSelect выбранной.
int CListBox::SetSel( int nIndex, BOOL bSelect = TRUE ); - устанавливает строку с индексом nIndex в выбранное состояние, если bSelect равен TRUE, и в невыбранное, если bSelect равен FALSE.
int CListBox::GetCaretIndex( ) const; - возвращает индекс строки, на которой установлен фокус в списке.
int CListBox::SetCaretIndex( int nIndex, BOOL bScroll = TRUE ); - устанавливает фокус на строку списка с индексом nIndex. Если bScroll равен 0, то строка прокручивается до полной видимости.
int CListBox::GetSelCount( ) const; - возвращает, сколько выбранных строк в списке со стилем LBS_MULTIPLESEL.
int CListBox::GetSelItems( int nMaxItems, LPINT rgIndex ) const; - заполняет буфер rgIndex индексами строк, выбранных в списке. Размер буфера указан в первом параметре функции, уфер должен быть достаточно большой, чтобы вместить все индексы.
int CListBox::SelItemRange( BOOL bSelect, int nFirstItem, int nLastItem ); - позволяет установить диапазон строк от индекса nFirstItem до nLastItem в состояние выбранных, если bSelect равен TRUE, и в состояние невыбранности, если bSelect равен FALSE.
void CListBox::SetAnchorIndex( int nIndex ); - устанавливает точку отсчета ( первую или последнюю строку ) при выборе диапазона строк.
int CListBox::GetAnchorIndex( ) const; - возвращает ранее установленную точку отсчета.
int CListBox::AddString( LPCTSTR lpszItem ); - вставляет элемент списка с текстом lpszItem в конец списка, возвращает индекс этой строки в списке. Если список имеет стиль LBS_SORT, то список при этом сортируется.
int CListBox::DeleteString( UINT nIndex ); - удаляет элемент списка с индексом nIndex.
int CListBox::InsertString( int nIndex, LPCTSTR lpszItem ); - вставка элемента списка в заданную позицию. Если список сортируется, то возвращается новый индекс строки.
void CListBox::ResetContent( ); - очистить список.
int CListBox::Dir( UINT attr, LPCTSTR lpszWildCard ); - список заполняется содержимым текущего каталога файлов. Первый параметр задает атрибуты выбираемых файлов ( как принято в MS_DOS ), второй параметр - задает строку для выбора, например, *.*. Возвращается индекс последнего добавленного элемента.
int CListBox::FindString( int nStartAfter, LPCTSTR lpszItem ) const; - осуществляет поиск строки в списке, начиная с элемента с индексом nStartAfter. Поиск не зависит от регистра текста.
int CListBox::FindStringExact( int nIndexStart, LPCTSTR lpszFind ) const;- , то же, что и функция выше. Если список имеет стиль самоотображаемого, но без стиля LBS_HASSTRING, то выполняется поиск 32-битового значения, соответствующего lpszFind.
int CListBox::SelectString( int nStartAfter, LPCTSTR lpszItem ); - выполняет поиск строки в списке и делает ее выделенной. При необходимости выполняется прокрутка списка.
virtual int CListBox::VKeyToItem( UINT nKey, UINT nIndex ); - Эта функция вызывается, когда обрабатывается родительским окном сообщение WM_VKEYTOITEM, получаемое от списка, когда он получает сообщение WM_KEYDOWN. По стандартным действиям выполняется изменение фокуса, прокрутка строк и т.д. Если же список имеет стиль LBS_WANTKEYBOARDINPUT и хотя бы одну строку.
virtual int CListBox::CharToItem( UINT nKey, UINT nIndex ); - - Эта функция вызывается, когда обрабатывается родительским окном сообщение WM_CHARTOITEM, получаемое от списка, когда он получает сообщение WM_CHAR. Список должен быть самоотображаемым, при этом не иметь атрибут LBS_HASSTRINGS, и иметь хотя бы однин элемент.
virtual void CListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ); - Эта функция вызывается, когда надо перерисовывать список со стилем LBS_OWNERDRAWFIXED или LBS_OWNERDRAWVARIABLE. Внешний вид списка определяется структурой, передаваемой в качестве параметра.
Структура DRAWITEMSTRUCT имеет следующий вид:
typedef struct tagDRAWITEMSTRUCT {
UINT CtlType; //тип отображаемого элемента:
//ODT_BUTTON, ODT_COMBOBOX, ODT_LISTBOX или
//ODT_MENU. Для списка ODT_LISTBOX.
UINT CtlID; //идентификатор элемента
UINT itemID; //индекс записи в списке или меню
UINT itemAction; //как выполнять перерисовку:
// ODA_DRAWENTIRE - весь элемент перерисовать
// ODA_FOCUS - установлен, когда элемент
//потерял фокус, надо анализировать для строк
// itemState
// ODA_SELECT - установлен, когда сделан выбор
//в элементе, надо анализировать для строк
// itemState
UINT itemState; //определяет состояние строки после перерисовки:
//ODS_DISABLED - строка недоступна после
//перерисовки
//ODS_FOCUS - строка имеет фокус ввода
//ODS_SELECTED - строка выбрана
HWND hwndItem; //дескриптор окна элемента управления
HDC hDC; //контекст устройства вывода
RECT rcItem; //прямоугольник для перерисовки
DWORD itemData; //связанное с элементом списка значение
} DRAWITEMSTRUCT;
virtual void CListBox::MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct); - Эта функция вызывается, когда надо перерисовывать список со стилем LBS_OWNERDRAWFIXED или LBS_OWNERDRAWVARIABLE. Функция задает размеры для перерисовки. Размеры элемента списка определяются структурой, передаваемой в качестве параметра.
Структура MEASUREITEMSTRUCT имеет следующий вид:
typedef struct tagMEASUREITEMSTRUCT {
UINT CtlType; //тип элемента управления (см. в предыдущей
//функции)
UINT CtlID; //идентификатор элемента управления
UINT itemID; //индекс элемента в списке для списков с разной
//высотой элементов
UINT itemWidth; //ширина элемента в меню ( для списков не
//применяется
UINT itemHeight; //высота элемента в списке ( максимум равен 255)
DWORD itemData //то же самое, что и в предыдущей функции
} MEASUREITEMSTRUCT; //
virtual int CListBox::CompareItem( LPCOMPAREITEMSTRUCT lpCompareItemStruct); - Эта функция вызывается для сортировки списка, когда он имеет стиль отображаемого пользователем и сортируемого. Параметр указывает, как выполняется сравнение элементов списка.
Функция возвращает следующие значения:
-1, первый элемент меньше второго,
0, первый элемент равен второму
1, первый элемент больше второго
Структура COMPAREITEMSTRUCT имеет следующий вид:
typedef struct tagCOMPAREITEMSTRUCT {
UINT CtlType; // тип элемента управления (см. в предыдущей
//функции)
UINT CtlID; // идентификатор элемента управления
HWND hwndItem; // дескриптор окна элемента управления
UINT itemID1; //индекс в списке первого элемента
DWORD itemData1; //информациия, связанная с первым элементом
UINT itemID2; // индекс в списке второго элемента
DWORD itemData2; // информациия, связанная с первым элементом
} COMPAREITEMSTRUCT;
virtual void CListBox::DeleteItem( LPDELETEITEMSTRUCT lpDeleteItemStruct ); - функция вызывается, когда пользователь удаляет элемент для самоотображаемого списка. Параметр определяет информацию об удаляемой записи.
typedef struct tagDELETEITEMSTRUCT { /* ditms */
UINT CtlType; //// тип элемента управления (см. в предыдущей
//функции)
UINT CtlID; // идентификатор элемента управления
UINT itemID; // индекс в списке удаляемого элемента
HWND hwndItem; // дескриптор окна элемента управления
UINT itemData; // информациия, связанная с удаляемым элементом
} DELETEITEMSTRUCT;
6.7 Комбинированный список CComboBox.
Комбинированный список объединяет в себе свойства CEdit и CListBox. Часть списка может выводиться на экран постоянно (CBS_SIMPLE) или выпадает из окна (CBS_DROPDOWN или CBS_DROPDOWNLIST). Выбранная запись выводится в окне. Эту запись можно редактировать (CBS_SIMPLE или CBS_DROPDOWN), или же она недоступна для редактирования (CBS_DROPDOWNLIST). Уведомляющие сообщения, посылаемые родительскому окну, имеют вид:
Сообщение | Описание |
ON_CBN_CLOSEUP | Окно списка закрыто, для списка CBS_SIMPLE не посылается |
ON_CBN_DBLCLK | Двойной щелчок на элементе списка, для списка CBS_SIMPLE посылается. |
ON_CBN_DROPDOWN | Окно списка развернуто, для списка CBS_SIMPLE не посылается |
ON_CBN_EDITCHANGE | Пользователь изменил строку, сообщение не посылается для списка CBS_DROPDOWNLIST |
ON_CBN_EDITUPDATE | Пользователь изменил строку, но текст еще не выведен на экран, сообщение не посылается для списка CBS_DROPDOWNLIST |
ON_CBN_ERRSPACE | Не хватает памяти для выполнения запроса |
ON_CBN_SELENDCANCEL | Выбор пользователя игнорируется |
ON_CBN_SELENDOK | Пользователь выбрал строку списка |
ON_CBN_SELCHANGE | Выбор в списке изменился |
ON_CBN_SETFOCUS | Элемент получил фокус ввода |
Стили комбинированного списка показаны в таблице.