» » » Алекс Jenter - Программирование на Visual C++. Архив рассылки


Авторские права

Алекс Jenter - Программирование на Visual C++. Архив рассылки

Здесь можно скачать бесплатно "Алекс Jenter - Программирование на Visual C++. Архив рассылки" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Рейтинг:
Название:
Программирование на Visual C++. Архив рассылки
Автор:
Издательство:
неизвестно
Год:
неизвестен
ISBN:
нет данных
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

Описание книги "Программирование на Visual C++. Архив рассылки"

Описание и краткое содержание "Программирование на Visual C++. Архив рассылки" читать бесплатно онлайн.



РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.






Для каждой точки соединения, реализованной в нашем классе CMyInterface, мы должны объявить connection point part, которая реализует точку соединения. Если вы реализуете одну или более точек соединения вы также должны объявить простую карту соединений в вашем классе. Карта соединений – это таблица точек соединения, поддерживаемых ActiveX-контролом. Наш пример демонстрирует простую карту соединений и одну точку соединения. Для этого откройте файл объявления класса MyInterface.h и сразу после макроса DECLARE_INTERFACE_MAP() добавьте нижеприведенный код:

DECLARE_CONNECTION_MAP()

BEGIN_CONNECTION_PART(CMyInterface,ObjCP)

 CONNECTION_IID(IID_IFireClassEvents

END_CONNECTION_PART(ObjCP)

Таким образом мы объявляем карту соединений. BEGIN_CONNECTION_PART и END_CONNECTION_PART — это макросы, объявленные во встроенном классе и наследуемые от CConnectionPoint, который реализует эту точку соединения. Если вы хотите переопределить какую-либо функцию класса CConnectionPoint или добавить функцию-член вашего родителя, тогда объявите её между двумя этими макросами. К примеру, макрос CONNECTION_IID, расположенный между двумя этими макросами, переопределяет функцию CConnectionPoint::GetIID.

Я буду немного непоследователен, однако попрошу вас сразу, раз уж вы редактируете данный заголовочный файл, подняться к объявлению класса CMyInterface и перед его объявлением вставить следующие строки:

extern const IID IID_IFireClassEvents;

interface IFireClassEvents : public IDispatch {};

Первая строка объявляет константу IID_IFireClassEvents, которую мы использовали в макросе CONNECTION_IID(IID_IFireClassEvents). Ведь все должно работать без ошибок. Однако перед описанием этой константы стоит служебное слово extern. Это значит, что она уже где-то объявлена. Поэтому я и сказал, что слегка непоследователен. Здесь все правильно. Сейчас мы закончим с заголовочным файлом и объявим этот идентификатор интерфейса в файле реализации класса CMyInterface.

Вторая строка есть объявление интерфейса. Теперь сохраните файл MyInterface.h и закройте его.

Следующим этапом добавим в файл MyInterface.cpp то, о чем собственно говорили только что выше. Найдите в коде декларацию идентификатора IID_IMyInterface и сразу после него вставьте следующие строки (только не забывайте вставлять правильные числовые значения, если вы используете uuid, отличный от того, что создала мне утилита guidgen.exe):

#pragma warning( disable : 4211)

static const IID IID_IFireClassEvents = //(F7222740-2296-11d5-964D-00001CDC1022)

 {0xf7222740, 0x2296, 0x11d5, {0x96, 0x4d, 0x0, 0x0, 0x1c, 0xdc, 0x10, 0x22}};

#pragma warning(default : 4211)

Обратите внимание на две директивы препроцессора, которые окаймляют данное объявление. Первая из них гасит ненужное предупреждение компилятора, а вторая снова его разрешает. Теперь добавьте в карту интерфейсов интерфейс IConnectionPointContainer (MyInterface.cpp):

BEGIN_INTERFACE_MAP(CMyInterface, CCmdTarget)

 INTERFACE_PART(CMyInterface, IID_IMyInterface, Dispatch)

 INTERFACE_PART(CMyInterface, IID_IConnectionPointContainer, ConnPtContainer)

END_INTERFACE_MAP()

И наконец, сразу за картой интерфейсов вставьте карту соединений:

BEGIN_CONNECTION_MAP(CMyInterface, CCmdTarget)

 CONNECTION_PART(CMyInterface, IID_IFireClassEvents, ObjCP)

END_CONNECTION_MAP()

Затем добавьте в конструктор нашего класса вызов функции EnableConnections. Эта функция является недокументированной функцией класса CCmdTarget, однако если вы не вызовете её из конструктора класса, работающего с Connection point и являющегося потомком CCmdTarget, то у вас ничего не получится.

CMyInterface::CMyInterface() {

 EnableAutomation();

 EnableConnections();

 // To keep the application running as long as an OLE automation

 // object is active, the constructor calls AfxOleLockApp.

 AfxOleLockApp();

}

Сохраните редактируемый файл и постройте наш проект. Если вы делали все правильно, то не должно быть ни ошибок, ни предупреждений. На данный момент у нас готов основной каркас. Займемся реализацией непосредственно самих функций. Однако сначала я хотел бы обратить ваше внимание на следующий факт. Я думаю, ни для кого не секрет, что COM-сервер может иметь сразу нескольких клиентов. Может случиться так, что этот сервер должен посылать событие клиентам в ответ на какое-либо действие пользователя. Например, сервер имеет графический интерфейс, и когда пользователь выбирает меню Файл, сервер должен уведомить ВСЕХ ЗАИНТЕРЕСОВАННЫХ клиентов об этом. Естественно возникает 2 вопроса:

1. Каким образом сервер сможет послать событие сразу всем клиентам.

2. Как определить, какой клиент заинтересован в получении событий, а какой нет?

Начнем со второго вопроса. Для этих целей интерфейс IConnectionPoint предусматривает специальные методы подписки на события Advise и Unadvise. С помощью первого из них клиент сообщает серверу, что он желает получать уведомления относительно какого-либо события, а вторая функция, наоборот, сообщает серверу, что данный клиент больше в таких сообщениях не нуждается. Соответственно, сервер должен иметь некий список, в который он заносит клиентов, подписанных на те или иные сообщения. И из которого он потом будет удалять отписавшихся клиентов. Таким образом, когда серверу нужно будет послать некое событие клиентам, то он в цикле пробежится по этому списку и отправит сообщения всем заинтересованным клиентам. Это и есть ответ на первый вопрос. Теперь приведем процедуру, которая реализует все выше сказанное. Вставьте её код в файл MyInterface.cpp а также не забудьте объявить её в MyInterfcae.h.

void CMyInterface::FireEvent() {

 const CPtrArray* pConnections=m_xObjCP.GetConnections();

 int nConnections=pConnections->GetSize();

 for (int i=0; i<nConnections; i++) {

  IDispatch* pClient=(IDispatch*)(pConnections->GetAt(i));

  if (pClient) {

   VARIANT varResult;

   DISPPARAMS disp={0,0,0,0};

   HRESULT hr = pClient->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);

  }

 }

}

Итак, что же мы имеем? Скажу сразу, что MFC сильно облегчила нам жизнь. Здесь const CPtrArray* pConnections=m_xObjCP.GetConnections(); мы объявляем указатель на CPtrArray и присваиваем ему значение полученное из m_xObjCP.GetConnections(). Вот и все. Теперь мы имеем указатель на список всех наших потенциальных клиентов. Объект m_xObjCP поддерживается средствами CCmdTarget и самостоятельно, «без нашего участия» заносит в список подписавшихся и удаляет из него отписавшихся клиентов. Дальше все просто: мы перебираем в цикле всех наших клиентов и с помощью метода Invoke им события.

Еще раз напомню: не забудьте добавить описание этой функции в наш класс. А теперь измените тело функции FireMyEvent, как показано ниже.

void CMyInterface::FireMyEvent() {

 FireEvent();

}

Таким образом, мы заставим метод сгенерировать событие. Сохраните все сделанные вами изменения и постройте проект. Ошибок быть не должно. После чего найдите полученную DLL и с помощью утилиты regsvr32.exe (или любого другого инструмента, способного вызвать функцию DllRegisterServer) зарегистрируйте её в вашей операционной системе. На этом с сервером все!

Часть 3. Реализация клиента.

Программа-пример Client

Теперь напишем клиента. Выполните пункты меню File->New и заполните опции согласно рисунку 8.

Рисунок 8


Обратите внимание на папки, куда я помещаю проекты клиента и сервера. Они оба должны находиться в одном каталоге. Жмите Ок, и в появившемся мастере выберите опцию создания диалогового приложения, см. рисунок 9, после чего жмите Finish.

Рисунок 9


Отредактируйте диалоговую форму. Чтобы она приняла вид, как на рисунке 10.

Рисунок 10


Сразу создайте обработчик для кнопки "Fire event", он нам пригодится, а также для кнопки ОК. Теперь необходимо в функции InitInstance класса CPointClientApp добавить инициализацию COM. В нашем случае вполне сойдет инициализация для STA, поэтому воспользуемся функцией CoInitialize(NULL):

BOOL CPointClientApp::InitInstance() {

 AfxEnableControlContainer();

 CoInitialize(NULL);

Сразу же добавьте в этот класс с помощью ClassWizard функцию ExitInstance, а в её обработчике поставьте деинициализацию COM:

int CPointClientApp::ExitInstance() {

 CoUninitialize();

 return CWinApp::ExitInstance();

}

Все, с этим классом закончили. Сохраните все изменения. Следующим шагом мы должны хорошенько поработать с классом CPointClientDlg. Для этого откройте файл PointClientDlg.h, в котором находится определение этого класса. Сейчас мы снабдим компилятор информацией об интерфейсах нашего COM-сервера. Для этого добавьте в PointClientDlg.h до определения самого класса следующую строку (после чего постройте проект):

#import "..\Server\Debug\PointServer.tlb" no_namespace named_guids

Для того, чтобы компилятор смог найти TLB-файл нашего сервера по указанному пути, папки с проектами клиента и сервера должны находиться в общем каталоге. Если вы правильно указывали пути для проектов при их создании, как я просил, то все будет нормально.

Теперь давайте добавим в класс CPointClientDlg (файл PointClientDlg.h) две приватные переменные:


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

Похожие книги на "Программирование на Visual C++. Архив рассылки"

Книги похожие на "Программирование на Visual C++. Архив рассылки" читать онлайн или скачать бесплатно полные версии.


Понравилась книга? Оставьте Ваш комментарий, поделитесь впечатлениями или расскажите друзьям

Все книги автора Алекс Jenter

Алекс Jenter - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Отзывы о "Алекс Jenter - Программирование на Visual C++. Архив рассылки"

Отзывы читателей о книге "Программирование на Visual C++. Архив рассылки", комментарии и мнения людей о произведении.

А что Вы думаете о книге? Оставьте Ваш отзыв.