ЗМІСТ
Передмова 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 ProgramnWritten using ObjectWindowsnCopyright (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);)