![]() Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Доступ к серверу с помощью интерфейса 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; просмотров: 456. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |