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

4.  Найдите строку с идентификатором уведомляющего сообщения CBN_SELCHANGE и в ячейке справа выберите действие <Add> для того, чтобы там появилось имя функции обработки OnSelchangeFillmode.

5.  Введите следующие коды в заготовку функции OnCbnSelchangeFillmode.

LRESULT CGraphProp:: OnCbnSelchangeFillmode(WORD /*wNotifyCode*/,

WORD /*wID*/, HWND hWndCtl, BOOL& bHandled)

{

for (UINT i = 0; i < m_nObjects; i++)  // Цикл пробега по всем объектам

{

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

//==== Выясняем индекс строки, выбранной в окне списка

DWORD sel = (DWORD)SendMessage (hWndCtl, CB_GETCURSEL,0,0);

//==== Преобразуем индекс в режим отображения полигонов

sel = sel==0 ? GL_POINT  : sel==1 ? GL_LINE : GL_FILL;

if FAILED (p->SetFillMode(sel)) // Устанавливаем режим в классе COpenGL

{

ShowError();

return 0;

}

}

bHandled = TRUE;

return 0;

}

Обратите внимание на то, что нам пришлось убирать два комментария, чтобы сделать видимым параметры hWndCtl и bHandled. Для того, чтобы управление возымело действие, введите следующие строки в тело метода SetFillMode, который является реализацией одноименного метода интерфейса IOpenGL.

m_FillMode = nMode; // Изменяем режим заполнения полигонов

DrawScene();  // Заново создаем изображение

FireViewChange(); // Просим перерисовать

return S_OK;

Реакция на нажатия кнопок

При создании отклика на выбор режима изображения полигонов следует учесть попеременное изменение текста и состояния кнопки. Произведите двойной щелчок на кнопке IDC_QUADS и введите следующие коды в заготовку функции обработки.

LRESULT CGraphProp::OnBnClickedQuads (WORD /*wNotifyCode*/,

WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)

{

for (UINT i = 0; i < m_nObjects; i++)

{

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

m_bQuad = !m_bQuad;  // Переключаем режим

SetDlgItemText (IDC_QUADS, m_bQuad ? "Quads" : "Strip");// Корректируем текст  кнопки

if FAILED (p->SetQuad (m_bQuad))

{

ShowError();

return 0;

}

}

bHandled = TRUE;

return 0;

}

Введите код в тело метода SetQuad, который является реализацией одноименного метода интерфейса IOpenGL.

m_bQuad = bQuad == TRUE;

DrawScene();

FireViewChange();

return S_OK;

Аналогичные, но более простые действия следует произвести в реакции на нажатие кнопки выбора файла. Введите функцию для обработки этого события и вставьте в нее следующий код:

LRESULT CGraphProp::OnClickedFilename(WORD /*wNotifyCode*/,

WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)

{

for (UINT i = 0; i < m_nObjects; i++)

{

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

if FAILED (p->ReadData())

{

ShowError();

return 0;

}

}

bHandled = TRUE;

return 0;

}

Постройте сервер и проверьте работу страницы свойств. Попробуйте прочесть другой файл, например, тот, который был создан приложением, созданным в рамках MFC. Так как мы не изменяли формат данных, записываемых в файл, то все старые файлы должны читаться. Добейтесь того, чтобы все работало.

Поддерживаемые интерфейсы

Элемент управления ActiveX представляет собой объект COM и, поэтому, должен, по крайней мере, поддерживать интерфейс IUnknown. Однако для того, чтобы выполнять какие-нибудь полезные действия, элемент управления ActiveX должен поддерживать и другие интерфейсы. Для выполнения многих из этих действий могут быть использованы стандартные интерфейсы. В таблице приведен список этих интерфейсов.