Модель программирования Component Object Model. Разработка COM-сервера, страница 37

Элемент

Идентификатор

Диалог

IDD_PROPDLG

Ползунок Общая в группе Освещенность

IDC_AMBIENT

Ползунок Рассеянная в группе Освещенность

IDC_DIFFUSE

Ползунок Отраженная в группе Освещенность

IDC_SPECULAR

Text справа от Общая в группе Освещенность

IDC_AMB_TEXT

Text справа от Рассеянная в группе Освещенность

IDC_DIFFUSE_TEXT

Text справа от Отраженная в группе Освещенность

IDC_SPECULAR_TEXT

Ползунок Общая в группе Материал

IDC_AMBMAT

Ползунок Рассеянная в группе Материал

IDC_DIFFMAT

Ползунок Отраженная в группе Материал

IDC_SPECMAT

Text справа от Общая в группе Материал

IDC_AMBMAT_TEXT

Text справа от Рассеянная в группе Материал

IDC_DIFFMAT_TEXT

Text справа от Отраженная в группе Материал

IDC_SPECMAT_TEXT

Ползунок Блестскость

IDC_SHINE

Ползунок Эмиссия

IDC_EMISSION

Text справа от Блестскость

IDC_SHINE_TEXT

Text справа от Эмиссия

IDC_EMISSION_TEXT

Ползунок X

IDC_XPOS

Ползунок Y

IDC_YPOS

Ползунок Z

IDC_ZPOS

Text справа от X

IDC_XPOS_TEXT

Text справа от Y

IDC_YPOS_TEXT

Text справа от Z

IDC_ZPOS_TEXT

Выпадающий список Заполнение

IDC_FILLMODE

Кнопка Quads

IDC_QUADS

Кнопка Выбор файла

IDC_FILENAME

Взаимодействие классов

Класс CGraphProp должен обеспечить реакцию на изменение регулировок, а класс COpenGL должен учесть новые установки и перерисовать изображение. Общение классов, как мы уже отметили, происходит по законам COM, то есть с помощью указателя на интерфейс. Здесь нам на помощь приходит шаблон классов CComQIPtr. Литеры «QI» в имени шаблона означают QueryInterface, что обещает нам автоматизацию в реализации запроса указателя. В этом классе переопределены операции выбора (->), взятия адреса (&), разадресации (*) и некоторые другие, которые упрощают использование указателей на различные интерфейсы. При создании объекта класса CComQIPtr, например:

CComQIPtr<IOpenGL, &IID_IOpenGL> p(m_ppUnk[i]);

он настраивается на нужный нам интерфейс, и далее мы работаем с удобствами, не думая о функциях QueryInterface, AddRef и Release. При выходе из области действия объекта p освобождение интерфейса произойдет автоматически. Введите в состав класса CGraphProp новые protected -переменные:

protected:

LONG m_Pos[11]; // Массив позиций ползунков

BYTE m_bQuad;   // Режим заполнения полигонов

Массив m_Pos будет хранить позиции движков для управления параметрами освещения сцены. Добавьте в конструктор класса CGraphProp строку инициализации.

ZeroMemory (m_Pos, sizeof(m_Pos));   // Обнуляем весь массив

Способом, который вы уже неоднократно применяли, введите в класс CGraphProp два обработчика Windows-сообщений WM_INITDIALOG и WM_HSCROLL. Затем перейдите к созданной мастером заготовке метода OnInitDialog, которую найдете в cpp-файле, и введите изменения, которые позволят при открытии страницы свойств привести регуляторы в соответствие со значениями переменных в классе COpenGL. Вы помните, что значения регулировок используются именно там. Там же они и хранятся.

Мы уже отметили, что общение двух классов одного и того же компонента происходит по законам COM, то есть с помощью указателя на интерфейс IOpenGL. В связи с этим нам придется довольно часто получать указатель на него. Существуют разные способы получения умного (smart) указателя: простые, но ненадежные и более сложные, но обеспечивающие большую степень надежности. Вот образец простого способа:

CComQIPtr<IOpenGL, &IID_IOpenGL> p(m_ppUnk[0]);

p->GetFillMode(&mode);

Вот образец более сложного способа:

CComQIPtr<IOpenGL, &IID_IOpenGL> p(m_ppUnk[0]);

if (!p)

return E_UNEXPECTED;

p->GetFillMode(&mode);