Образец CTRLTEST: реализация пользовательских элементов управления
Обновлен: Ноябрь 2007
В образце CTRLTEST показано несколько методов для реализации и использования пользовательских элементов управления.
Реализация CParsedEdit — специального элемента управления "Поле ввода", функции которого наследуются из класса управления библиотеки — и трех методов применения пользовательских элементов управления.
Использование элемента управления "Счетчик". Счетчик содержит маленькие кнопки со стрелками вверх и вниз, которые предназначены для увеличения и уменьшения значения.
Реализация меню Custom в виде кнопок с рисунками с помощью класса CBitmapButton.
Рисование меню и списков средствами владельца (родительского окна). Соответствующие классы управления, производные от классов CMenu и CListBox, предоставляют такую возможность объектно-ориентированным способом.
Использование файлов ресурсов, которые не поддерживаются редакторами ресурсов в Microsoft Visual C++. Здесь показаны преимущества и недостатки использования RC2-файла в диалоговом окне, где расположен пользовательский элемент управления со стилями, определенными в константах файла заголовка.
Все примеры в образце CTRLTEST запускаются с помощью команд меню.
Примечание о безопасности. |
---|
Этот образец кода служит для демонстрации основных принципов и не предназначен для использования в приложениях или на веб-узлах, поскольку не может считаться примером наиболее безопасного кода. Корпорация Майкрософт не несет ответственности за случайные или косвенные убытки в случае использования образца кода не по назначению. |
Чтобы получить образцы и инструкции по их установке, выполните следующие действия.
В меню Справка среды Visual Studio выберите пункт Примеры.
Дополнительные сведения см. в разделе Поиск файлов примеров.
Самая последняя версия и полный список образцов доступны в Интернете на странице образцов Visual Studio 2008.
Кроме того, образцы находятся на жестком диске компьютера. По умолчанию образцы кода и файл Readme копируются в папку, находящуюся в папке \Program Files\Visual Studio 9.0\Samples\. Все образцы кода для экспресс-выпусков Visual Studio находятся в Интернете.
Построение и запуск образца
Построение и запуск образца CTRLTEST
Откройте решение Ctrltest.sln.
В меню Построение выберите команду Построить.
В меню Отладка выберите пункт Запуск без отладки.
Пример реализации и использования пользовательских элементов управления
Пользовательский элемент управления можно реализовать путем наследования класса CWnd, но будет значительно проще воспользоваться функциями стандартных элементов управления Windows, создав класс, производный от класса управления в библиотеке. В образце CTRLTEST такой подход применяется для реализации специально элемента управления "Поле ввода" — CParsedEdit. Этот элемент управления "Поле ввода" принимает только заданные наборы вводимых символов: числовые, буквенные и символы, не выполняющие функции управляющих. Класс CParsedEdit является производным от CEdit. Он содержит обработчик сообщений OnChar для фильтрации символов.
В реализации команд из меню Simple показаны три метода применения пользовательского элемента управления. Эти методы различаются в зависимости от того, как приложение связывает экземпляры элемента управления в диалоговом окне с классом CParsedEdit. Каждая из команд меню Simple выводит диалоговое окно с четырьмя экземплярами элемента управления CParsedEdit. Данные, вводимые в диалоговое окно, отправляются в порт отладки через выход TRACE. В меню Simple находятся три команды.
Test C++ Derived Class
Элементы управления CParsedEdit входят в класс диалогового окна в качестве элементов данных. Эти элементы управления создаются явным образом в функции OnInitDialog диалогового окна путем вызова метода CParsedEdit::CreateSet. См. файл Dertest.cpp.
Test WNDCLASS Registered
Элементы управления CParsedEdit размещаются в ресурсе шаблона диалогового окна (IDD_WNDCLASS_EDIT) в виде пользовательских элементов управления, для которых WNDCLASS имеет имя "paredit". Рекомендуется изучить свойства этих пользовательских элементов управления с помощью редактора диалоговых окон Visual C++.
Пустая подпись. Это исходное значение, отображаемое в элементе управления CParsedEdit.
Class:paredit. Это имя класса WNDCLASS, зарегистрированное методом CParsedEdit::RegisterControlClass в файле PAREDIT2.CPP перед вызовом диалогового окна.
Visible:checked. Элемент управления является видимым.
Tabstop:checked. Пользователь может перейти к этому элементу управления, нажимая клавишу TAB.
Style:0x5081002, 0x5081001, 0x5081003, 0x5081ffff для четырех элементов управления, выполняющих синтаксический анализ вводимых данных. Шифр 0x500000 обозначает стили WS_CHILD и WS_VISIBLE, а 0x1000 — стиль WS_TABSTOP. Все пользовательские элементы управления имеют стиль WS_CHILD. Стили WS_VISIBLE и WS_TABSTOP автоматически устанавливаются редактором диалоговых окон, когда отмечаются стили Visible и Tabstop. Шифр 0x80000 обозначает стиль WS_BORDER. Поскольку на странице свойств для пользовательского элемента управления в редакторе диалоговых окон доступны все стили окон, в том числе WS_BORDER, необходимо проверить значение константы в файле \Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\WINUSER.H. Стили, обозначенные константами 0x0001, 0x0002, 0x0004 и 0x0ffff, определяются в файле PAREDIT.H соответственно именами PES_NUMBERS, PES_LETTERS, PER_OTHERCHARS и PES_ALL.
Шестнадцатеричные обозначения стилей на странице свойств для пользовательского элемента управления не являются самодокументирующими. Если важно использовать символьные имена стилей, такие как PES_NUMBERS и PES_LETTERS, можно вручную изменить отдельный файл ресурсов, например RES\Ctrltest.rc2, который включается компилятором ресурсов на этапе компиляции, но не считывается средой Visual C++ на этапе редактирования. Обсуждение преимуществ и недостатков изменения диалогового окна пользовательского элемента управления вручную в RC2-файле см. в разделе Использование файлов ресурсов, которые не поддерживаются редакторами ресурсов Visual C++.
Test Dynamic Subclassed
Элементы управления располагаются в ресурсе шаблона диалогового окна (IDD_SUB_EDIT в файле Ctrltest.rc) в виде стандартных элементов управления "Поле ввода". Эти элементы управления объявляются в виде элементов данных CParsedEdit в классе диалогового окна. Функция OnInitDialog диалогового окна вызывает метод CParsedEdit::SubClassEdit, который в свою очередь вызывает метод CWnd::SubclassDlgItem, чтобы сопоставить каждый экземпляр элемента управления "Поле ввода" с классом CParsedEdit. См. файл Paredit.cpp.
Пример элемента управления "Счетчик"
В образец CTRLTEST входит реализация элемента управления "Счетчик". Счетчик содержит маленькие кнопки со стрелками вверх и вниз, которые предназначены для увеличения и уменьшения значения.
Команда Spin Control вызывает диалоговое окно, в котором находятся четыре элемента управления CParsedEdit, каждый из которых сопоставлен с элементом управления "Счетчик". Данные, вводимые в элементы управления CParsedEdit в этом диалоговом окне, фильтруются таким образом, чтобы принимать только неотрицательные целые числа. Пользователь может вводить числовые данные, набирая значение с клавиатуры в элементе управления CParsedEdit или используя сопоставленный элемент управления "Счетчик".
Пример кнопки с растровым изображением
Реализация следующих команд меню Custom демонстрирует способы использования класса CBitmapButton:
Bitmap Button 1. Конструктор диалогового окна явно загружает ресурсы рисунка для каждого из трех состояний кнопки (отпущена, нажата, имеет фокус), вызывая метод CBitmapButton::LoadBitmaps.
Bitmap Button 2. Функция OnInitDialog диалогового окна вызывает метод CBitmapButton::Autoload для загрузки ресурсов рисунка, используя следующее правило создания имени. Текст окна элемента управления служит в качестве имени базового ресурса, а затем добавляются буквы U, D и F, чтобы получить имена ресурсов для каждого из трех изображений, соответствующих состояниям "отжата", "нажата" и "имеет фокус". Например, для кнопки OK три ресурса изображений имеют имена OKU, OKD и OKF.
Bitmap Button 3. Диалоговое окно является расширением второго диалогового окна, описанного выше, и использует четвертое возможное состояние кнопки (отключена). Для использования этого диалогового окна нажимайте кнопку со стрелкой влево или вправо, пока не будет отображаться число 1 (наименьшее) или 10 (наибольшее). Когда достигается предельное значение, кнопка отключается, и отображается четвертый вариант рисунка. В соответствии с правилом создания имен ресурс рисунка для отключенного состояния имеет суффикс X, что показано в именах ресурсов PREVX и NEXTX.
Пример рисования владельцем (меню и список)
Для различных элементов управления и меню Windows доступна функция рисования владельцем, которая позволяет родительскому окну (владельцу) рисовать необходимые элементы в клиентской области элемента управления вместо использования стандартных функций элемента управления. Соответствующие классы управления и класс CMenu поддерживают эту функцию более удобны, объектно-ориентированным способом. Класс управления или класс меню выполняет задачи рисования. Это называется саморисованием.
В образце CTRLTEST показан общий принцип рисования владельцем в реализации следующих команд из меню Custom.
Custom Menu. Этот пункт меню вызывает всплывающее меню CColorMenu, производное от класса CMenu. Каждый элемент вложенного меню отображает один из восьми цветов с помощью функции саморисования. Сообщение подтверждает цвет, выбранный из вложенного меню.
Custom List Box. Этот пункт меню вызывает диалоговое окно, которое отображает элемент CColorListBox, производный от класса CListBox. Список содержит восемь пунктов, каждый из которых нарисован одним из восьми цветов с применением функции саморисования. Выход TRACE подтверждает пункт, выбранный из списка.
Пример использования файлов ресурсов, которые не поддерживаются редакторами ресурсов в Visual C++.
Файл ресурсов CTRLTEST\RES\Ctrltest.rc2 является примером файла, который не поддерживается редакторами ресурсов Visual C++ в удобном для чтения формате. Если открыть файл Ctrltest.rc2 в Visual C++ и сохранить его, будут потеряны полезные данные в удобочитаемом формате, хотя компилятор ресурсов сохранит возможность компиляции RC2-файла и получит из него эквивалентный двоичный RES-файл. Поэтому файл RES\Ctrltest.rc2 добавлен конструкцией #include в файле Ctrltest.rc в директиве времени компиляции, указанной с помощью команды Resource File Set Includes.
Далее описаны три категории немашинных (предназначенных для человека) данных, которые не поддерживаются редакторами ресурсов Visual C++. Две категории из трех показаны в файле Ctrltest.rc2.
Символьные имена стилей пользовательских элементов управления. Например, стиль "msctls_updown32" определен для элемента управления "Счетчик". Visual C++ может интерпретировать это символьное имя при чтении RC2-файла, однако во время обратной записи это имя будет представлено шестнадцатеричным значением.
Стандартные символьные имена стилей Windows WS_ и стилей, используемых в элементах управления, производных от стандартного класса управления Windows. Например, имя ES_AUTOHSCROLL определено для элемента управления "Счетчик" в диалоговом окне IDD_SPIN_EDIT. Visual C++ может интерпретировать эти символьные имена при чтении RC2-файла, однако во время обратной записи это имя будет представлено шестнадцатеричным значением.
Арифметические символы в RC-файле. Выражения, подобные "IDC_EDIT1+2" для определения элементов управления в диалоговом окне IDD_SPIN_EDIT будут записываться Visual C++ в RC2-файл в виде одного шестнадцатеричного значения.
В образце CTRLTEST показаны преимущества и недостатки использования RC2-файла в таком диалоговом окне, где расположен пользовательский элемент управления со стилями, определенными в константах файла заголовка. В диалоговых окнах IDD_WNDCLASS_EDIT и IDD_SPIN_EDIT находятся пользовательские элементы управления со стилями, заданными в символьной форме, однако IDD_WNDCLASS задается в RC-файле, доступном для редактирования в редакторе диалоговых окон Visual C++, а IDD_SPIN_EDIT задается в RC2-файле, который можно редактировать только вручную.
Различия между использованием RC-файла и RC2-файла можно кратко представить следующим образом.
Для диалогового окна IDD_WNDCLASS_EDIT сценарий ресурсов определяется в файле Ctrltest.rc. Для диалогового окна IDD_SPIN_EDIT сценарий ресурсов определяется в файле RES\Ctrltest.rc2. Для диалогового окна IDD_WNDCLASS_EDIT пользовательский элемент управления WNDCLASS имеет тип "paredit", константы стиля определяются в файле PAREDIT.H, а примером константы стиля служит PES_NUMBER. Окно IDD_WNDCLASS_EDIT можно редактировать в Visual C++, однако в нем нельзя использовать стили #define. Окно IDD_SPIN_EDIT нельзя редактировать в Visual C++, но в нем можно использовать стили #define.
С одной стороны, использование RC2-файла позволяет применять для пользовательского элемента управления удобочитаемые символьные стили, определенные в файле заголовка, но с другой стороны, RC2-файл нельзя редактировать в редакторе диалоговых окон Visual C++. Формировать макет диалогового окна в Visual C++ проще, чем вручную писать сценарий ресурсов, а кроме того, написание сценария ресурсов сильнее подвержено ошибкам. Однако стили, отображаемые на странице свойств пользовательского элемента управления в редакторе диалоговых окон Visual C++, не являются самодокументирующими.
Ключевые слова
В этом образце показаны следующие ключевые слова:
AfxGetInstanceHandle; AfxMessageBox; AfxThrowResourceException; CBitmapButton::AutoLoad; CDC::FillRect; CDC::FrameRect; CDialog::DoModal; CDialog::EndDialog; CDialog::OnInitDialog; CDialog::OnOK; CDialog::OnSetFont; CEdit::Create; CEdit::SetSel; CFrameWnd::Create; CListBox::AddString; CListBox::CompareItem; CListBox::DrawItem; CListBox::GetItemData; CListBox::MeasureItem; CMenu::AppendMenu; CMenu::CreateMenu; CMenu::Detach; CMenu::DrawItem; CMenu::EnableMenuItem; CMenu::FromHandle; CMenu::GetMenuString; CMenu::MeasureItem; CRect::Width; CStatic::Create; CString::Format; CString::LoadString; CWinApp::InitInstance; CWnd::Attach; CWnd::EnableWindow; CWnd::FromHandle; CWnd::GetDlgCtrlID; CWnd::GetDlgItem; CWnd::GetDlgItemInt; CWnd::GetMenu; CWnd::GetParent; CWnd::GetWindowRect; CWnd::GetWindowText; CWnd::IsWindowEnabled; CWnd::MessageBox; CWnd::OnChar; CWnd::OnCommand; CWnd::OnVScroll; CWnd::PostNcDestroy; CWnd::SendMessage; CWnd::SetDlgItemInt; CWnd::SetFocus; CWnd::SetFont; CWnd::SetWindowPos; CWnd::ShowWindow; CWnd::SubclassDlgItem; CallWindowProc; GetBValue; GetClassInfo; GetGValue; GetRValue; GetSystemMetrics; HIWORD; IsCharAlpha; IsCharAlphaNumeric; LOWORD; MAKEINTRESOURCE; MAKELONG; MessageBeep; ModifyMenu; RGB; RegisterClass; SetWindowLong
Примечание. |
---|
Некоторые образцы, включая данный, не модифицировались с учетом изменений в мастерах, библиотеках и компиляторе Visual C++, однако по-прежнему демонстрируют выполнение требуемой задачи. |