Введение методов в интерфейс IOpenGL
На этом этапе
важно решить, какие данные (свойства) и методы класса будут экспонироваться
СОМ-объектом, а какие останутся в качестве служебных, для внутреннего пользования.
Те методы и свойства, которые будут экспонированы, должны быть соответствующим
образом отражены в IDL-файле. Те, которые нужны только нам, останутся внутри
сервера. Для примера введем в число экспонируемых методов функцию GetLightParams,
которая определяет действующие параметры освещения.
- Поставьте фокус на строку
с именем интерфейса lOpenGL в окне CLassView и вызовите контекстное меню.
- Выберите команду Add
> Add Method В окне мастера Add Method Wizard введите в поле Method
Name имя метода GetLightParams. В поле Parameter Name введите имя параметра
pPos, в поле Parameter Type: — тип параметра int*, задайте атрибут параметра,
установив флажок out, и нажмите кнопку Add.
- Нажмите кнопку Finish.
Проанализируйте
изменения, которые появились в IDL-файле, в файле OpenGLh и в файле OpenGLcpp.
В первом из перечисленных файлов появилось новое, уточненное описание метода
интерфейса
1:
interface
lOpenGL : IDispatch
{
[propput,
bindable, requestedit, id(DISPID_FILLCOLOR)]
HRESULT
FillColor([in]OLE_COLOR clr);
[propget,
bindable, requestedit, id(DISPID_FILLCOLOR)]
HRESULT
FillColor([out,
retval]OLE_COLOR* pclr);
[id(l),
helpstring("method GetLightParams")]
HRESULT
GetLightParams([out] int* pPos);
};
в файле заголовков
появилась строка декларации метода ко-класса, который реализует функциональность
интерфейса:
STDMETHODIMP
GetLightParams(int* pPos);
и, наконец, в файле реализации ко-класса появилась стартовая заготовка тела
метода:
STDMETHODIMP
COpenGL::GetLightParams(int *pPos)
{
//
TODO: Add your implementation code here
return
S_OK;
}
Повторите описанные
действия и введите в интерфейс еще один метод SetLightParam, который изменяет
один из параметров освещения сцены OpenGL. При задании параметров этого метода
добейтесь такого описания в окне Parameter List:
[in]
short lp [in]
int nPos;
Введите в состав
интерфейса еще один метод ReadData, на сей раз без параметров. Он будет реагировать
на кнопку и производить чтение файла с данными о новом графике. Для управления
обликом поверхности графика нам понадобятся две пары методов типа get-set. Введите
в интерфейс следующие методы:
- GetFillMode с параметром
[out] DWORD* pMode;
- SetFillMode С параметром
[in] DWORD nMode;
- GetQuad с параметром
[out] BOOL* bQuad;
- SetQuad с параметром
[in] BOOL bQuad.
Найдите новые
методы в IDL-файле и убедитесь, что мастер автоматически пронумеровал методы
(1,2,...), присвоив им индексы типа DISPID:
[id(l),
helpstring("method GetLightParams")]
HRESULT
GetLightParams([out] int* pPos);
[id(2),
helpstring("method SetLightParam")]
HRESULT
SetLightParam([in] short Ip, [in] int nPos);
[id(3),
helpstring("method ReadData")]
HRESULT
ReadData(void);
[id(4),
helpstring("method GetFillMode")]
HRESULT
GetFillMode([out] DWORD* pMode);
[id(5),
helpstring("method SetFillMode")]
HRESULT
SetFillMode([in] DWORD nMode);
[id(6),
helpstring("method GetQuad")]
HRESULT
GetQuad([out] BOOL* bQuad);
[id(7),
helpstring("method SetQuad")]
HRESULT
SetQuad([in] BOOL bQuad);
С помощью этих
индексов методы будут вызываться клиентами, получившими указатель на интерфейс
диспетчеризации IDispatch. Мы уже обсуждали способ, который используется при
вызове методов по индексам DISPID. Непосредственный вызов производит метод IDispatch:
: invoke. Тот факт, что наш объект поддерживает IDispatch, мы определили при
создании ATL-заготовки. Если вы не забыли, то мы тогда установили переключатель
типа интерфейса в положение Dual. Это означает, что объект будет раскрывать
свои методы как с помощью vtable, так и с помощью IDispatch. Некоторые детали
этого процесса обсуждались в предыдущем уроке.