Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Доступ к серверу с помощью интерфейса IDispatch




Сценарий для версии MVS 6.0

 

Проиллюстрируем эту технологию на примере получения доступа к серверу Microsoft Word. Последовательность действий следующая.

Шаг 1. Создание каркаса приложения.

Создадим с помощью мастера Win32 Console Application заготовку обычного консольного приложения и выберем приложение с поддержкой MFC. Предполагается, что проекту присвоено имя UseWord.

Шаг 2. Инициализация OLE.

Любое клиентское приложение, будь оно консольным или оконным, которое хочет использовать какой-либо сервер СОМ, должно инициализировать службу СОМ с помощью функции CoInitialize(). Эту функцию надо вызвать всего один раз прежде чем использовать какие-либо другие функции СОМ, т.е. прежде чем пытаться устанавливать связь с сервером и вызывать его функции. По завершению работы приложения необходимо вызвать функцию CoUninitialize(), которая, как сказано в MSDN, «закрывает библиотеку СОМ в текущем апартаменте, выгружает все библиотеки DLL, загруженные апартаментом, освобождает все другие ресурсы апартамента и разрывает все RPC-соединения с апартаментом». Обеспечить вызов этих функций можно и с помощью описания класса OleInit, как это было сделано выше в подразделе «Доступ к серверу с помощью пользовательских интерфейсов».

С учетом этого файл реализации консольного приложения UseWord.cpp может иметь вид, приведенный в следующем листинге.

// UseWord.cpp

#include "stdafx.h"

#include "UseWord.h"

#include <Conio.h>

// …

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

{

       cerr << _T("Fatal Error: MFC initialization failed") << endl;

       return 1;

}

if (CoInitialize(NULL)!=S_OK)

{

       char Work[]="Ошибка инициализации OLE";

       CharToOem(Work,Work);

       cerr<<Work<<endl;

       getch(); return 1;

}

TRACE("Инициализация OLE выполнена успешно\n");

// сюда надо поместить код для работы с WinWord

CoUninitialize();

getch();

return 0;

}

 

Если такую программу запустить на выполнение в режиме отладки, то в окне Debug мы увидим сообщения среды Visual C++ о загрузке библиотек ole32.dll, msvcrt.dll, advapi32.dll и rpcrt4.dll, которые не будут загружаться, если убрать из программы инициализацию OLE. Кроме того, естественно, мы должны увидеть сообщение «Инициализация OLE выполнена успешно» все в том же окне Debug. Рекомендую это проделать практически, следуя концепции быстрой разработки программ.

Шаг 3. Запуск сервера Word на выполнение.

Для использования диспинтерфейсов Word надо получить доступ к их объявлениям, хранящимся в библиотеке MSWord.olb. Этот файл должен находиться в каталоге …\\Program Files\Microsoft Office\Office. (В зависимости от версии Microsoft Word имя файла может отличаться от приведенного, например, Word9.olb. Сказанное относится и к имени каталога Office, которое может также включать номер версии, например, Office11.)

Для получения описаний интерфейсов и методов воспользуемся ClassWizard: вызовем его окно, нажмем кнопку «Add Class» и в появившемся мини-меню выберем тему «From a Type Library». В появившемся диалоговом окне загрузки файла надо выбрать файл MSWord.olb и нажать кнопку ОК, после чего появится еще одно диалоговое окно (рис.1). В нем надо выбрать те классы, к которым нам требуется получить доступ, и опять-таки нажать ОК. Мастер создаст файлы MSWord.h и MSWord.cpp и поместит их в каталог проекта. Заголовочный файл MSWord.h надо подключить к проекту.

 

 

 

Рис. 1. Выбор классов для генерации

 

В файлы MSWord.h и MSWord.cpp ClassWizard поместит сгенерированные классы-оболочки (IDispatch wrapper classes), посредством которых мы и будем вызывать методы интерфейсов.

Теперь модифицируем файл UseWord.cpp, добавив в него код запуска Word.

 

// UseWord.cpp

#include "stdafx.h"

#include "UseWord.h"

#include <ComDef.h>

#include <Conio.h>

#include "MSWord.h"

// «стандартные» директивы препроцессора опущены

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

{

   cerr << _T("Fatal Error: MFC initialization failed") << endl; return 1;

}

if (CoInitialize(NULL)!=S_OK)

{

   char Work[]="Ошибка инициализации OLE";

   CharToOem(Work,Work);

   cerr<<Work<<endl;

   getch(); return 1;

}

TRACE("Инициализация OLE выполнена успешно\n");

try

{

   LPDISPATCH pDisp;

   LPUNKNOWN pUnk;

   CLSID clsid;

   _Application m_app;

   CLSIDFromProgID(L"Word.Application",&clsid);

   if(GetActiveObject(clsid,NULL,&pUnk)==S_OK)

   {

         VERIFY(pUnk->QueryInterface(IID_IDispatch,(void **)&pDisp)==S_OK);

         m_app.AttachDispatch(pDisp);

         pUnk->Release();

         TRACE("Подключение к запущенному экземпляру Word выполнено

                                        успешно");

   }

   else // запускаем приложение Word

   {

         if(!m_app.CreateDispatch("Word.Application"))

         {

              throw "Не найдено приложение Word";

         }

   }

   /* В этой точке мы либо подключились к уже запущенному экземпляру Word, либо запустили свой экземпляр приложения */

   m_app.SetVisible(true);

   TRACE("Окно Word должно быть видимо");

   char Work[]="Нажми любую клавишу для завершения работы";

   CharToOem(Work,Work);

   cout<<Work<<endl;

   getch();

 

/* VARIANT SaveChanges;

   SaveChanges.vt=VT_BOOL;

   SaveChanges.bVal=VARIANT_TRUE;

   COleVariant fict;

   m_app.Quit(&SaveChanges,&fict,&fict);

*/

}

catch(_com_error &ex)

{  /* вывод сообщения об ошибке*/

       char *Mess=new char [strlen(ex.ErrorMessage())+1];

       CharToOem(ex.ErrorMessage(),Mess);

       cerr<<Mess<<endl;

       delete Mess; // освобождение памяти

}

catch(char * msg)

{

AfxMessageBox(msg);

}

CoUninitialize();

getch();

return 0;

}

 

Пример реализации одного из методов интерфейса _Application:

 

LPDISPATCH _Application::GetDocuments()

{

LPDISPATCH result;

InvokeHelper(0x6, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL);

return result;

}

 

Вспомогательная функция InvokeHelper(), реализация которой содержится в файле OleDisp2.cpp, подготавливает параметры для вызова функции IDispatch::Invoke(), вызывает ее и возвращает результат.










Последнее изменение этой страницы: 2018-04-12; просмотров: 379.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...