Поделиться через


Образец CTRLTEST: реализация пользовательских элементов управления

Обновлен: Ноябрь 2007

В образце CTRLTEST показано несколько методов для реализации и использования пользовательских элементов управления.

  • Реализация CParsedEdit — специального элемента управления "Поле ввода", функции которого наследуются из класса управления библиотеки — и трех методов применения пользовательских элементов управления.

  • Использование элемента управления "Счетчик". Счетчик содержит маленькие кнопки со стрелками вверх и вниз, которые предназначены для увеличения и уменьшения значения.

  • Реализация меню Custom в виде кнопок с рисунками с помощью класса CBitmapButton.

  • Рисование меню и списков средствами владельца (родительского окна). Соответствующие классы управления, производные от классов CMenu и CListBox, предоставляют такую возможность объектно-ориентированным способом.

  • Использование файлов ресурсов, которые не поддерживаются редакторами ресурсов в Microsoft Visual C++. Здесь показаны преимущества и недостатки использования RC2-файла в диалоговом окне, где расположен пользовательский элемент управления со стилями, определенными в константах файла заголовка.

Все примеры в образце CTRLTEST запускаются с помощью команд меню.

zz9355ha.alert_security(ru-ru,VS.90).gifПримечание о безопасности.

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

Чтобы получить образцы и инструкции по их установке, выполните следующие действия.

  • В меню Справка среды Visual Studio выберите пункт Примеры.

    Дополнительные сведения см. в разделе Поиск файлов примеров.

  • Самая последняя версия и полный список образцов доступны в Интернете на странице образцов Visual Studio 2008.

  • Кроме того, образцы находятся на жестком диске компьютера. По умолчанию образцы кода и файл Readme копируются в папку, находящуюся в папке \Program Files\Visual Studio 9.0\Samples\. Все образцы кода для экспресс-выпусков Visual Studio находятся в Интернете.

Построение и запуск образца

Построение и запуск образца CTRLTEST

  1. Откройте решение Ctrltest.sln.

  2. В меню Построение выберите команду Построить.

  3. В меню Отладка выберите пункт Запуск без отладки.

Пример реализации и использования пользовательских элементов управления

Пользовательский элемент управления можно реализовать путем наследования класса 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

zz9355ha.alert_note(ru-ru,VS.90).gifПримечание.

Некоторые образцы, включая данный, не модифицировались с учетом изменений в мастерах, библиотеках и компиляторе Visual C++, однако по-прежнему демонстрируют выполнение требуемой задачи.

См. также

Другие ресурсы

Примеры MFC