Чтение онлайн

на главную

Жанры

Шрифт:

Процедура, приведенная в листинге 7.28, не считывает значения двоичных параметров. Так сделано для упрощения этого и так громоздкого фрагмента кода. В считывании значений двоичных параметров на самом деле нет ничего сложного: нужно лишь заранее определить размер данных (метод GetDataSize) и создать буфер соответствующего размера.

Глава 8 Обмен данными между приложениями

• СообщениеWM_COPYDATA

• Использованиебуфераобмена

• Проецируемыевпамятьфайлы

Организация обмена данными между приложениями, а именно между процессами этих приложений, является достаточно трудоемкой задачей. Архитектура Win32 подразумевает

максимальную изоляцию выполняющихся приложений друг от друга. Каждое приложение исполняется в своем виртуальном адресном пространстве, которое изолировано и не имеет доступа к памяти других процессов приложений. Но довольно часто возникает необходимость передачи данных из одного выполняющегося процесса в другой. Это вызвано тем, что функциональные приложения и пакеты программ исполняются не в одном процессе, поэтому для нормальной работы используются основные возможности межпроцессного взаимодействия. Наиболее простым, понятным, но не всегда удобным является передача данных с использованием сообщения WM_COPYDATA. Также для передачи данных между приложениями широко используются проецируемые в память файлы (Mapping Files). Существуют и такие высокоуровневые средства, как буфер обмена или уже рассмотренная технология СОМ. Перечисленные способы будут подробно рассматриваться в этой главе. За рамки этой книги выходит рассмотрение способа передачи данных через каналы (трубы, или Pipe), который считается устаревшим и по этой причине не вызывает интереса.

8.1. Сообщение WM_COPYDATA

Сообщение WMCOPYDATA позволяет приложениям копировать данные между их адресными пространствами. Для передачи сообщения должна использоваться функция синхронной отправки сообщения SendMessage, а не PostMessage, которая асинхронным образом передает сообщение. Данные, предназначенные для передачи, не должны содержать указателей или других ссылок на объекты, недоступные для программы, принимающей эти данные. Рассмотрим параметры, передаваемые с сообщением WM_COPYDATA:

...

//дескриптор передающего окна

wParam = (WPARAM) (HWND) hwnd;

//указатель на структуру с данными

lParam = (LPARAM) (PCOPYDATASTRUCT) pcds;

На использование сообщения налагаются следующие ограничения:

• данные, которые будут приняты, должны быть только для чтения, так как изменение структуры с данными может привести к непредсказуемым последствиям;

• если приложению, получающему данные, требуется использовать их после возврата из обработчика WMCOPYDATA, оно должно скопировать их в локальный буфер.

Итак, приступим к созданию приложения, демонстрирующего работу WM_COPYDATA Для создания хорошего примера потребуется создать два приложения. Первое будет отправлять данные (например, строку текста), другое приложение будет их получать. На главной форме первого приложения помещаем элемент управления TextBox, в который будет записываться передаваемая строка, и кнопку, нажатие которой инициирует передачу данных. Для второго приложения достаточно элемента для отображения текстовой информации типа Label. Перейдем к рассмотрению исходных текстов созданных приложений.

Мы будет посылать сообщение окну, и сообщений может быть различное количество, поэтому для уникальной идентификации операции введем специальную константу:

...

const

CMD_SETLABELTEXT = 1; // Задаем ID команды

На форме находится кнопка отправки данных другому приложению, ее обработчик выглядит следующим

образом (листинг 8.1).

...

Листинг 8.1.

Отправка данных другому приложению

procedure TDataSender.bnSendClick(Sender: TObject);

var

CDS: TCopyDataStruct;

begin

//Устанавливаем тип команды

CDS.dwData := CMD_SETLABELTEXT;

//Устанавливаем длину передаваемых данных

CDS.cbData := Length(StringEdit.Text) + 1;

//Выделяем память буфера для передачи данных

GetMem(CDS.lpData, CDS.cbData);

try

//Копируем данные в буфер

StrPCopy(CDS.lpData, StringEdit.Text);

// Отсылаем сообщение в окно с заголовком StringReciever

SendMessage(FindWindow(NIL, \'StringReciever\'),

WM_COPYDATA, Handle, Integer(@CDS));

Finally

//Высвобождаем буфер

FreeMem(CDS.lpData, CDS.cbData);

end;

end;

Подробного комментария данный листинг не требует. Обратите лишь внимание на вызов функции SendMessage, которая использует FindWindow для задания одного из своих параметров. Процедура FindWindow в случае успешного выполнения возвращает HWND окна, заголовок которого задается в параметре этой функции (строка StringReciever из предыдущего примера). Синхронная отправка сообщения WM_COPYDATA с набором данных, которые помещены в структуру CDS, осуществляется вызовом SendMessage.

Рассмотрим второе приложение, которое принимает строку и отображает ее в надписи ( Label). Для начала в блок объявления помещаем обработчик сообщения и объявляем само сообщение WM_COPYDATA:

...

type

TStringReciever = class(TForm)

LabelStr: TLabel;

private

//Обработчик сообщения WM_COPYDATA

procedure WMCopyData(var MessageData: TWMCopyData);

message WM_COPYDATA;

Как и в случае первого приложения, нам необходима константа, которая будет идентифицировать тип операции:

...

const

CMD_SETLABELTEXT = 1;

Далее рассмотрим тело функции обработчика сообщения WM_COPYDATA (листинг 8.2).

...

Листинг 8.2.

Обработка сообщения WM_COPYDATA

procedure TStringReciever.WMCopyData(var MessageData: TWMCopyData);

begin

//Устанавливаем свойства метки, если заданная команда совпа-

дает

if MessageData.CopyDataStruct.dwData = CMD_SETLABELTEXT then

begin

//Устанавливаем текст из полученных данных

LabelStr.Caption := PChar(MessageData.CopyDataStruct.lpData);

MessageData.Result := 1;

end else

MessageData.Result := 0;

end;

Если окну второго приложения, которое носит название StringReciver (получатель строки), приходит сообщение WM_COPYDATA, то происходит вызов WMCopyData. В качестве параметра эта процедура получает структуру данныхМеБ sage Data типа TWMCopyData, содержащую идентификатор операции и данные (передаваемую строку). После проверки типа операции в случае совпадения его с константой CMD_SETLABELTEXT полученные данные преобразуются в строку. Преобразование происходит при помощи функции PChar. Полученная строка устанавливается в качестве заголовка для метки с именем LabelStr. Затем полю Result структуры MessageData присваивается значение 1 или 0, в зависимости от успеха операции.

Поделиться:
Популярные книги

Медиум

Злобин Михаил
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Медиум

Жена на четверых

Кожина Ксения
Любовные романы:
любовно-фантастические романы
эро литература
5.60
рейтинг книги
Жена на четверых

Великий род

Сай Ярослав
3. Медорфенов
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Великий род

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона

Черный маг императора

Герда Александр
1. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора

Приручитель женщин-монстров. Том 5

Дорничев Дмитрий
5. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 5

Барон ненавидит правила

Ренгач Евгений
8. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Барон ненавидит правила

Приручитель женщин-монстров. Том 14

Дорничев Дмитрий
14. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Приручитель женщин-монстров. Том 14

Совершенный: Призрак

Vector
2. Совершенный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Совершенный: Призрак

Покоривший СТЕНУ. Десятый этаж

Мантикор Артемис
3. Покоривший СТЕНУ
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Покоривший СТЕНУ. Десятый этаж

Книга пятая: Древний

Злобин Михаил
5. О чем молчат могилы
Фантастика:
фэнтези
городское фэнтези
мистика
7.68
рейтинг книги
Книга пятая: Древний

Последний попаданец

Зубов Константин
1. Последний попаданец
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Последний попаданец

Разведчик. Заброшенный в 43-й

Корчевский Юрий Григорьевич
Героическая фантастика
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.93
рейтинг книги
Разведчик. Заброшенный в 43-й

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок