Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Сценарий для версии MVS 2005
Проиллюстрируем эту технологию на примере получения доступа к серверу Microsoft Word. Последовательность действий следующая. Шаг 1. Создание каркаса приложения. Создадим с помощью мастера Win32 Console Application заготовку обычного консольного приложения с поддержкой MFC. Предполагается, что проекту присвоено имя UseWord. Шаг 2. Инициализация OLE. Любое клиентское приложение, будь оно консольным или оконным, которое хочет использовать какой-либо сервер СОМ, должно инициализировать службу СОМ с помощью функции CoInitialize(). Эту функцию надо вызвать всего один раз прежде чем использовать какие-либо другие функции СОМ, т.е. прежде чем пытаться устанавливать связь с сервером и вызывать его функции. По завершению работы приложения необходимо вызвать функцию CoUninitialize(), которая, как сказано в MSDN, «закрывает библиотеку СОМ в текущем апартаменте, выгружает все библиотеки DLL, загруженные апартаментом, освобождает все другие ресурсы апартамента и разрывает все RPC-соединения с апартаментом». Обеспечить вызов этих функций можно и с помощью описания класса OleInit, как это было сделано выше в подразделе «Доступ к серверу с помощью пользовательских интерфейсов». С учетом этого файл реализации консольного приложения UseWord.cpp может иметь вид, приведенный в следующем листинге. #include "stdafx.h" #include "UseWord.h" // …
CWinApp theApp;
using namespace std; struct OleInit { OleInit() { CoInitialize(NULL); TRACE("CoInitialize(NULL) executed\n"); } ~OleInit() { CoUninitialize(); TRACE("CoUninitialize() executed\n"); } } Init;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { _tprintf(_T("Fatal Error: MFC initialization failed\n")); return nRetCode = 1; }
return nRetCode; }
Если такую программу запустить на выполнение в режиме отладки, то в окне Debug мы увидим сообщения «CoInitialize(NULL) executed» все в том же окне Debug. Рекомендую это проделать практически, следуя концепции быстрой разработки программ. Шаг 3. Генерация классов-оболочек для интерфейсов сервера Word. Для использования диспетчерских интерфейсов Word надо получить доступ к их объявлениям, хранящимся в библиотеке MSWord.olb. Этот файл должен находиться в каталоге …\\Program Files\Microsoft Office\Office. (В зависимости от версии Microsoft Word имя файла может отличаться от приведенного, например, Word9.olb. Сказанное относится и к имени каталога Office, которое может также включать номер версии, например, Office11.) Для получения описаний интерфейсов и методов Word надо выполнить команду ProjectèAdd Class, в появившемся окне выбрать Categories==MFC и Templates==MFC Class From TypeLib. Нажимаем кнопку Add и в новом появившемся окне открываем список Available type libraries (доступные библиотеки типов). В этом списке перечислены все библиотеки типов, зарегистрированные в реестре. Выбираем в списке элемент Microsoft Word (рис.1), а в списке Interfaces выберем один интерфейс – _Application – и включим его в список Generated classes с помощью кнопки >. (Ясное дело, что в «реальной» программе надо было бы генерировать классы для всех интерфейсов, которые нам понадобятся.) Обратите внимание на то, что в элементах Class и File мастер показывает имена классов и заголовочных файлов, которые он будет генерировать. Закончите работу по генерации объявлений классов нажатием кнопки Finish.
Рис. 1. Выбор библиотеки типов и интерфейсов
В файл CApplication0.h мастер поместит сгенерированный класс-оболочку CApplication (IDispatch wrapper classes), который мы и будем использовать для вызова методов интерфейсов. Класс CApplication облегчает подключение к серверу или его запуск и обеспечивает вызов методов сервера с помощью вспомогательных функций. Рекомендую ознакомиться с содержимым этого файла.
Шаг 4. Запуск сервера Word. Теперь модифицируем файл UseWord.cpp, добавив в него код запуска Word. Не забудьте в начало файла добавить директивы для подключения заголовочного файла, сгенерированного мастером. // UseWord.cpp : Иллюстрация запуска приложения MS Word // #include "stdafx.h" #include "UseWord.h" #include <ComDef.h> // объявление класса _com_error #include "CApplication.h" #include <ConIO.h>
#ifdef _DEBUG #define new DEBUG_NEW #endif CWinApp theApp; using namespace std;
char Buf[1024]; char * Rus(char * Str) { CharToOemA(Str,Buf); return Buf; } struct OleInit { OleInit() { CoInitialize(NULL); TRACE("CoInitialize(NULL) executed\n"); } ~OleInit() { CoUninitialize(); TRACE("CoUninitialize() executed\n"); } } Init;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { _tprintf(_T("Fatal Error: MFC initialization failed\n")); return nRetCode = 1; } try { LPDISPATCH pDisp; LPUNKNOWN pUnk; CLSID clsid; CApplication m_app; /*Получение GUID приложения Word по его внешнему имени Word.Application, под которым Word зарегистрирован в реестре*/ CLSIDFromProgID(L"Word.Application",&clsid); /*GetActiveObject позволяет получить интерфейс запущенного экземпляра сервера, если таковой есть, по его 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 выполнено успешно\n"); } else // самостоятельно запускаем приложение Word if(!m_app.CreateDispatch(clsid)) throw "Не найдено приложение Word"; /* В этой точке мы либо подключились к уже запущенному экземпляру Word, либо запустили свой экземпляр приложения */ m_app.put_Visible(true); TRACE("Окно Word должно быть видимо\n"); cout<<Rus("Нажми любую клавишу для завершения работы")<<endl; _getch(); // Готовим параметры для метода Quit() VARIANT SaveChanges, DocumentFormat, Empty; SaveChanges.vt=VT_BOOL; SaveChanges.boolVal=VARIANT_TRUE; DocumentFormat.vt=VT_I4; DocumentFormat.intVal=1; Empty.vt=VT_EMPTY; m_app.Quit(&SaveChanges,&DocumentFormat,&Empty); } catch(_com_error &ex) // обработка СОМ ошибок { AfxMessageBox(ex.ErrorMessage()); } catch(char * msg) { AfxMessageBox(CString(msg)); } _getch(); return nRetCode; }
Некоторые комментарии к программе. В файле CApplication.h нет ни одного GUID! И вообще здесь в программе используется только clsid сервера Word, который мы получаем с помощью функции CLSIDFromProgID(), и еще GUID диспетчерского интерфейса IID_IDispatch, определенный где-то в другом месте. Функция void COleDispatchDriver::AttachDispatch( LPDISPATCH lpDispatch, BOOL bAutoRelease = TRUE );
подключает интерфейс lpDispatch к объекту класса COleDispatchDriver (класс CApplication является наследником этого класса). Параметр bAutoRelease указывает, должен ли интерфейс освобождаться при выходе объекта из сферы видимости. В нашем случае мы прикрепили полученный с помощью функции QueryInterface() интерфейс pDisp к объекту m_app. После этого мы сможем вызывать методы объекта m_app. Вот примеры реализации оболочек (wrapper) двух методов интерфейса _Application, которые мы используем как методы объекта m_app:
|
||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 596. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |