Реферат по предмету "Программирование"


Протоколы и стандарты объектно-ориентированного программирования

СОДЕРЖАНИЕ
Предисловие MS Windows и новый метод разработки программ Динамический
обмен данными OLE-технология Заключение Список литературы Приложение 1.Пример
использования OLE-технологии Предисловие Наиболее распространенным языком программирования
последне-го десятилетия безусловно является С. Этому способствовали
такиеего особенности, как лаконичность, мощность, гибкость, мо-бильность. Вместе
с тем, стремительное усложнение приложений, дляреализации которых применяются
традиционные процедурно-ориентиро-ваннные языки программирования и, в частности
С, заставляют гово-рить об определенном кризисе в их использовании, связанном
преж-де всего с недостаточной надежностью и выразительной способностью. Подобных
недостатков во многом лишены языки объектно-ориен-тированнго программирования
(ООП), в сонове которыхлежит идея мо-делирования объектов посредством иерархически
связанных классов.Отдельно взятый класс рассматривается как совакупность
множестваданных и операций над ними, причем доступ к элементам данныхкласса возможен
только посредством операций этого класса. Уста-новление четкой взаимозависимости
между данными и операциями ве-дет к большой целостности данных и значительно
повышает надеж-ность программ по сравнению с традиционными языками программиро-вания.
Кроме того, идея программирования с помощью классов вомногом использует
тот же подход, который позволяет людям формиро-вать модели объектов реального
мира. Впервые идеи ООП были реализованы в середине 60-х годов вязыке программирования
Симула-67. Последний, однако, не нашел вто время широкого распространения
как в силу своей относительноменьшей производительности по сравнению с
традиционными языкамитипа FORTRAN, ALGOL, PL/1 так и, возможно, неадекватности
предла-гаемых средств решаемым в то время задачи. Еще одним важным огра-ничением
для распространеия Симулы-67 стали трудности, с которы-ми пришлось столкнуться
большинству программистов при его изуче-нии. Дело в том, что наряду с целым рядом
безусловных достоинств,идеи ООП обладают и одним существенным недостатком
- они далеконе просты для понимания и особенно для освоения с целью практи-ческого
использования. С++ - развитие С. С++ - это объектно-ориентированыый язык, то
есть язык, поз-воляющий программисту оперировать объектами некоторых типов,предварительно
им определенным. Название языка "С++" отражаетэволюционный характер
изменения языка С (запись "++", в языке С,означает, что к какой-то переменной
прибавляется единица). Онимеет еще более мощные и гибкие средства для написания
эффектив-ных программ, чем С, от которого он произошел. Человек, програм-мирующий
на традиционных языках, может просто потерять голову оттех возможностей, которые
предоставляет С++. Но не менее важным является то, что такой распространенный
иуниверсальный язык, как С, сохранен в качестве основы. С прост,эффективен,
переносим. Чего только нет в языке С: строковых дан-ныхнет, матриц нет, средств
параллельного программирования тоженет. Нет даже ввода-вывода. Типы, операции
и операторы С очень близки к тому, с чем мыимеем дело в Ассемблере,- числа,
адреса, арифметические и логи-ческие действия, циклы... Кроме того, многие особенности
С нед-вусмысленно намекаю компилятору, как сократить код и время испол-нения
программы. Эти характерные черты языка С позволяют напи-сать эффективно работающий
и не слишком сложный компилятор. И хо-тя в машинных кодах на разных компьютерах
элементарные операцииобозначаютс по-разному, вряд ли разработчику компилятора
придет вголову интерпретировать простейшие выражения каким-нибудь ориги-нальным
способом. Именно поэтому язык С "идет везде и на всем",программы, написанные
на нем, работают эффективно, и их можно пе-реносить с одного компьютера
на другой. Большинство языков программирования созданы для решения оп-ределенного
круга задач. В них не только не хватает определенныхтипов данных и функций,
но и много лишнего с точки зрения челове-ка, далекого от области, на которую
ориентирован язык. Специали-зированные типы данных или операторы, требующие нетривиальнойподдержки,
затрудняют изучение языка и мешают вашей работе, есливы ими
не собираетесь пользоваться. Поэтому С, в котором нет ни-чего лишнего, популярен
среди широкого круга программистов. Соот-ветствующие библиотеки могут добавить
к средствам языка специали-зированные функции для работы со строками, файлами,
списками, ус-тройствами ввода-вывода, математическими объектами и т.д. Остает-ся
только выбрать то, что нужно лично вам. Заголовочные файлы об-легчают использование
библиотек, предоставляют полезные типы дан-ных, глобальные переменные,
макроопределения... Они во многом ус-траняют противоречие между эффективностью
программы и удобствомиспользования библиотечных функций. Они также позволяют
не повто-рятся и не писать по нескольку раз одно и тоже в различных прог-раммах.
Поскольку С был создан специально для системного програм-мирования, он имеет
возможности низкого уровня, позволяющие "иг-рать без правил". В зависимости от
устройства и операционной сис-темы вашей машины вы можете "влезть" в видеопамять
или использо-вать системные программы, находящиеся в оперативной памяти. В любом
случае вы можете рассматривать код собственной прог-раммы как данные, а массив
данных как код функции, квадратнуюматрицу как вектор, а текст как бинарное
дерево. Что бы ни нахо-дилось в памяти - это всего лишь последовательная цепочка
чисел.Если вы не боитесь риска - можете делать все, что вам вздумается. Современные
прграммисты выбирают С не только из-за его преи-муществ. В настоящее время
мы имеем дело с цепной реакцией: чембольше написано на С, тем больше на нем
напишут еще. Это одна изпричин, почему язык С++ сохраняет С в качестве подмножества.
По мнению автора С++, Бьерна Страуструпа, различие междуидеологией С и С++
заключается примерно в следующем: программ наС отражает "способ мышления" процессора,
а С++ - способ мышленияпрограммиста. Отвечая требованиям современного
программирования,С++ делает акцент на разработке новых типов данных, наиболее
пол-но соответствующих концепциям выбранной области знаний и задачамприложения.
На С пишут библиотеки функций, С++ позволяет созда-вать библиотеки классов. Класс
является ключевым понятием С++.Описание класса содержит описание данных, требующихся
для пред-ставления объектов этого типа, и набор операций для работы с
по-добными объектами. В отличие от традиционных структур С или Паскаля, членамикласса
являются не только данные, но и функции. Функции-членыкласса имеют привилегированный
доступ к данным внутри объектовэтого класса и обеспечивают интерфейс
между этими объектами и ос-тальной программой. При дальнейшей работе совершенно
не обяза-тельно помнить о внутренней структуре класса и мехагизме работы"встроенных
функций". В этом смысле класс подобен электрическомуприбору - мало кто
знает о его устройстве, но все знают, как импользоваться. Часто в целях повышения
эффективности и упрощения структурыпрограммы приходится заставлять ее работать
с разнородными объек-тами так, как если бы они имели один и тотже тип. Например,
ок-ружность и квадрат естественно рассматривать как варианты геомет-рической
фигуры. Полезно составлять списки фигур, нарисованных наэкране, или функций,
которые их размножают, двигают и т.д. О точ-ном типе объекта приходится порой
забывать. Список геометричес-ких фигур "не знает", что в нем находится - отрезки
или звездоч-ки. Не знает этого и компилятор. Но все время, пока вы рисуетеэти
объекты, неизбежно приходится "помнить", что они из себяпредставляют. Конечно,
возможности низкого уровня позволяют "за-бывать" и "вспоминать" когда и как
нам заблагорассудится, но приэтом компилятор теряет контроль над осмысленностью
действий. Использование производных классов и виртуальных функций поз-воляет избежать
рискованной техники и не заботится о том, в ка-кой форме объект типа "геометрическая
фигура" хранит информацию отом, круг он или квадрат. (Кроме возможностей
ООП, создание ти-пов данных "треугольник" или "квадрат" как производные
от базово-го класса "геометрическая фигура" отражает логическую связь поня-тий).
Виртуальные функции, по существу, определяют, что именноможно делать с объектом,
а не то, как это делать. Создавая класс"геометрическая фигура", мы можем
включить в него виртуальныефункции рисования, увеличения, поворота. С использованием
этихфункций можно создать еще один член класса. Затем можно разработать библиотеку
программ интерактивнойграфики, снабдив ее средствами диалого, функциями
вроде дополне-ния некоторой области экрана одинаковыми геометрическими фигура-ми
и т.д. Библиотечные функции будут вызывать функции-члены клас-са "геометрическая
фигура": рисования, движения, поворота,увели-чения. А после того, как мы
все это напишем, откомпилируем, спря-чем текст функций, которые считаем своей
интеллектуальной соб-ственностью, начинается самое интересное. Теперь мы можем
опи-сать сколько угодно новых типов фигур - многоугольников, звездо-чек, эллипсов
- производных от класса "геометрическая фигура" иобъяснить, как их рисовать,
увеличивать и поворачивать. Как дви-гать - объяснять не надо. Это уже есть в базовом
классе. Функциинашей библиотеки могут работать собъектами вновь созданных
типов,для них это варианты геометричесой фигуры. Следует отметить, чтов производных
классах могут (и, как правило, должны) появлятсяданные и функции, которых
нет в базовом классе. Однако ни одна изфункций, обрабатывающих "геометрические
фигуры", никогда не уз-нает о специфических свойствах многоугольника или эллипса,
крометого, что они по-своему рисуются, увеличиваются и поворачиваются.Производный
класс сам может быть базовым для других классов, апоздние версии С++ позволяют
сделать один класс производным отнескольких других. При написании программы
часто допускаются досадные оплошнос-ти, обнаруживающиеся только на стадии выполнения
и, увы, слишкомпоздно. Например, если переменная по смыслу - знаменатель
дроби,хотелось бы получить сообщение об ошиюке тогда, когда ей присваи-вается
ноль, а не тогда, когда на этот ноль что-нибудь делится.Или, скажем, функция
рисования точки. Невозможно удержаться отсоблазна вызвать ее хотя бы раз без проверки
выхода за границыэкрана. В то же время , если мы пишем программу рисования
линии,обязательно нужна функция, которая тупо ставит точку - и как мож-но быстрее.
Существует много ситуаций, когда функции и данныеследует разрешить использовать
только привилегированным функциям,над которыми ва "хорошо подумали". В
С++ этого можно добиться,сделав "опасные" данные и функции защищенными членами
какого-ни-будь класса. К ним имеют доступ только функции-члены этого жекласса,
а так же друзья класса. Напротив, если данные или фун-кции-члены объявлены public,
они являются общедоступными. С++ предоставляет в распоряжение программиста
сложные типыданных. Однако ни аппарат классов, ни перегрузка операций невлияют
на эффективность. То, что класс - это класс, известнотолько компилятору. Если
функции-члены классов объявлены inline,на их вызов не требуется время. Фактически
это не функции, а под-становки. Лишь виртуальные функции оставляют относительно
не-большой след в оперативной памяти. Из всего выше сказанного вытекает логичный
вывод: С++ наибо-лее удобный, универсальный и необходимый язык. Но все же
возни-кает вопрос, что же было написано на этом языке, используя прин-ципы ООП,
что можно было бы "потрогать" любому программисту илипользователю. Ответ очевиден
- это Microsoft Windows.MS Windows и новый метод разработки программ. Одним
из наиболее важных механизмов взаимодействия программявляется обмен данными.
В MS Windows существует несколько способоввзаимодействия приложений: - почтовый
ящик; - динамический обмен данными; - встраивание объектов. Специальный почтовый
ящик (clipboard) Windows позволяетпользователю переносить информацию из одного
приложения в другое,не заботясь об ее форматах и представлении. В отличие от
профессиональных операциональных операционныхсистем, где механизм обмена данными
между программами доступентолько программисту, в Windows это делается очень
просто и наг-лядно для пользователя. Механизм обмена данных между приложениями
- жизненно важноесвойство многозадачной среды. И в настоящее время производителипрограммного
обеспечения пришли уже к выводу, что для переносаданных из одного
приложения в другое почтового ящика уже недоста-точно. Появился новый, более
универсальный механизм - OLE (Object Linking and Embedding ) - Встроенная объектная
связь, который позволяет пе-реносить из одного приложения в другое разнородные
данные. Напри-мер, с помощью этого механизма данные, подготовленные в системесетевого
планирования Time Line for Windows ( Symantec ), можнопереносить в текстовый
процессор Just Write ( Symantec ), а за-тем, скажем, в генератор приложений
Object Vision (Borland).Правда, это уже нестандартное средство Microsoft
Windows, но темне менее реализация OLE стала возможной именно в Windows. Кроме
механизма почтового ящика, предназначенного, в основ-ном, для пользователя, программисту
в Windows доступны спе-циальные средства обмена данными между приложениями.
Программным путем можно установить прямую связь между зада-чами, например,
принимая данные из последовательного порта, авто-матически помещать их, скажем,
в ячейки электронной таблицыExcel, средствами которой можно тут же отображать
сложные зависи-мости в виде графиков или осуществлять их обработку в реальномрежиме
времени (этот механизм носит название динамического обме-на данными - Dynamic
Data Exchange, DDE ). Основные термины Клиентское приложение DDE - приложение,
которому необходи-мо установить диалог с сервером и получить данные от
сервера впроцессе диалога. DDE-диалог - взаимосвязь между клиентским и серверным
при-ложениями. Сервер-приложение - DDE приложение, которое передает дан-ные клиенту
в процессе диалога. DDE-Транзакция -обмен сообщениями или данными между
клиен-том и сервером. Item имя - строка, идентифицирующая некоторое множестводанных,
которое сервер в состоянии передать клиенту в процесседиалога. Service имя
- строка, генерируемая сервером и используе-мая клиентом для установления диалога.
Строковый указатель - двойное слово, генерируемое опера-ционной системой,
идентифицирующее строку, передающуюся в процес-се динамического обмена данными.
Topic имя - строка, которая идентифицирует тип данных,необходимых клиентскому
приложению при динамическом обмене данных. Фильтр транзакции - флаг, который препятствует
передаченежелательных типов транзакций в функцию обратного вызова.
В Microsoft Windows динамический обмен данных является фор-мой связи, которая использует
общие области памяти для обменаданными между приложениями. Приложение
может использовать DDE внекоторый момент времени для передачи и получения новых
данных отсервера. Механизм DDE схож с механизмом почтового ящика, который яв-ляется
частью операционной системы WINDOWS. Существует лишь нез-начительная разница
в том, что почтовый ящик, в большинстве слу-чае, используется как буфер временного
хранения информации. DDEможет быть инициализирован пользователем и в большинстве
случаевпродолжать работать без его вмешательства. Библиотека DDEML обеспечивает
пользователя набором средств,которые упрощают использование механизма
DDE в WINDOWS приложе-ниях. Вместо того, чтобы обрабатывать, получать и передавать
DDEсообщения напрямую, приложения используют функции DDEML библиоте-ки. Библиотека
DDEML также обеспечивает работу со строками и раз-деляемыми данными,
генерируемыми DDE приложениями. Вместо того,чтобы использовать указатели на общие
области памяти, DDE прило-жения создают и обмениваются строковыми указателями,
которыеидентифицируют строки и данные. Уже существующие приложения, использующие
протокол DDE, ос-нованный на сообщениях полностью совместимы с теми, которые
ис-пользуют библиотеку DDEML. Вот почему приложение, использующееDDE-протокол
могут установить диалог и выполнять транзакции сприложениями, использующими библиотеку
DDEML. Взаимосвязь между клиентом и сервером. DDE возникает всегда между
клиентским приложением и сервер-ным. Клиентское приложение инициализирует обмен
данными путем ус-тановления диалога с сервером и передачи транзакции. Транзакциянеобходима
для данных и обслуживания. Сервер отвечает на транзак-цию и обеспечивает
клиента данными. Сервер может иметь сразу нес-колько клиентов в одно
и тоже время, в свою очередь, клиент мо-жет получать данные сразу от нескольких
серверов. Некоторое при-ложение одновременно может быть и клиентом и сервером.
В добавокк вышесказанному, клиент и сервер могут оборвать диалог в любоеудобное
для них время. DDE сервер использует три зарезервированных типа имен, рас-положенных
иерархично: service, topic item - уникально идентифи-цируют некоторое
множество данных, которое сервер может передатьклиенту в процессе диалога. Service
имя - это строка, которую генерирует сервер в тепромежутки времени, в которые
клиент может установить диалог ссервером. Topic имя - это строка, которая идентифицирует
логичес-кий контекст данных. Для сервера, который манипулирует файлами,topic
имена это просто названия файлов; для других серверов - этоспецифические
имена конкретного приложения. Клиент обязательнодолжен указывать topic имя
вместе с service именем, когда он хо-чет установить диалог с сервером. Item имя
- это строка, которая идентифицирует некото-рое множество данных, которое сервер
может передать клиенту впроцессе транзакции. Например, item имя может идентифицироватьЦЕЛОЕ
( int, integer ), СТРОКУ ( string, char * ), несколько па-раграфов
текста, или BITMAP образ. Все вышеуказанные имена позволяют клиенту установить
диа-лог с сервером и получить от него данные. Системный режим Системный режим
работы обеспечивает клиента всей необходи-мой информцией о сервере. Для того,
чтобы определить, какие серверы доступны в дан-ный момент времени, а также какой
информацией они могут обеспе-чить клиента, последний, находясь в начальном
режиме работы, дол-жен установить имя устройства, равное NULL. Такой шаблон диалогамаксимально
увеличивает эффективность работы, а также работу ссервером в системном
режиме. Сервер, в свою очередь, должен под-держивать нижеописанные item
имена, а также другие, часто ис-пользуемые клиентом: SZDDESYS ITEM TOPICS - список
item имен, с которыми можетработать сервер в данный момент времени. Этот
список может изме-няться время от времени. SZDDESYS ITEM SYSITEMS - список item
имен, с которыми мо-жет работать сервер в системном режиме. SZDDDESYS ITEM STATUS
- запросить текущий статус сервера.Обычно, данный запрос поддерживается только
в формате CF_TEXT исодержит строку типа Готов/Занят. SZDDE ITEM ITEMLIST -
список item имен, поддерживаемых сер-вером в несистемном режиме работы. Этот список
может менятьсявремя от времени. SZDDESYS ITEM FORMATS - список строк, представляющий
собойсписок всех форматов почтового ящика, поддерживаемых сервером
вданном диалоге. Например, CF_TEXT формат представлен строкой TEXT. Основное назначение
и работа функции обратного вызова Приложение, которое использует DDEML,
должно содержать фун-кцию обратного вызова, которая обрабатывает события, полученныеприложением.
DDEML уведомляет приложение о таких событиях путемпосылки транзакций
в функцию обратного вызова данного приложения. В зависимости от флага
фильтра транзакции, сформированногопри вызове функции DdeInitialize, функция обратного
вызова полу-чает отсортированные транзакции вне зависимости от того, являет-ся
ли данное приложение клиентом, сервером или тем и другим од-новременно.
Следующий пример демонстрирует наиболее типичное ис-пользование функции обратного
вызова. HDDEDATA CALLBACK DdeCallback( uType, uFmt, hconv, hsz1,hsz2, hdata,
dwData1, dwData2 ) UINT uType; // Тип транзакции UINT uFmt; // Формат почтого
ящика HCONV hconv; // Идентификатор диалога HSZ hsz1; // Идентификатор строки
#1 HSZ hsz2; // Идентификатор строки #2 HDDEDATA hdata; // Идентификатор глобального
объек- та памяти DWORD dwData1; // Данные текущей транзакции #1 DWORD dwData2;
// Данные текущей транзакции #2 { switch (uType) { case XTYP_REGISTER: case
XTYP_UNREGISTER: . . . return (HDDEDATA) NULL; case XTYP_ADVDATA: . . . return
(HDDEDATA) DDE_FACK; case XTYP_XACT_COMPLETE: . . . return (HDDEDATA) NULL;
case XTYP_DISCONNECT: . . . return (HDDEDATA) NULL; default: return (HDDEDATA)
NULL; } } Параметр uType идентифицирует тип посланной транзакции вфункцию обратного
вызова при помощи DDEML. Значения оставшихсяпараметров зависят от типов транзакции.
Типы транзакций будут об-суждены нами в разделе "Обработка Транзакций".
Диалог между приложениями Диалог между клиентом и сервером всегда устанавливается
потребованию клиента. Когда диалог установлен, оба партнера полу-чают идентификатор,
который описывает данный диалог. Партнеры используют этот идентификатор
в большинстве фун-кций DDEML для посылки транзакций и для их обработки. Клиенту
мо-жет потребоваться диалог как с одним сервером, так и с нескольки-ми.
Рассмотрим подробно как приложение устанавливает диалог иполучает информацию о уже
существующих каналах связи. Простой Диалог Клиентское приложение устанавливает
простой диалог с серве-ром путем вызова функции DdeConnect и определяет идентификаторыстрок,
которые содержат всю необходимую информацию о service име-ни текущего
сервера и интересущем клиента в данный момент topicимени. DDEML отвечает
на вызов этой функции посылкой соответствую-щей транзакции XTYP_CONNECT в функцию
обратного вызова каждогодоступного в данный момент времени сервера, зарегистрированноеимя
которого совпадает с именем, переданным при помощи функцииDdeConnect
при условии, что сервер не отключал фильтр serviceимени вызовом функции DdeServiceName.
Сервер может также установить фильтр на XTYP_CONNECT тран-закцию
заданием соответствующего флага CBF_FAIL_CONNECTIONS привызове функции DdeInitialize.
В процессе обработки транзакции типа XTYP_CONNECT DDEML пе-редает полученные
от клиента service и topic имена серверу. Сер-вер должен проверить эти имена
и возвратить TRUE, если он в сос-тоянии работать с такими именами, и FALSE
в противном случае.Если ни один из существующих серверов не отвечает на CONNECT-зап-рос
клиента, функция DDeConnect возвращает ему NULL с информа-цией о том,
что в данный момент времени НЕ возможно установитьдиалог. Однако, если сервер возвратил
TRUE, то диалог был успешноустановлен и клиент получает идентификатор
диалога - двойное слово, посредством которого и ведетсяобмен данными с сервером.
Затем сервер получает транзакцию вида XTYP_CONNECT_CONFIRM(в случае, если он
НЕ описывал флаг фильтра CBF_FAIL_CONFIRMS привызове соответствующей функции).
В нижеприведенном примере производится попытка установитьдиалог с сервером, который
в состоянии работать с service именем'My Server' в системном режиме. Считаем,
что параметрыhszSysTopic и hszServName уже предварительно созданы нами ранее.
HCONV hConv; HWND hwndParent; HSZ hszServName; HSZ hszSysTopic; . . . hConv
= DdeConnect( idInst, // Копия приложения hszServName, // Идентификатор service-имени
handle hszSysTopic,// Идентификатор system-topic-имени (PCONVCONTEXT) NULL);
// Используем контекст по умолчанию if( hConv == NULL ) { MessageBox( hwndParent,
"MyServer НЕ доступен!", (LPSTR) NULL, MB_OK ); return FALSE; } . . .
В этом примере функция DdeConnect заставляет DDEML посы-лать транзакцию вида XTYP_CONNECT
в функцию обратного вызова сер-вера MyServer. А теперь приведем пример
функции обратного вызова сервера,который обрабатывает транзакцию XTYP_CONNECT
и сравнивает своезарегистрированное имя с именем, полученным от клиента. Как
ужебыло отмечено ранее, если они совпадают, то сервер в состоянииустановить диалог
с клиентом. #define CTOPICS 5 HSZ hsz1; // Идентификатор строки, полученный
от DDEML. HSZ ahszTopics[CTOPICS]; // Массив поддреживаемых topic имен int i;
// Счетчик цикла . . // Для обработки транзакций используем стандартную ANSI C
. // конструкцию switch --> case --> default. . case XTYP_CONNECT: for (i = 0; i
AM , 1 --> PM } TIME; HDDEDATA EXPENTRY DdeCallback (uType, uFmt, hconv, hsz1,
hsz2, hdata, dwData1, dwData2) UINT uType; UINT uFmt; HCONV hconv; HSZ hsz1;
HSZ hsz2; HDDEDATA hdata; DWORD dwData1; DWORD dwData2; { CHAR szBuf[32]; switch
(uType) { case XTYP_ADVREQ: case XTYP_REQUEST: if ((hsz1 == hszTime &hsz2 == hszNow)
&(uFmt == CF_TEXT)) { // Копируем строку в буфер. itoa(tmTime.hour, szBuf,
10); lstrcat(szBuf, ":"); if (tmTime.minute DDE-->OLE является продолжением
воплощенияидеи "сам изобрел - сам внедряй". Естесственно, наибольшие на-дежды сейчас
возлагаются на OLE (ее новый стандарт OLE.2), так какэтот стандарт позволяет
включать в себя очень мощные средства, такиекак Multimedia. В одном файле может
находится не только текст,рисунок, а и даже целый фильм, полностью озвученный
и готовыйк показу.СПИСОК ЛИТЕРАТУРЫ 1. Гладков С.А. Фролов Г.В. Программирование
в Microsoft Windows: В 2-х частях. М.:"ДИАЛОГ-МИФИ", 1992. 2. Фойц С. Windows
3.1 для пользователя. Пер. с немецкого Киев:BHV, 1992. 3. Microsoft Windows
Software Development Kit. Version 3. Programmer's Reference, Programming Tools,
Windows Extensions. 4. Charles Petzold. Programming Windows. Microsoft Press.
5. Библия Windows 3.X. М.: И.В.К. - Софт, 1992. 6. Borland C++. Usres manual.Приложение
1. Пример использования OLE технологии// ObjectWindows - (C) Copyright
1992 by Borland International//// oleclnt.cpp// Пример Ole Client программы,
испльзующей OWL. Она показывает// пример использования Ole functions, и C++ классов
.// Основное окно позволяет пользователю создать paint brush// object, или
копировать его из clipboard.#include #include #include #include #include #include
#include #include #pragma hdrstop#include "oleclnte.h"#include "oleclntr.h"#include
"oleclnt.h"// статические данные классаLPOLECLIENTVTBL TOwlClient::lpClientVtbl
= NULL;int TOleDocWindow::nNextObjectNum = 0;void TOleApp::InitInstance(){
TApplication::InitInstance(); vcfLink = RegisterClipboardFormat( "ObjectLink"
); vcfNative = RegisterClipboardFormat( "Native" ); vcfOwnerLink = RegisterClipboardFormat(
"OwnerLink" ); // comments in owlole.h mention these ole clipboard
formats}// описание функций OWL Object, которые// позволяют хранить описание
Ole Objectint FAR PASCAL _export StdCallBack(LPOLECLIENT lpClient, OLE_NOTIFICATION
notification, LPOLEOBJECT lpObject ){ return (( PTOwlClient )lpClient)->TOleDocWindowThis->
CallBack( lpClient , notification, lpObject );}TOwlClient::TOwlClient(
PTOleDocWindow owner , HINSTANCE hInst ){ TOleDocWindowThis = owner;
if ( !lpClientVtbl ) { lpClientVtbl = new OLECLIENTVTBL; if ( hInst == 0 )
{ lpClientVtbl->CallBack = StdCallBack; } else { lpClientVtbl->CallBack = (TCallBack)MakeProcInstance(
(FARPROC)StdCallBack, hInst ); } } lpvtbl = lpClientVtbl;}void
TOleDocWindow::WMURedraw( RTMessage ){ bObjectLoaded = TRUE; InvalidateRect(
HWindow, NULL, TRUE ); UpdateWindow( HWindow );}#pragma argsusedint TOleDocWindow::CallBack(
LPOLECLIENT lpOleClient ,OLE_NOTIFICATION oleNot,LPOLEOBJECT
lpOleObject ){ switch ( oleNot ) { case OLE_CHANGED: case OLE_SAVED: PostMessage(
HWindow , WM_U_REDRAW, 0, 0L ); break; case OLE_CLOSED: break; case OLE_QUERY_PAINT:
break; case OLE_RELEASE: break; case OLE_RENAMED: break; default:
break; } return TRUE;}void TOleDocWindow::CMAbout( RTMessage ){ MessageBox( HWindow
, "OLE Client Program\nWritten using ObjectWindows\nCopyright (c) 1992 Borland",
GetApplication()->Name, MB_OK );}// создание новой paint brushvoid TOleDocWindow::CMPBrush(
RTMessage ){ BackupObject(); bObjectLoaded = FALSE; lstrcpy(
lpszObjectName, GetNextObjectName() ); ret = OleCreate( "StdFileEditing", (LPOLECLIENT)pOwlClient,
"PBRUSH", lhClientDoc, GetApplication()->Name, &pObject,
olerender_draw, 0 ); // Создание Ole Object - асинхронная операция. // Необходимо
ожидать его создание, иначе // могут возникнуть ошибки при обработке // сообщений
этого объекта. wait( ret , lpObject ); // OleSetHostNames устанавливает имя
в сервере OLE. ret = OleSetHostNames( lpObject, GetApplication()->Name,lpszObjectName
); wait( ret , lpObject );}void TOleDocWindow::CMUndo( RTMessage msg){
if ( lpUndoObject ) if ( lpUndoObject != lpObject ) { LPOLEOBJECT lpObjectToDelete
= lpObject; lpObject = lpUndoObject; lpUndoObject = NULL; ret = OleDelete(
lpObjectToDelete ); wait( ret , lpObjectToDelete ); bObjectLoaded = bUndoObjectLoaded;
WMURedraw( msg ); }}void TOleDocWindow::CMCut( RTMessage msg){ CMCopy(
msg ); CloseCurrentOle();}void TOleDocWindow::CMCopy( RTMessage ){ if ( OpenClipboard(
HWindow ) &EmptyClipboard() ) { ret = OleCopyToClipboard( lpObject );
check( ret ); CloseClipboard(); }}void TOleDocWindow::BackupObject(){ if ( lpObject
) { ret = OleClone( lpObject, (LPOLECLIENT)pOwlClient, lhClientDoc, GetApplication()->Name,
&pUndoObject ); wait( ret, lpObject ); lstrcpy( lpszLastObjectName,
lpszObjectName ); lstrcpy( lpszObjectName , GetNextObjectName() ); bUndoObjectLoaded
= bObjectLoaded; }}void TOleDocWindow::CMPaste( RTMessage ){ if (
OpenClipboard( HWindow ) ) { BackupObject(); lstrcpy( lpszObjectName, GetNextObjectName()
); ret = OleCreateFromClip( "StdFileEditing", (LPOLECLIENT)pOwlClient,
lhClientDoc, lpszObjectName, &pObject, olerender_draw, 0 ); check( ret ); ret
= OleSetHostNames( lpObject, GetApplication()->Name, lpszObjectName ); wait(
ret , lpObject ); bObjectLoaded = TRUE; CloseClipboard(); PostMessage( HWindow
, WM_U_REDRAW, 0, 0L ); }}LPSTR TOleDocWindow::GetNextObjectName(){ static char
buffer[ MAXPATH ]; wsprintf( buffer, "object #%03d", nNextObjectNum++ ); return
buffer;}void TOleDocWindow::Paint( HDC hdc, PAINTSTRUCT _FAR )
{
LPOLEOBJECT
lpObjectToDraw = NULL; if ( bObjectLoaded ) lpObjectToDraw = lpObject; else if
( lpUndoObject ) lpObjectToDraw = lpUndoObject; if ( lpObjectToDraw ) { RECT rect;
GetClientRect( HWindow, rect);// Замечание по OleDraw:// OleDraw должен возвращать
OLE_ERROR_OBJECT, если// object был нарисован неверно. ret = OleDraw( lpObjectToDraw
, hdc, rect, NULL, 0 ); wait( ret, lpObjectToDraw ); }}TOleDocWindow::TOleDocWindow(
PTWindowsObject parent, LPSTR title ) : TWindow( parent, title
){ ret = OLE_OK; lhClientDoc = 0; bObjectLoaded = FALSE; bUndoObjectLoaded
= FALSE; bUndoObjectLoaded = FALSE; pOwlClient = NULL; lpObject = NULL; lpUndoObject
= NULL; strcpy( lpszDocName , "noname.ole" ); *lpszLastObjectName = 0; *lpszObjectName
= 0; bDefDocName = TRUE;}void TOleDocWindow::SetupWindow() { TWindow::SetupWindow();
RegisterClientDoc(); pOwlClient = new TOwlClient( this );}void
TOleDocWindow::RegisterClientDoc() { ret = OleRegisterClientDoc( GetApplication()->Name,
lpszDocName, 0, &hClientDoc ); check( ret );}void TOleDocWindow::ShutDownWindow(){
CloseCurrentOle(); if ( pOwlClient ) delete pOwlClient; TWindow::ShutDownWindow();}void
TOleDocWindow::RegFileName( LPSTR FileName ){ lstrcpy(
lpszDocName , FileName ); ret = OleRegisterClientDoc( GetApplication()->Name,
lpszDocName , 0, &hClientDoc ); check ( ret );}void TOleDocWindow::CMActivate(
RTMessage ){ BackupObject(); RECT rect; GetClientRect( HWindow, rect); ret =
OleActivate( lpObject , OLEVERB_PRIMARY, TRUE, TRUE , HWindow , rect); wait ( ret,
lpObject ); PostMessage( HWindow , WM_U_REDRAW, 0, 0L );}void TOleDocWindow::WMInitMenu(
RTMessage msg ){ HMENU hMenu = (HMENU)msg.WParam; WORD wEnableUndo;
if ( (lpObject != lpUndoObject) &
( lpUndoObject != NULL )) wEnableUndo = MF_ENABLED;
else wEnableUndo = MF_GRAYED; EnableMenuItem( hMenu, CM_UNDO , wEnableUndo
); EnableMenuItem( hMenu, CM_COPY , ( bObjectLoaded ? MF_ENABLED : MF_GRAYED
)); EnableMenuItem( hMenu, CM_CUT , ( bObjectLoaded ? MF_ENABLED : MF_GRAYED
)); ret = OleQueryCreateFromClip( "StdFileEditing", olerender_draw, 0 ); EnableMenuItem(
hMenu, CM_PASTE , (( ret == OLE_OK ) ? MF_ENABLED : MF_GRAYED ));
EnableMenuItem( hMenu, CM_ACTIVATE , ( bObjectLoaded ? MF_ENABLED : MF_GRAYED ));
EnableMenuItem( hMenu, CM_CLEAR , ( bObjectLoaded ? MF_ENABLED : MF_GRAYED ));
DrawMenuBar( HWindow );}LPSTR TOleDocWindow::GetClassName() { return "OLEDOCWINDOW";
}void TOleDocWindow::GetWindowClass(WNDCLASS _FAR wc){ TWindow::GetWindowClass(
wc ); wc.lpszMenuName = "MENU_DOCWINDOW";}void TOleDocWindow::CMClear(
RTMessage ){ CloseCurrentOle();}void TOleDocWindow::CloseCurrentOle(){ // окончательное
сохранение if ( lpObject ) { ret = OleDelete( lpObject ); wait( ret ,
lpObject ); } if ( lpUndoObject ) { ret = OleDelete( lpUndoObject ); wait( ret
, lpObject ); } lpObject = lpUndoObject = NULL; bObjectLoaded = FALSE; InvalidateRect(
HWindow , NULL, TRUE ); UpdateWindow( HWindow );}void TOleApp::InitMainWindow(){
MainWindow = new TOleDocWindow(NULL, "OWL OLE Application" );}int PASCAL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmd, int nCmdShow){
TOleApp OleApp ("OleApp", hInstance, hPrevInstance, lpCmd, nCmdShow);
OleApp.Run(); return (OleApp.Status);}


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.

Сейчас смотрят :

Реферат Расчет основных технико экономических показателей работы участка цеха машиностроительного предприятия
Реферат Сутність та характеристика об`єктів нерухомості
Реферат Теория поля К.Левин
Реферат America The Myth Of Equality Essay Research
Реферат Тема Родины в творчестве Ф.Абрамова
Реферат Разработка автоматизированной информационной системы Система учета ОАО ЮТК
Реферат Куусинен, Отто Вильгельмович
Реферат Психологическая культура юриста
Реферат Практический маркетинг на примере сети магазинов "Обувной мир"
Реферат Теория деятельности А.Н.Леонтьев
Реферат Білети 6
Реферат Cпециальные физические упражнения лечебной физической культуры при заболеваниях желчевыводящих путей
Реферат Преодоление последствий посттравматического стрессового расстройства у участников боевых действий, получивших ранения и увечья, с помощью метода психологического дебрифинга
Реферат Теория личностных конструктов Дж.А.Келли
Реферат Темперамент личности