Пришлось впервые столкнуться с технологией ActiveX. Тяжело девушке разобраться.

Я программно получаю список ActiveX зарегистрированных на компьютере. Затем загружаю нужный мне ActiveX в контейнер OleConteiner на форме (среда С++ Builder 6). Я знаю CLSID и ProgID этого ActiveX. Подскажите цепочку кода, которая позволила бы вывести в отдельный список имена всех методов этого ActiveX, которые находятся в его интерфейсах.
Спасибо.
Спасибо. Попробую разобраться.
GS>Советую сначала разобраться — а нужно ли получать список методов программно или все-таки ручками, поскольку ручками это делается просмотром в OleVewer. Ну, если intellisense не работает.
У меня стоит задача следующая:
1.Загрузить в список ActiveX установленные на компьютере.
2.Выбрать любой ActiveX из списка и загрузить в OleConteiner.
3.Получить список методов, которые есть у этого ActiveX в его интерфейсах.
Пункт 1 и 2 я сделала. С 3-им пунктом полный завал. Очень жалею, что в слабо ориентируюсь в COM технологиях. Надо будет прочитать хорошую книгу об этом, а сейчас время поджимает c кодом, а я “плаваю” в этом вопросе.
С кодом из приведенной ссылки пока не получается. Проблема в том что моя “родная” и, к сожалению, единственная среда разработки это C++ Builder 6.
Что касается OleVewer, то насколько я слышала это для VC, а не для Builder.
Пробую реализовать пункт №3, но пока безуспешно.
Для начала, как я понимаю, надо выполнить три пункта:
A) Запросить IDispatch
B) Взять GetTypeInfo у запрошенного IDispatch
C) Взять ITypeLib у запрошенного ITypeInfo (ITypeInfo::GetContainingTypeLib)
Мои безуспешные попытки в C++ Builder:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
// CheckListBoxClassName это список c классами зарегистрированных ActiveX
//получаю указатель на ActiveX
wchar_t *ConvertInID;
for (int i = 0; i<CheckListBoxClassName->Count; i++)
{
if(CheckListBoxClassName->State[i]==cbChecked)
{
ConvertInID = (WideString)CheckListBoxClassName->Items->Strings[i];//ProgID моего ActiveX
break;
}
}
CLSID clsid;
CLSIDFromProgID(ConvertInID,&clsid);
IUnknown * pDispU = CreateComObject(clsid);
IDispatch * pInterfaceIDiapatch = NULL;
if(0 == (pDispU->QueryInterface(IID_IDispatch,(LPVOID*)&pInterfaceIDiapatch)) && (pInterfaceIDiapatch != NULL))
{
ITypeInfo * pInterfaceInfo = NULL;
if(0==(pInterfaceIDiapatch->GetTypeInfo(0,0,&pInterfaceInfo)) &&(pInterfaceInfo != NULL))
{
//планируемый код
//ITypeLib * pITypeLib = NULL;
//unsigned int * pIndex;
//HRESULT hRes = pInterfaceInfo->GetContainingTypeLib(&pITypeLib,pIndex);
}
pInterfaceInfo->Release();
}
}
На строке pDispU->QueryInterface(IID_IDispatch,(LPVOID*)&pInterfaceIDiapatch) очень часто, практически через раз, выскакивают исключения.
Почему не правильно я не знаю.
Разобралась.
Надо писать в моем коде для Builder:
_di_IUnknown pDispU = CreateComObject(clsid);
Попробую дальше писать код для достижения цели.
Здравствуйте, Lena_ki, Вы писали:
L_>На строке pDispU->QueryInterface(IID_IDispatch,(LPVOID*)&pInterfaceIDiapatch) очень часто, практически через раз, выскакивают исключения.
L_>Почему не правильно я не знаю.
Скорее всего потому, что в вашем списке есть СОМ объекты не реализующие IDispatch. СОМ объект не обязан его реализовывать и не обязан иметь библиотеку типов. Большинство из со-классов зарегистрированых в среднестатистической системе как раз и относятся имено к тем, которые IDispatch не реализуют.
Не путайте ActiveX (в классическом понимани — нечто с окошком реализующее IDispatch и сотств. имеющее библиотеку типов) и просто СОМ. Между прочим, нормального определения термина ActiveX не существует, а то которое я когда-то видел у Майкрософта гласило, что "ActiveX — это СОМ с саморегистрацией". Т.е. IUnknown+DllRegisterServer == минимальный ActiveX, IDispatch и библиотека типов — опионально.
Кстати, если вам просто нужна информация о типах — грузить контрол в контейнер совсем не обязательно.