Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Троелсен Э. -> "С# и платформа .NET. Библиотека программиста" -> 237

С# и платформа .NET. Библиотека программиста - Троелсен Э.

Троелсен Э. С# и платформа .NET. Библиотека программиста — СПб.: Питер, 2004. — 796 c.
ISBN 5-318-00750-3
Скачать (прямая ссылка): cplatforma2004.pdf
Предыдущая << 1 .. 231 232 233 234 235 236 < 237 > 238 239 240 241 242 243 .. 320 >> Следующая

следующим образом:
STuMENKX)JMP ССоСат::SpsedU?(int delta) {
Il Добавляем значение delta и проверяем, не пришло ли время сработать событий curSpeed += delta:
// Если автонобиль еще не ¦,трвался. а скорость превысила максимально // допустимую...
if<curSpeed >~ maxSpeed && (dead) {
II Должно сработать событие и установиться состояние 'dead' CComBSTP. msg{"You are toast..."):
Fire Exploae<JJ.msa.DetuchO):
curSpeed = maxSpeed: dead - true:
}
return S_QK;
}
Генерация ошибки COM
Вспомним, что при создании класса CoCa г мы добавили поддержку протокола ошибок СОМ. Для наших целей нам сейчас совершенно необязательно углубляться в объекты ошибок СОМ на низком уровне. Все, что нам сейчас необходимо знать, — го, что нам потребуется вызвать унаследованный метод Error(), для того чтобы сообщить об ошибке в среде ATL. Продемонстрируем это на примере. Давайте внесем изменения в метод GetCurSpeed() таким образом, чтобы при попытке пользователя получить информацию о скорости автомобиля, который уже «мертв», ему выдавалось сообщение об ошибке (то есть возвращался объект ошибки СОМ):
STDMETH0OIMP ССоСаг::GetCurSpeedCіnt *currSp)
{ // Генерируем ошибку, если автомобиль "мертв"
ifudead)
{
*currSp = curSpeed:
return S_OK;
)
else
I
*currSp = 0:
Error (''Sorry, this car has met It's maker");
588 Глава 12 • Взаимодействие с унаследованным программным кодом
return E FAIL;
, 1
К этому моменту в нашем распоряжении есть сокласе СОМ, который поддерживает единственный пользовательский интерфейс (он же интерфейс по умолчанию — [default]). Кроме того, наш сокласе может передавать клиентам информацию о событиях и ошибках. Откомпилируем сокласс еще раз, чтобы убедиться в отсутствии опечаток.
Представление внутренних подобъектов и применение SAFEARRAY
Чтобы сокласс полностью отвечал нашим требованиям, нам осталось добавить в него еще два элемента. Первый элемент - это внутренний объект, который будет называться CoEngi пе и представлять двигатель нашего автомобиля. Чтобы создать его, вставим при помощи ATL Object Wizard новый ATL Simple Object, изменим имя интерфейса [default] на IEngine и изменим на вкладке Attributes (Атрибуты) тип интерфейса на [dual ].
Затем используем мастер Add Method для добавления в интерфейс I Engine единственного метода, который будет называться GetCyl nders ( . Этот метод будет возвращать массив COM SAFEARRAY переменных BSTR, которые будут представлять прозвища для каждого цилиндра двигателя. (Да, я согласен, что прозвища цилиндрам даются не так часто, но это позволит нам возвращать массив строковых значений клиенту .NET.) Код IDLдля интерфейса IEngine будет выглядеть следующим образом:
[object, ой 1 df23D2BB87-A8FB-4301-DED5-9DOCA77AE403). dual, helpstringt"!Engine
Interface"). pointer_default(un1que) ]
Interface IEngine : IDispatch
{
[id(D. helpstringt "method GetCyl і nders")]
HRESULT GetCylіnders{[out. recvolj VARIANT* arCylinders):
}:
А вот так может выглядеть реализация метода GetCyl nders
STOHfTHODIhP CCoEngir.e:: GetCyl і rider; {VARIAr^ *arCyIinders) {
Variantlmt(arCylinders): II Массив строковых значений arCylinders->vt - VT_ARRAY | VTJlSTR:
// Создаем пассив
SAFEARRAV *pSA;
SAFEARRAYBOUND bounds - {4. 0}:
pSA = SafeArrayCreate(VT_BSTR. 1. abounds);
// Заполняв* массив BSTR *theStrings;
SafeArrayAccessDataCpSA. (void**)&theStrings);
theStrings[0] - SysAllocString(L"Grinder"); theStrings[l] - SysAllocString(L"Oily"): th9Str-.ngs[21 = SvsAl loc5t'"'HiQ(L:'ThuPDer:'): the$trings[3] - SysAllocString(L"Cru5her"):
Создаем при помощи ATL 589
SafeArrayUnaccessOata(pSA);
// Возвращаем кассиэ
arCylinders-=-parray = pSA;
return
}
Если вы никогда не работали с COM SAFEARRAYвручную, то этот код, скорее всего, вызовет у вас недоумение. Попробуем вкратце объяап-пъ, что к чему. SAFEARRAY — это самоописываемый массив [о!еаиІотагіоп]-совместимьіх типов данных, для которого задаются верхняя и нижняя границы тех элементов, которые могут быть в него помещены. Объекты SAFEARRAY создаются, заполняются и управляются при помощи набора библиотечных функций СОМ (как это было сделано в предыдущем коде). Однако нам опять-таки совершенно незачем углубляться во все эти подробности. Главное, что необходимо вынести из всего сказанного, - то, что метод GetCyl і riders (J может быть использован внешними клиентами для получения массива строковых объектов COM (BSTR).
Наша следующая задача — обеспечить возможность клиентам СОМ получать ссылки на интерфейс I Eng і пе из типа СоСаг. Для этого мы будем использовать стандартный механизм СОМ для включения одного типа в другой. Внешний класс CoCa г будет обеспечивать доступ к внутреннему классу CoEngi ne при помощи следующего дополнительного метода интерфейса
// Вспомните! Возврат указателя на интерфейс требует двойного преобразования, Также // определение интерфейса ІЕлдіпе должно быть размещено над определением интерфейса // Tear. так. чтобы компилятор MIOL мог "увидеть" определение интерфейса interface ICar : IDispatch [
[id(3>. heloStrlrajt'method GrtEnglne'H
Предыдущая << 1 .. 231 232 233 234 235 236 < 237 > 238 239 240 241 242 243 .. 320 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100