Использование ActiveX компонентов в серде Visual C++, страница 2

2.Помещаем на форму вторую кнопку и создаем для нее обработчик. Кроме кнопки помещаем элемент Label и задаем ему идентификатор IDC_GRID2.

void CComTestDlg::OnBtnsecond()

{

3.В обработчике задаем переменную идентификатора программы ProgID – ее значение извлекаем из OLE/COM Object Viewer'а:

Рис.21

            const WCHAR* szProgID = L"MSFlexGridLib.MSFlexGrid";

4.По идентификатору программы определяем CLSID

    CLSID  clsid;

   HRESULT hr = ::CLSIDFromProgID( szProgID, &clsid );

   if ( FAILED( hr ))

   {

               ::AfxMessageBox("Unable to get CLSID from ProgID.");

      return;

   };

   5. По определенному CLSID получаем интерфейс на фабрику классов

   IClassFactory* pCF;

   hr = CoGetClassObject( clsid,

                          CLSCTX_INPROC,

                          NULL,

                          IID_IClassFactory,

                          (void**) &pCF );

   if ( FAILED( hr ))

   {

      ::AfxMessageBox("Failed to GetClassObject server instance.");

      return;

   }

6. Из фабрики классов получаем интерфейс IDispatch

   IDispatch* pDisp;

   hr = pCF->CreateInstance( NULL, IID_IDispatch, (void**) &pDisp );

   pCF->Release();

   if ( FAILED( hr ))

   {

      ::AfxMessageBox("Failed to create server instance.");

      return ;

   }

  7. Подключаем интерфейс IDispatch к оконному элементу IDC_GRID2

   AtlAxAttachControl(pDisp,GetDlgItem(IDC_GRID2)->m_hWnd,NULL);

8. Теперь можно обращаться к вызовам интерфейса. Реализуем методы, которые были использованы ранее в классах оболочек.

Для изменения стиля границы находим в OLE/COM Object Viewer'е интерфейс IMSFlexGrid и свойство данного интерфейса BorderStyle. Как видно для изменения свойства и чтения его используется два метода с одинаковым именем, но один обозначен как propget(property get) propput (property put). Метод изменения принимает один параметр.

            //m_Grid.SetBorderStyle(0);

Рис.22

Для прямого вызова метода изменения свойства выполним следующие действия:

{

   DISPID dispid;        // переменная номера свойства

            WCHAR * name=L"BorderStyle";// имя свойства в кодировке Unicode

// Определяем по именя свойства его номер

            pDisp->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&dispid);

//Заполнения параметров для передачи в метод Invoke

            DISPPARAMS dispparams; //Структура передаваемых параметров

            DISPID mydispid[1] = { DISPID_PROPERTYPUT };//Используем помещение значения свойства

            VARIANTARG vararg[1];//передаем 1 параметр

            dispparams.rgvarg = vararg; //заносим адрес массива параметров в структуру передачи

            VariantInit(&dispparams.rgvarg[0]);//Инициализируем  массив параметров

            dispparams.rgvarg[0].vt = VT_I2;   // граница кодируется числом – тип 2 байта целое

            dispparams.rgvarg[0].iVal = 0;         // 0 – нет границы

            dispparams.rgdispidNamedArgs = mydispid; // массив флага

            dispparams.cArgs = 1;      // количество передаваемых аргументов

            dispparams.cNamedArgs = 1;   // количество изменяемых свойств

//Вызов метода Invoke с передачей агрументов. Данный метод собственно изменяет свойство или вызываем метод компонента.

            pDisp->Invoke(dispid, IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_PROPERTYPUT,