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

На этом этапе важно решить, какие данные (свойства) и методы класса будут экспонироваться COM-объектом, а какие останутся в качестве служебных (для внутреннего пользования). Те методы и свойства, которые будут экспонированы, должны быть соответствующим образом отражены в IDL-файле. Те, которые нужны только нам, останутся внутри сервера. Для примера введем в число экспонируемых методов функцию GetLightParams, которая определяет действующие параметры освещения.

1.  Поставьте фокус на строку с именем интерфейса IOpenGL в окне ClassView и вызовите контекстное меню;

2.  Выберите команду Add Method, введите в поле Method Name имя метода GetLightParams, в поле Parameter type выберите тип параметра этой функции: LONG*, в поле Parameter name введите имя: pPos, уточните атрибут параметра [out] (возвращаемый) и нажмите кнопку Add.

3.  Нажмите кнопку Finish.

Проанализируйте изменения, которые появились в IDL-файле, в файле OpenGL.h и в файле OpenGL.cpp. В первом из перечисленных файлов появилось новое, уточненное описание метода интерфейса:

interface IOpenGL : IDispatch

{

[propput, id(DISPID_FILLCOLOR)]

HRESULT FillColor([in]OLE_COLOR clr);

[propget, id(DISPID_FILLCOLOR)]

HRESULT FillColor([out, retval]OLE_COLOR* pclr);

[id(1), helpstring("method GetLightParams")]

HRESULT GetLightParams([out] LONG* pPos);

};

в файле заголовков появилась строка декларации метода ко-класса, который реализует функциональность интерфейса:

STDMETHOD(GetLightParams)(LONG* pPos);

и, наконец, в файле реализации класса появилась стартовая заготовка тела метода:

STDMETHODIMP COpenGL::GetLightParams(LONG* pPos)

{

// TODO: Add your implementation code here

return S_OK;

}

Повторите описанные действия и введите в интерфейс еще один метод SetLightParam, который изменяет один из параметров освещения сцены OpenGL. При задании параметров этого метода будьте внимательны. Добейтесь того, чтобы метод получил следующий прототип:

[id(2), helpstring("method SetLightParam")]

HRESULT SetLightParam([in] SHORT lp, [in]LONG nPos);

Для практики введите в состав интерфейса еще несколько методов. При задании имен и параметров  ориентируйтесь на следующий перечень строк, которые должны образоваться в IDL-файле в результате ваших действий. Это не так просто сделать: наиболее часто при задании параметров вы забываете нажать кнопку Add. Результ: у методов отсутствуют параметры.

[id(3), helpstring("method GetFillMode")]

HRESULT GetFillMode([out] ULONG* pMode);

[id(4), helpstring("method SetFillMode")]

HRESULT SetFillMode([in] ULONG nMode);

[id(5), helpstring("method GetQuad")]

HRESULT GetQuad([out] BYTE* bQuad);

[id(6), helpstring("method SetQuad")]

HRESULT SetQuad([in] BYTE bQuad);

[id(7), helpstring("method ReadData")]

HRESULT ReadData(void);

Метод ReadData не имеет параметров. Он будет производить чтение файла с данными о новом графике. Далее мы собираемся вручную ввести сразу много изменений в файл с описанием класса COpenGL. При изменении файла заголовков класса мы нарушим стиль, заданный стартовой заготовкой, и вернемся к более привычному, принятому в MFC-приложениях. Мы перенесем существующее тело конструктора, а также функции OnDraw в файл реализации класса OpenGL.cpp. В файле OpenGL.h останутся только декларации этих функций. Ниже приведено полное описание класса COpenGL с учетом нововведений, упрощений и исправлений. Вставьте его вместо того текста, который есть в файле OpenGL.h, но будьте очень осторожны. Если имена ваших классов (методов, или файлов) не соответствуют моим, то вносите изменения выборочно. Далее мы будем вставлять в файл новые сущности с помощью инструментов студии.

#pragma once

#include "resource.h"

#include <atlctl.h>

#include "ATLGL.h"

#include "_IOpenGLEvents_CP.h"

class Point3D //====== Вспомогательный класс

{

public:

float x, y, z; // Координаты точки

Point3D () { x = y = z = 0; }

Point3D (double xx, double yy, double zz)

{

x = float (xx);    z = float (yy);    y = float (zz);