GeoSELECT.ru



Программирование / Реферат: Протокол HDLC (Программирование)

Космонавтика
Уфология
Авиация
Административное право
Арбитражный процесс
Архитектура
Астрология
Астрономия
Аудит
Банковское дело
Безопасность жизнедеятельности
Биология
Биржевое дело
Ботаника
Бухгалтерский учет
Валютные отношения
Ветеринария
Военная кафедра
География
Геодезия
Геология
Геополитика
Государство и право
Гражданское право и процесс
Делопроизводство
Деньги и кредит
Естествознание
Журналистика
Зоология
Инвестиции
Иностранные языки
Информатика
Искусство и культура
Исторические личности
История
Кибернетика
Коммуникации и связь
Компьютеры
Косметология
Криминалистика
Криминология
Криптология
Кулинария
Культурология
Литература
Литература : зарубежная
Литература : русская
Логика
Логистика
Маркетинг
Масс-медиа и реклама
Математика
Международное публичное право
Международное частное право
Международные отношения
Менеджмент
Металлургия
Мифология
Москвоведение
Музыка
Муниципальное право
Налоги
Начертательная геометрия
Оккультизм
Педагогика
Полиграфия
Политология
Право
Предпринимательство
Программирование
Психология
Радиоэлектроника
Религия
Риторика
Сельское хозяйство
Социология
Спорт
Статистика
Страхование
Строительство
Схемотехника
Таможенная система
Теория государства и права
Теория организации
Теплотехника
Технология
Товароведение
Транспорт
Трудовое право
Туризм
Уголовное право и процесс
Управление
Физика
Физкультура
Философия
Финансы
Фотография
Химия
Хозяйственное право
Цифровые устройства
Экологическое право
   

Реферат: Протокол HDLC (Программирование)



Содержание:

|Техническое задание |2 |
| | |
|Введение |3 |
| | |
|Глава 1. Теоретическая часть | |
| | |
| Выбор языка |4 |
|программирования | |
| Понятие протокола |5 |
|канального уровня | |
| Обзор протокола HDLC |6 |
| | |
|Глава 2. Программная часть | |
| | |
| Описание алгоритма работы |13|
|программы | |
| Описание интерфейса |15|
| | |
|Заключение. |17|
| | |
|Список используемой литературы. |18|
|Приложение. |19|



Техническое задание

Разработать программу имитации передачи информации через протокол
канального уровня HDLC.
Введение


HDLC - протокол высокоуровнего управления каналом передачи данных,
является опубликованным ISO стандартом и базовым для построения других
протоколов канального уровня (SDLC, LAP, LAPB, LAPD, LAPX и LLC). Он
реализует механизм управления потоком посредством непрерывного ARQ
(скользящее окно) и имеет необязательные возможности (опции),
поддерживающие полудуплексную и полнодуплексную передачу, одноточечную и
многоточечную конфигурации, а так же коммутируемые и некоммутируемые
каналы.
Выбор языка программирования

Потребность в разработке и применении эффективных и адекватных
реальной действительности компьютерных программ и технологий сегодня
возрастает. Компьютерная технология незаменима, поскольку она даёт
возможность оптимизировать и рационализировать управленческую функцию за
счет применения новых средств сбора, передачи и преобразования информации.
Выпускная работа написана в программной среде Delphi. Это наводит на
вопрос, а почему выбран именно этот язык программирования?
Delphi обладает широким набором возможностей, начиная от
проектировщика форм и кончая поддержкой всех форматов популярных баз
данных. Среда устраняет необходимость программировать такие компоненты
Windows общего назначения, как метки, пиктограммы и даже диалоговые панели.
Работая в Windows , вы неоднократно видели одинаковые «объекты» во многих
разнообразных приложениях. Диалоговые панели (например, Choose File и Save
File) являются примерами многократно используемых компонентов, встроенных
непосредственно в Delphi, который позволяет приспособить эти компоненты к
имеющийся задаче, чтобы они работали именно так, как требуется создаваемому
приложению. Также здесь имеются предварительно определенные визуальные и не
визуальные объекты, включая кнопки, объекты с данными, меню и уже
построенные диалоговые панели. С помощью этих объектов можно, например,
обеспечить ввод данных просто несколькими нажатиями кнопок мыши, не
прибегая к программированию. Та часть, которая непосредственно связана с
программированием интерфейса пользователя системой, получила название
визуальное программирование.
Визуальное программирование как бы добавляет новое измерение при
создании приложений, давая возможность изображать эти объекты на экране
монитора до выполнения самой программы. Без визуального программирования
процесс отображения требует написания фрагмента кода, создающего и
настрающего объект «по месту». Увидеть закодированные объекты было возможно
только в ходе исполнения программы. При таком подходе достижение того,
чтобы объекты выглядели и вели себя заданным образом, становится
утомительным процессом, который требует неоднократных исправлений
программного кода с последующей прогонкой программы и наблюдения за тем,
что в итоге получилось.
Благодаря средствам визуальной разработки можно работать с объектами,
держа их перед глазами и получая результаты практически сразу. Способность
видеть объекты такими, какими они появляются в ходе исполнения программы,
снимает необходимость проведения множества операций вручную, что характерно
для работы в среде, не обладающей визуальными средствами — вне зависимости
от того, является она объектно-ориентированной или нет. После того, как
объект помещен в форму среды визуального программирования, все его атрибуты
сразу отображаются в виде кода, который соответствует объекту как единице,
исполняемой в ходе работы программы.
Размещение объектов в Delphi связано с более тесными отношениями между
объектами и реальным программным кодом. Объекты помещаются в вашу форму,
при этом код, отвечающий объектам, автоматически записывается в исходный
файл. Этот код компилируется, обеспечивая существенно более высокую
производительность, чем визуальная среда, которая интерпретирует информацию
лишь в ходе исполнения программы.
Понятие протокола канального уровня.

Для создания надежного механизма передачи данных между двумя станциями
необходимо определить протокол, который позволит принимать и передавать
различные данные по каналам связи. Протоколы представляют собой просто
набор условий (пра- вил), которые регламентируют формат и процедуры обмена
информацией между двумя или несколькими независимыми устройствами или
процессами. Протокол имеет три важнейших элемента: синтаксис, семантику и
синхронизацию. Синтаксис протокола определяет поля; например, может быть 16-
байтовое поле для адресов, 32-байтовое поле для контрольных сумм и 512 байт
на пакет. Семантика протокола придает этим полям значение: например, если
адресное поле состоит из всех адресов, это "широковещательный" пакет.
Синхронизация - количество битов в секунду - это скорость передачи данных.
Она важна не только на самых низких уровнях протокола, но и на высших.

Протокол канального обеспечивает следующие функции :
. управление передачей данных через физический канал организованный
на первом уровне;
. проверка информационного канала;
. формирование кадра т.е. окаймление передаваемых данных служебными
символами данного уровня;
. контроль данных;
. обеспечение прозрачности информационного канала;
. управление каналом передачи данных;

Данный протокол занимает второй уровень в многоуровневой организации
управления сетью.



Обзор протокола HDLC


Типы, логические состояния и режимы работы станций. Способы
конфигурирования канала связи

Существует три типа станций HDLC:
Первичная станция (ведущая) управляет звеном передачи данных (каналом).
Несет ответственность за организацию потоков передаваемых данных и
восстановление работоспособности звена передачи данных. Эта станция
передает кадры команд вторичным станциям, подключенным к каналу. В свою
очередь она получает кадры ответа от этих станций. Если канал является
многоточечным, главная станция отвечает за поддержку отдельного сеанса
связи с каждой станцией, подключенной к каналу.
Вторичная станция (ведомая) работает как зависимая по отношению к первичной
станции (ведущей). Она реагирует на команды, получаемые от первичной
станции, в виде ответов. Поддерживает только один сеанс, а именно только с
первичной станцией. Вторичная станция не отвечает за управление каналом.
Комбинированная станция сочетает в себе одновременно функции первичной и
вторичной станции. Передает как команды, так и ответы и получает команды и
ответы от другой комбинированной станции, с которой поддерживает сеанс.
Три логических состояния , в которых могут находиться станции в процессе
взаимодействия друг с другом.
Состояние логического разъединения (LDS) . В этом состоянии станция не
может вести передачу или принимать информацию. Если вторичная станция
находится в нормальном режиме разъединения (NDM - Normal Disconnection
Mode), она может принять кадр только после получения явного разрешения на
это от первичной станции. Если станция находится в асинхронном режиме
разъединения (ADM - Asynchronous Disconnection Mode), вторичная станция
может инициировать передачу без получения на это явного разрешения, но кадр
должен быть единственным кадром, который указывает статус первичной
станции. Условиями перехода в состояние LDS могут быть начальное или
повторное (после кратковременного отключения) включение источника питания;
ручное управление установлением в исходное состояние логических цепей
различных устройств станции и определяется на основе принятых системных
соглашений.
Состояние инициализации (IS) . Это состояние используется для передачи
управления на удаленную вторичную/комбинированную станцию, ее коррекции в
случае необходимости, а также для обмена параметрами между удаленными
станциями в звене передачи данных, используемыми в состоянии передачи
информации.
Состояние передачи информации (ITS) . Вторичной, первичной и
комбинированным станциям разрешается вести передачу и принимать информацию
пользователя. В этом состоянии станция может находится в режимах NRM, ARM и
ABM, которые описаны ниже.
Три режима работы станции в состоянии передачи информации, которые могут
устанавливаться и отменяться в любой момент.
Режим нормального ответа (NRM - Normal Response Mode) требует, чтобы
прежде, чем начать передачу, вторичная станция получила явное разрешение от
первичной. После получения разрешения вторичная станция начинает передачу
ответа, который может содержать данные. Пока канал используется вторичной
станцией, может передаваться один или более кадров. После последнего кадра
вторичная станция должна снова ждать явного разрешения, прежде чем снова
начать передачу. Как правило, этот режим используется вторичными станциями
в многоточечных конфигурациях звена передачи данных.
Режим асинхронного ответа (ARM - Asynchronous Response Mode) позволяет
вторичной станции инициировать передачу без получения явного разрешения от
первичной станции (обычно, когда канал свободен, - в состоянии покоя). Этот
режим придает большую гибкость работы вторичной станции. Могут передаваться
один или несколько кадров данных или управляющая информация, отражающая
изменение статуса вторичной станции. ARM может уменьшить накладные расходы,
поскольку вторичная станция, чтобы передать данные, не нуждается в
последовательности опроса. Как правило, такой режим используется для
управления соединенными в кольцо станциями или же в многоточечных
соединениях с опросом по цепочке. В обоих случаях вторичная станция может
получить разрешение от другой вторичной станции и в ответ на него начать
передачу. Таким образом разрешение на работу продвигается по кольцу или
вдоль соединения.
Асинхронный сбалансированный режим (ABM - Asynchronous Balanse Mode)
используют комбинированные станции. Комбинированная станция может
инициировать передачу без получения предварительного разрешения от другой
комбинированной станции. Этот режим обеспечивает двусторонний обмен
потоками данных между станциями и является основным (рабочим) и наиболее
часто используемым на практике
Три способа конфигурирования канала для обеспечения совместимости
взаимодействий между станциями, использующих основные элементы процедур
HDLC и способных в процессе работы менять свой статус (первичная,
вторичная, комбинированная):
Несбалансированная конфигурация (UN - Unbalanced Normal) обеспечивает
работу одной первичной станции и одной или большего числа вторичных станций
в конфигурации одноточечной или многоточечной, полудуплексной или
полнодуплексной, с коммутируемым каналом и с некоммутируемым. Конфигурация
называется несбалансированной потому, что первичная станция отвечает за
управление каждой вторичной станцией и за выполнение команд установления
режима.
Симметричная конфигурация (UA - Unbalanced Asynchronous) была в исходной
версии стандарта HDLC и использовалась в первых сетях. Эта конфигурация
обеспечивает функционирование двух независимых двухточечных
несбалансированных конфигураций станций. Каждая станция обладает статусом
первичной и вторичной, и, следовательно, каждая станция логически
рассматривается как две станции: первичная и вторичная. Главная станция
передает команды вторичной станции на другом конце канала, и наоборот.
Несмотря на то, что станция может работать как в качестве первичной, так и
вторичной станции, которые являются самостоятельными логическими объектами,
реальные команды и ответы мультиплексируются в один физический канал. Этот
подход в настоящее время используется редко.
Сбалансированная конфигурация (BA - Balanced Asynchronous) состоит из двух
комбинированных станций, метод передачи - полудуплексный или дуплексный,
канал - коммутируемый или некоммутируемый. Комбинированные станции имеют
равный статус в канале и могут несанкционированно посылать друг другу
трафик. Каждая станция несет одинаковую ответственность за управление
каналом.
Управление потоком

Формат кадра HDLC

На канальном уровне используется термин кадр для обозначения независимого
объекта данных, передаваемого от одной станции к другой (рис.1).
Флаг . Все кадры должны начинаться и заканчиваться полями флага "01111110".
Станции, подключенные к каналу, постоянно контролируют двоичную
последовательность флага. Флаги могут постоянно передаваться по каналу
между кадрами HDLC. Для индексации исключительной ситуации в канале могут
быть посланы семь подряд идущих единиц. Пятнадцать или большее число единиц
поддерживают канал в состоянии покоя. Если принимающая станция обнаружит
последовательность битов не являющихся флагом, она тем самым уведомляется о
начале кадра, об исключительной (с аварийным завершением) ситуации или
ситуации покоя канала. При обнаружении следующей флаговой
последовательности станция будет знать, что поступил полный кадр.
|Формат кадра HDLC |
|Флаг |Адрес |Управляющее поле |Информационное поле |CRC |Флаг |

|Формат управляющего поля кадра HDLC |
|1 |0 |S-коды |P/F |N(R) |S-формат |
|1 |1 |U-коды |P/F |U-коды |U-формат |


Рис.1. Формат кадра и управляющего поля HDLC, где:

N(S) - порядковый номер передаваемого кадра,

N(R) - порядковый номер принимаемого кадра,

P/F - бит опроса/окончания
Адресное поле определяет первичную или вторичную станции, участвующие в
передаче конкретного кадра. Каждой станции присваивается уникальный адрес.
В несбалансированной системе адресные поля в командах и ответах содержат
адрес вторичной станции. В сбалансированных конфигурациях командный кадр
содержит адрес получателя, а кадр ответа содержит адрес передающей станции.
|Правила адресации |
|Первична|------ Команда (Адрес В) -----> |Вторична|Несбалансир|
|я | |я |. |
|станция | |станция |конфигураци|
|А | |В |я |
| | |Комбинир|Сбалансир. |
|. | |. |конфигураци|
|станция | |станция |я |
|А | |В | |
| |= msecs;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if opendialog1.Execute then
begin
kl:=true;
LabeledEdit1.Text:=OpenDialog1.FileName;
memo3.Lines.LoadFromFile(OpenDialog1.FileName);
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var st6,st5,st3,st2,st1,st,st4:string;kol,k,i,j,im:integer;f:file of
char;ch:char;
begin
if kl=true then
begin
kl:=false;
assignfile(f,OpenDialog1.filename);
reset(f);
form2.Memo3.Lines.Clear;
while not eof(f) do
begin
im:=0;
form2.Memo2.Lines.Clear;
edit3.Text:='10100000';
memo2.Lines.Add('Команда RR - готов к приему');
memo2.Lines.Add('---------------------------');
Radiogroup1.itemindex:=0;
RichEdit1.Lines.Clear;
RichEdit1.Lines.Add('011111101010010101100000000000000001111110');
RadioGroup2.ItemIndex:=1;
delay(2000);

form2.RadioGroup1.ItemIndex:=0;
form2.RadioGroup2.ItemIndex:=1;
form2.memo1.Lines.Clear;
form2.memo1.Lines.Add('011111101010010101100000000000000001111110');
form2.Show;
delay(2000);
form2.Memo1.Lines.Clear;
form2.Memo1.Lines.Add('011111101010010101110000000000000001111110');
form2.RadioGroup1.itemindex:=1;
form2.RadioGroup2.ItemIndex:=1;
delay(2000);
form2.Hide;
edit3.Text:='10101000';
memo2.Lines.Add('Ответ RR - готов к приему');
memo2.Lines.Add('-------------------------');
RichEdit1.Lines.Clear;
RichEdit1.Lines.Add('011111101010010101110000000000000001111110');
RadioGroup1.itemindex:=1;
RadioGroup2.ItemIndex:=1;

st:='';
st:='011111101010010101';
i:=0;
st3:='';
RichEdit1.Lines.Clear;
memo2.Lines.Add('Передача');
memo2.Lines.Add('-------------------------');
st4:='';
st4:=st4;
st5:='';
st6:='';
while (not eof(f))and (i case --> default.
.

case XTYP_CONNECT:
for (i = 0; i < CTOPICS; i++)
{
if (hsz1 == ahszTopics[i])
return TRUE; // Установка диалога
}

return FALSE; // Topic имя НЕ поддерживается,
диалог запрещен.
.
. // Обработка других типов транзакций.
.

Если сервер возвращает TRUE в ответ на транзакцию
XTYP_CONNECT, DDEML посылает транзакцию вида XTYP_CONNECT_CONFIRM
в функцию обратного вызова данного сервера. Обработав эту тран-
закцию, сервер может получить идендификатор диалога.
Вместо конкретного имени сервера клиент может установить
шаблон диалога путем установки идентификаторов service и topic
имен в NULL при вызове функции DdeConnect.
Если хотя бы один из вышеперечисленных идентификаторов ра-
вен NULL, DDEML посылает транзакцию типа XTYP_WILDCONNECT в фун-
кцию обратного вызова всех активных в данный момент DDE-приложе-
ний (исключения составляют лишь те, кто при вызове соответствую-
щей функции указал флаг фильтрации XTYP_WILDCONNECT).
Любое сервер-приложение должно ответить на данную транзак-
цию и возвратить указатель на массив структур типа HSZPAIR, окан-
чивающийся нулем.
Если сервер-приложение НЕ вызывает функцию DDeNameService
для регистрации собственного service имени в системе и фильтр об-
работки транзакций включен, то сервер НЕ получит транзакцию вида
XTYP_WILDCONNECT.
Вышеописанный массив должен содержать одну структуру для
каждого service и topic имен. DDEML выбирает одну пару из масси-
ва для установления диалога и возвращает его идентификатор клиен-
ту. Затем DDEML посылает серверу транзакцию вида
XTYP_CONNECT_CONFIRM (исключения составляют лишь те серверы, ко-
торые при инициализации установили фильтр обработки транзакций).
Продемонстируем использование транзакции вида XTYP_CONNECT.

#define CTOPICS 2

UINT uType;
HSZPAIR ahszp[(CTOPICS + 1)];
HSZ ahszTopicList[CTOPICS];
HSZ hszServ, hszTopic;
WORD i, j;

if (uType == XTYP_WILDCONNECT)
{
// Сканируем список topic имен и создаем мас-
сив структур типа HSZPAIR

j = 0;
for (i = 0; i < CTOPICS; i++)
{
if (hszTopic == (HSZ) NULL ||
hszTopic == ahszTopicList[i])
{
ahszp[j].hszSvc = hszServ;
ahszp[j++].hszTopic = ahszTopicList[i];
}
}

//
// Последний элемент массива всегда NULL.
//

ahszp[j].hszSvc = NULL;
ahszp[j++].hszTopic = NULL;

//
// Возвращаем дискриптор глобального объекта
// памяти,содержащий структуры типа HSZPAIR.
//

return DdeCreateDataHandle(
idInst, // Копия приложения
(LPBYTE) &ahszp, // Указатель на массив
типа HSZPAIR

sizeof(HSZ) * j, // Длина массива
0, // Начальное смещение
(HSZ) NULL, // item-имя не существует
0, // формат item-имени также
// не существует
0); // Возлагаем все работу
// с массивом на систему
}

Любой сервер или клиент может оборвать диалог в любое вре-
мя путем вызова функции DdeDisconnect. Это означает, что партнер
по обмену данными получает транзакцию типа XTYP_DISCONNECT в фун-
кции обратного вызова (если, конечно, партнер не установил фильтр
обработки транзакций вида CBF_SKIP_DISCONNECTIONS).
Обычно приложение реагирует на транзакцию XTYP_DISCONNECT
вызовом функции DdeQueryInfo для получения информации о прекра-
щенном диалоге. После того, как функция обратного вызова обрабо-
тала транзакцию типа XTYP_DISCONNECT, идентификатор диалога
больше не существует.
Клиентское приложение, которое получает транзакцию типа
XTYP_DISCONNECT в своей функции обратного вызова может попы-
таться возобновить диалог при промощи вызова функции
DdeReconnect. Клиентское приложение может вызывать эту функцию
только находясь внутри своей собственной функции обратного вызова.

Сложный диалог
Клиентское приложение может использовать функцию
DdeConnectList для того, чтобы определить какие сервер-приложе-
ния существуют в системе в данный момент времени.
Клиент обязательно должен описывать service и topic имена,
когда он вызывает эту функцию; это означает, что DDEML должна
послать транзакцию вида XTYP_CONNECT все функции обратного вызо-
ва всех имеющихся в данный момент сервер-приложений, чьи зарегис-
трированные имена совпадают с именами, указанными клиентом (ис-
ключение составляют лишь те серверы, которые фильтруют получае-
мые транзакции).
В добавление к вышесказанному, можно отметить, что клиент,
при вызове функции DdeConnectList, может указать NULL в качестве
service или topic имени, либо же сразу для обоих. Все доступные в
системе серверы, чьи зарегистрированные имена совпадают с имена-
ми, указанными клиентом, отвечают на его запрос. Диалог устанав-
ливается со всеми такими серверами, даже если в системе запущено
одно и тоже сервер-приложение несколько раз.
Клиент может использовать функции DdeQueryNextServer и
DdeQueryConvInfo для того, чтобы понять, какой сервер находится в
списке, полученный при вызове функции DdeConnectList.
DdeQueryNextServer возвращает идентификатор диалога для следующе-
го сервера, находящегося в списке; DdeQueryConvInfo заполняет
структуру CONVINFO информацией о диалоге.
Клиент может сохранить полученные идентификаторы диалогов и
отказаться от просмотра оставшихся серверов в списке.
Приведем пример использования функции DdeConnectList для
установления диалога со всеми серверами, которые поддерживают имя
'system topic', затем будем использовать функции DdeQueryConvInfo
и DdeQueryNextServer для получения их идентификаторов service
имен, одновременно не забывая сохранить последние во временном
буфере.

HCONVLIST hconvList; // Список диалогов
DWORD idInst; // Дискриптор приложения
HSZ hszSystem; // System topic
HCONV hconv = NULL; // Идентификатор диалога
CONVINFO ci; // Информация о диалоге
UINT cConv = 0; // Количество идентификаторов
диалогов
HSZ *pHsz, *aHsz; // Указатель на идентификатор
строки

// Присоединяемся ко всем серверам, поддерживающим
// System topic.
hconvList = DdeConnectList(idInst, NULL, hszSystem,
NULL, NULL);

// Вычисляем количество серверов в списке.

while((hconv = DdeQueryNextServer(hconvList,hconv))
!= NULL)
cConv++;

// Выделяем буфер для сохранения идентификаторов строк.

hconv = NULL;
aHsz = (HSZ *) LocalAlloc(LMEM_FIXED, cConv * sizeof(HSZ));

// Копируем идентификатор строки в буфер.

pHsz = aHsz;
ile((hconv = DdeQueryNextServer(hconvList,hconv)) != NULL)
{
DdeQueryConvInfo(hconv, QID_SYNC, (PCONVINFO) &ci);

DdeKeepStringHandle(idInst, ci.hszSvcPartner);
*pHsz++ = ci.hszSvcPartner;
}
.
. // Используем идентификатор: 'общаемся' с сервером.
.

// Освобождаем память и прекращаем диалог.

LocalFree((HANDLE) aHsz);
DdeDisconnectList(hconvList);

Приложение может оборвать индивидуальный диалог, находящий-
ся в списке диалогов путем вызова функции DdeDisconnect; приложе-
ние может оборвать все диалоги, находящиеся в списке путем вызо-
ва функции DdeDisconnectList.
Обе вышеуказанные функции указывают DDEML о необходимости
посылки транзакции вида XTYP_DISCONNECT во все функции партнеров
по диалогу данного приложения (в случае использования функции
DdeDisconnectList будет посылаться транзакция XTYP_DISCONNECT для
каждого элемента в списке диалогов).

Обмен данными между приложениями
Так как DDE использует области памяти для передачи данных
из одного приложения в другое, DDEML обеспечивает конечного прог-
раммиста функциями, при помощи которых DDE-приложения могут соз-
давать и обрабатывать DDE-объекты.
Весь спектр транзакций, который вызывает обмен данными,
требует от приложения, экспортирующего их, создания некоторого
буфера, содержащего эти данные, а затем вызова функции
DdeCreateDataHandle.
Эта функция создает DDE-объект, копирует данные из буфера в
этот объект и возвращает идентификатор данных для данного прило-
жения.
Идентификатор данных-это двойное слово, которое использует
DDEML для обеспечения доступа к данным в DDE-объекте.
Для того, чтобы разделять данные в DDE-объекте, приложение
передает идентификатор данных DDEML, а затем DDEML передает его в
функцию обратного вызова приложения, получающего данные.
В нижеприведенном примере показано, как создать DDE-объект
и получить его идентификатор. В процессе обработки транзакции ти-
па XTYP_ADVREQ, функция обратного вызова конвертирует текущее
время в ASCII строку, копирует строку в вспомогательный буфер, а
затем создает DDE-объект, содержащий вышеуказанную строку. Фун-
кция обратного вызова возвращает идентификатор DDE-объекта DDEML,
которая передает этот идентификатор клиентскому приложению.

typedef struct tagTIME
{
INT hour; // 0 - 11 формат времени для
часов.
INT hour12; // 12-ой формат.
INT hour24; // 24-ой формат.
INT minute;
INT second;
INT ampm; // 0 --> 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 < 10)
lstrcat(szBuf, "0");
itoa(tmTime.minute,
&szBuf[lstrlen(szBuf)], 10);
lstrcat(szBuf, ":");
if (tmTime.second < 10)
strcat(szBuf, "0");
itoa(tmTime.second,
&szBuf[lstrlen(szBuf)], 10);
szBuf[lstrlen(szBuf)] = '0';

// Создаем глобальный объект и
// возвращаем его идентификатор

return (DdeCreateDataHandle(
idInst, // копия
приложения
(LPBYTE) szBuf, // исходный
буфер
lstrlen(szBuf) + 1,
0, // смещение
от его начала
hszNow, // item-имя
CF_TEXT, // формат
почтого ящика
0));
}

else return (HDDEDATA) NULL;
.
. // Обработка других типов транзакций.
.

}
}

Клиентское приложение получает указатель на DDE-объект пу-
тем передачи идентификатора данных функции DdeAccessData. Указа-
тель, возвращаемый этой функцией, обеспечивает доступ к данным в
формате 'ТОЛЬКО НА ЧТЕНИЕ'. Клиент должен просмотреть полученные
данные при помощи этого указателя и вызвать функцию
DdeUnaccessData для его уничтожения. Клиент может скопировать по-
лученные данные в заранее приготовленный буфер посредством вызо-
ва функции DdeGetData.
В следующем примере мы получим указатель на DDE-объект,
сохраним его в параметре hData, скопируем содержимое во времен-
ный буфер и уничтожим указатель:

HDDEDATA hdata;
LPBYTE lpszAdviseData;
DWORD cbDataLen;
DWORD i;
char szData[32];

. . .

case XTYP_ADVDATA:
lpszAdviseData = DdeAccessData(hdata,
&cbDataLen);
for (i = 0; i < cbDataLen; i++)
szData[i] = *lpszAdviseData++;
DdeUnaccessData(hdata);
return (HDDEDATA) TRUE;
. . .

Обычно, когда приложение, создающее идентификатор данных,
передает его DDEML, этот идентификатор портится внутри вышеука-
занного приложения. В этом нет ничего страшного, если сервер дол-
жен разделять данные только с одним клиентом. Если же сервер дол-
жен разделять данные сразу с несколькими клиентами одновременно,
ему придется указывать флаг HDATA_APPOWNED при вызове функции
DdeCreateDataHandle.
Это делает возможным получение прав собственности на
DDE-объект сервер-приложения и предотвращает порчу идентификато-
ра данных DDEML. Приложение может передавать DDEML идентификатор
данных любое количество раз, однако вызывать функцию
DdeCreateDataHandle можно лишь однажды.
Если приложение указывает флаг HDATA_APPOWNED в параметре
atCmd при вызове функции DdeCreateDataHandle, оно обязательно
должно вызывать функцию DdeFreeDataHandle для очистки памяти вне
зависимости от того, передавался ли идентификатор данных DDEML
или нет. Перед тем как оборвать диалог, приложение должно вызы-
вать функцию DdeFreeDataHandle для очистки всех созданных иденти-
фикаторов, но которые так и не были переданы DDEML.
Если приложение еще не передало идентификатор DDE-объекта
DDEML, то оно может добавить данные к уже существующему объекту
или полностью заменить их в нем. Все эти сервисные функции обслу-
живаются функцией DdeAddData.
Обычно приложение использует эту функцию для новой инициа-
лизации старых не уничтоженных DDE-объектов. После того, как при-
ложение передает идентификатор данных DDEML, DDE-объект, иденти-
фицирующий этот идентификатор НЕ может быть изменен, однако он
может быть уничтожен.
OLE-технология

Как видно из описанного выше протокола DDE, приложения
должны обязательно знать типы передаваемых данных, уметь их обра-
батывать, а в основном даже могут работать только с символьными
строками. Это, конечно, не очень удобно, когда необходимо, напри-
мер, создать небольшой текст с различными картинками, пиктограм-
мами и другими наглядными или не очень иллюстрациями. В этом слу-
чае на помощь программисту проиходит OLE - встраивание объектов.
Вместе с данными мы получаем машинный код, который эти данные мо-
жет обрабатывать.

Способы упорядочивания, источники и целевые документы
При использовании OLE-технологии пользователь всегда имеет
дело с одним ведущим приложением (главным) и одним ведомым (под-
чиненным), а точнее, содним ведомым.
Приложение, с помощью которого получен объект для встраива-
ния всегда играет роль подчиненного. Это особенно характерно для
случаев передачи объектов при встраивании и связывании через бу-
фер промежуточного обмена.
Часто используемые термины Приложение-источник и Целевое
приложение касаются не подчинения приложений, а определяют генеа-
логию объектов.
Некоторые Windows-приложения могут выступать только в роли
подчиненных, а некоторые только в роли ведущих. Например,
Paintbrush в OLE технологии может играть только роль подчиненно-
го приложения, служащего для создания и модификации отдельных
объектов. Другие приложения, например, Write или Cardfile можно
считать оправданным с точки зрения, что гораздо чаще приходится
вставлять иллюстрации в сложные по структуре текст, чем текст в
иллюстрации. Новые приложения,такие как Word, могут выполнять в
рамках OLE обе эти функции.
Употребление термина объект считается престижным в кругах
программистов, хотя часто он употрябляется и не к месту. Всякий
разработчик почитает своим долгом применить в своем продукте ООП
без особой на то необходимости. В среде Windows в термин объект
вкладывается несколько специфический смысл. Пользователя не приг-
лашают постигать азы ООП, или заняться конструированием объектов
на С++.
Когда об объектах говорят в рамках Windows, то имеют в виду
возможность встраивания в некоторый документ фрагмента, порожден-
ного другим приложением. Вот это "инородное тело" и называется
объектом.
В таком подходе нет ничего нового. Когда в текст, подготав-
ливаемый Write, вставляется рисунок из Paintbrush посредством
Clipboard или таблиц Exсel, в документ, подготавливаемый в Word,
то результатом действия будет как раз появления объекта.
Традиционные объекты всегда представляют собой копии. Рабо-
та с ними основывается на том, что все Windows приложения поддер-
живают не только свой собственный формат , но и некоторый обоб-
щенный, стандартный, играющий роль общеизвестного международного
языка. Если, например, в текстовый документ вставляется таблица
из табличного процессора, то буффер промежуточного обмена преоб-
разует ее в формат к стандартному, и тем самым обеспечивает
вставку. Такая копия в текстовом редакторе по виду не отличается
от оригиналу, но она недоступна для внесения изменений. Невозмож-
но, вставив таким способом копию из Paintbrush в Write документ,
изменить цвет, толщину линий или масштаб.
Новые объекты, доступные в рамках Windows 3.1 очень похожи
на традиционные, но они не являются копиями - это оригиналы. Они
имеются в единственном экземпляре и находятся непостредственно в
целевых документах. Там они существуют одновременно в двух форма-
тах - в стандартном и в формате приложения-источника.
Благодаря стандартному формату объект может идицироваться и
сохранять в рамках целевого документа. Имеется возможность обра-
ботки объекта также, как и любого файла оригинала. Ситуация выг-
лядит так, словно внутри объекта встроен другой. Это обеспечи-
вает доступ к средствам обработки нового объекта (приложению-ис-
точнику) посредством простого двойного щелчка на объекте.

Встроенные объекты
Информация, вставленныя в документ целевого приложения,
представляет собой объект. Такой объект встраивается в документ,
обрабатываемый ведущим приложением. Это значит, что он рассматри-
вается как составная часть данного документа, может распечаты-
ваться и сохраняться вместе с ним. Такие объекты могут содержать
информацию любого типа: текст, таблицы, графики и др.
Встроенные объекты существуют только в единственном экзем-
пляре и тлько там, где они встроены - в целевом документе. Обра-
батываются они своими "родительскими" программами, вызываемыми
весьма эффективным спосбом, в отличае от традиционного.

Связывание с родительским приложением
Следующей весьма удобной особенностью встроенных объектов
является то, что они остаются связанными с породившим их приложе-
ниями. Благодаря этому пользователь избавляется от необходимости
помнить имена и директории файлов-источников. Достаточно двойно-
го щелчка на объекте - и родительская программа запускается.
Важным достоинством подобного связывания встроенных объек-
тов является мобильность документов. Можно легко перенести такой
документ с одной машины на другую (необходимо только чтобы на них
обеих была установлена оболочка и были необходимые приложения или
динамические библиотеки от них). Для обработки встроенных объек-
тов достаточно будет щелкнуть по ней дважды и на другой машине
произойдет тоже самое, что и на вашей: вызовется соответсвующее
приложение. В этом случае необходимым условием переноса является
наличие на другой машине текстового редактора Write и графическо-
го редактора Paintbrush.
При работе в рамках DDE такой перенос не возможен, точнее он
будет включать в себя не только перенос самого файла-документа,
но и связанных с данным файлом файлов-источников и целевых фай-
лов - всей структуры.

Перспективы развития OLE
Технология OLE делает только первые шаги. Пока только неко-
торые Windows приложения являются OLE совместимыми. Среди утилит
группы Accessories версии 3.1 такими на сегоднешний день являют-
ся только Write, Paintbrush и Cardfile. Но даже они "в своем кру-
гу" не допускают вставки в произвольном направлении (т.е. из лю-
бой в любую другую). В настаящее время речь идет о поддержке наи-
более оправданного с практической точки зрения "напрвления
встраивания" - из Paintbrush в Write и Сardfile документа.
Чтобы определить какие из приложений поддерживаю OLE интер-
фейс, необходимо из OLE-совместимого приложения выполнить дирек-
тиву "ВСТАВИТЬ ОБЪЕКТ" в меню "Edit". В отрывшемся окне будет
продемонстрирован список доступных встраиваемых объектов.
В настоящий момент многие компиляторы уже ввели поодержку
OLE в свои библиотеки: Borland C++ ver4.5. Пример использования OLE
технологии приведен в приложении 1. Данная программа использует соз-
данный рисунок Paintbrush в виде файла или копирует его из Clipboard.

Заключение

В заключении хотелось бы отметить, что существующие способы
обмена информации возникали вместе с развитием Windows. Как сама
суть Windows, они являются продолжением заложенной в нее цель:
cпособность работать с файлами любых форматов, на любом оборудовании.
В отличие от стандартного решения, когда фирма-производитель обо-
лочки (типа Windows) пыталась сама написать различные драйверы
для поддержки устройств и различные библиотеки для поддержки
форматов многочисленных файлов других пакетов, фирма Microsoft
возложила эту обязанность на производителей оборудования и
программного обеспечения. Таким образом, последовательное разви-
тие Clipboard-->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 Object

int 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 argsused
int 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 Programn
Written using ObjectWindowsnCopyright (c) 1992 Borland",
GetApplication()->Name, MB_OK );
}

// создание новой paint brush
void TOleDocWindow::CMPBrush( RTMessage )
{
BackupObject();
bObjectLoaded = FALSE;

lstrcpy( lpszObjectName, GetNextObjectName() );

ret = OleCreate( "StdFileEditing",
(LPOLECLIENT)pOwlClient,
"PBRUSH",
lhClientDoc,
GetApplication()->Name,
&lpObject,
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,
&lpUndoObject );
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,
&lpObject,
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,
&lhClientDoc );
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,
&lhClientDoc );
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);
}




Новинки рефератов ::

Реферат: Иран (География)


Реферат: Биография Н. В. Гоголя (Литература : русская)


Реферат: Математическое моделирование биполярных транзисторов типа p-n-p (Радиоэлектроника)


Реферат: Сорняки и борьба с ними (Биология)


Реферат: Обеспечение национальной безопасности РК в контексте интеграционных связей стран СНГ (с 1991-2001г.г.) (Международное публичное право)


Реферат: Отчет по практике в Банке АСАКА (Банковское дело)


Реферат: Исследование движения центра масс межпланетных космических аппаратов (Астрономия)


Реферат: Власть мафии (Политология)


Реферат: Бизнес план на тему: Каким видом бизнеса вы хотели бы заниматься? (Банковское дело)


Реферат: Истоки и ценности индустриальной цивилизации (История)


Реферат: Сегодня студенты, завтра - интеллектуальный потенциал нации - какой? (взгляд самой молодёжи) (Культурология)


Реферат: Методы оценки управленческого персонала в организации (Психология)


Реферат: Комиссия Евросоюза (Право)


Реферат: Николай II - последний самодержец земли российской (История)


Реферат: Биология (Биология)


Реферат: Соціальне становище Запорізького краю (История)


Реферат: Имущественные права (Право)


Реферат: Деяния святых апостолов (Религия)


Реферат: Закон о пенсиях (Право)


Реферат: Правовое регулирование деятельности налоговых органов РФ (Государство и право)



Copyright © GeoRUS, Геологические сайты альтруист