Шаг 119 - Добавление страницы свойств

Страницы свойств реализуются как отдельные COM объекты, это позволяют страницам свойств быть общедоступными, если необходимо. Чтобы добавить страницу свойств к вашему элементу управления Вы можете использовать ATL Object Wizard.

Запустите ATL Object Wizard и выберите Controls с левой стороны из групп. Выберите страницу свойств (Property Page) и нажмите Next. Выберите страницу свойств (Property Page) и нажмите Next. Вы увидите диалоговое окно, которое позволяет Вам ввести имя нового объекта. Назовем объект PolyProp и введем его имя в окно редактирования Short Name.

119_1.gif (6188 b)

Обратите внимание, что окно Interface недоступно. Это потому что страница свойств не нуждается в заказном интерфейсе.

Нажмите на вкладку Strings, чтобы установить заголовок страницы свойств. Заголовок страницы свойств - это строка, которая появляется на вкладке. Напечатайте $Polygon как заголовок. Doc String - это описание, которое рамка свойства помещает в строку состояния или совет в панели инструментов. Обратите внимание, что стандартная страница свойств в настоящее время не использует эту строку, но Вы можете устанавливать ее в любом случае. Вы не собираетесь генерировать Helpfile в настоящее время, сотрите этот текстовый блок. Нажмите OK и объект страницы свойств будет создан.

119_2.gif (3736 b)

Появятся следующие три файла:

Сделаны следующие изменения кода:

  1. Новая страница свойств добавлена в объектную карту в Polygon.cpp.
  2. Класс PolyProp добавлен в файл Polygon.idl.
  3. Добавлен новый файл сценария регистрации в реестре PolyProp.rgs в ресурсах проекта.
  4. Шаблон диалогового окна добавлен к ресурсу проекта для страницы свойств.
  5. Строки свойств, которые Вы определили, добавлены в таблицу строк ресурсов.

Теперь добавьте поля, которые Вы хотите видеть на странице свойств. Обратите внимание, что в Polygon.rc диалог пуст (кроме метки, которая напоминает, что нужно вставить свои управляющие элементы). Удалите эту метку и добавьте метку, которая содержит текст "Sides:". Рядом с меткой добавьте окно редактирования с идентификатором IDC_SIDES.

119_3.gif (3459 b)

Включите Polygon.h в начале файла PolyProp.h:

#include "Polygon.h"  // определение IPolyCtl

Теперь дайте возможность классу CPolyProp установить число сторон в вашем объекте, когда нажимается кнопка Apply. Измените функцию Apply в PolyProp.h следующим образом.

STDMETHOD(Apply)(void)
{
	USES_CONVERSION;
	ATLTRACE(_T("CPolyProp::Apply\n"));
	for (UINT i = 0; i < m_nObjects; i++)
	{
		CComQIPtr<IPolyCtl, &IID_IPolyCtl> pPoly(m_ppUnk[i]);
		short nSides = (short)GetDlgItemInt(IDC_SIDES);
		if FAILED(pPoly->put_Sides(nSides))
		{
			CComPtr<IErrorInfo> pError;
			CComBSTR strError;
			GetErrorInfo(0, &pError);
			pError->GetDescription(&strError);
			MessageBox(OLE2T(strError), _T("Error"), MB_ICONEXCLAMATION);
			return E_FAIL;
		}
	}
	m_bDirty = FALSE;
	return S_OK;
}

Страница свойств может иметь несколько клиентов одновременно, поэтому функция Apply вызывает put_Sides каждого клиента со значением полученным из окна редактирования. Вы используете CComQIPtr класс, который выполняет QueryInterface для каждого объекта, чтобы получить интерфейс IPolyCtl из IUnknown (сохраненный в массиве m_ppUnk).

Код теперь проверяет, что установка свойства была произведена. Если установка свойств происходила не верно, то код отображает подробности в виде ошибки, отображая окно сообщения из интерфейса IErrorInfo. Обычно, контейнер запрашивает объект интерфейса ISupportErrorInfo и вызывает InterfaceSupportsErrorInfo, чтобы определить, поддерживает ли объект данные об ошибках. Но так как это наш элемент управления, то можно пропустить эту проверку.

CComPtr помогает автоматически обрабатывать подсчет ссылки, в результате можно не вызвать Release. CComBSTR помогает с обработкой BSTR, в результате не надо выполнять обращение SysFreeString. Использование строковых преобразований добавляется макрокомандой USES_CONVERSION в начале функции.

Мы должны создать флажок для страницы свойств, чтобы указать, что к кнопке Apply нужно разрешить доступ. Доступ нужно разрешать когда пользователь изменяет значение в окне редактирования Side. Щелкните правой кнопкой мыши на странице свойств класса в ClassView, и затем выберите Add Windows Message Handler... из контекстного меню. Выберите IDC_SIDES из списка и затем добавьте сообщение EN_CHANGE.

Теперь добавьте следующий код в Polyprop.h к функции OnChangeSides. (удалите весь код, который там поместил мастер):

LRESULT OnChangeSides(WORD wNotify, WORD wID, HWND hWnd, BOOL& bHandled)
{
	SetDirty(TRUE);
	return 0;
}

Функция OnChangeSides будет вызываться когда сообщение WM_COMMAND послано с уведомлением EN_CHANGE для элемента управления IDC_SIDES. OnChangeSides затем вызывает SetDirty и передает TRUE, чтобы указать, что страница свойств теперь изменена и кнопку Apply можно разрешить. Давайте добавим страницу свойств к вашему элементу управления. ATL Object Wizard не делает это автоматически с тех пор как в вашем проекте появляется несколько элементов управления.

Откройте PolyCtl.h и добавьте эту строку в карту свойств:

PROP_ENTRY("Sides", 1, CLSID_PolyProp)

Карта свойств элемента управления теперь выглядит следующим образом:

BEGIN_PROP_MAP(CPolyCtl)
	PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
	PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
	PROP_ENTRY("FillColor", DISPID_FILLCOLOR, CLSID_StockColorPage)
	PROP_ENTRY("Sides", 1, CLSID_PolyProp)
	// Example entries
	// PROP_ENTRY("Property Description", dispid, clsid)
	// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

Вы могли бы добавить макрокоманду PROP_PAGE с CLSID вашей страницы свойств, но если Вы используете макрокоманду PROP_ENTRY, то значение свойства Sides будет сохранено когда элемент управления сохранится. Три параметра для макрокоманды - описание свойства, DISPID свойства, CLSID страницы свойств. Это полезно, если Вы загружаете элемент управления в VB и устанавливаете число Sides во время разработки. Так как число Sides было сохранено, то когда Вы перезагружаете проект число Sides автоматически восстанавливается.

Соберите элемент управления и вставьте его в ActiveX Control Test Container. Затем в меню Edit нажимаем PolyCtl Class Object. На странице свойств выберите вкладку Polygon.

119_4.gif (3636 b)

Кнопка Apply первоначально заблокирована. Начните печатать значение в окне редактирования Side и кнопка Apply станет доступной. После того, как Вы закончили вводить значение нажмите кнопку Apply. Элемент управления будет изменен и кнопка Apply снова заблокируется. Пробуйте ввести недопустимое значение и Вы увидите окно сообщения содержащее описание ошибки из функции put_Sides.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 16.09.2002