25.1. Обмен сообщениями
Посылка сообщений – это естественный способ связи между программами в Windows. В Delphi все участники обмена должны быть наследниками класса TWinControl, т.е. окнами, у которых есть свои номера или дискрипторы. Следующий пример показывает, как найти запущенное приложение c главным окном Server:
Var Svrh:THandle;
Begin
Svrh:=FindWindow(nil, ’Server’);
If Svrh=0 then ShowMassage(’Сервер не найден’);
Передать сообщение окну можно с помощью функции
Function SendMessage(Hwnd:HWND; Msg:Cardinal; WParam, LParam:Integer):LongBool;
Здесь Hwnd – номер окна, Msg – код команды, WParam и LParam – параметры, которые передаются окну. Эта функция ожидает окончания обработки переданного сообщения и возвращает его результат. Другая функция PostMessage имеет такие же параметры, но она не ждет окончания обработки посланного сообщения, а лишь сообщает о том, смогла ли она поставить сообщение в очередь.
Для создания обработчика Windows сообщений нужно в классе объявить метод с директивой message и указать номер обрабатываемой команды. Как видно из списка параметров функции посылки сообщения, каждому окну может быть передано не более 8 байт информации. Для передачи большего количества информации можно использовать команду WM_COPYDATA.
Рассмотрим пример создания сервера с именем Server, который каждому клиенту посылает информацию о текущем времени на сервере. В примере используются следующие типы:
TMsg = packed record // Тип сообщения
hwnd: HWND; // Указатель на окно, которому посылается сообщение
message: UINT; // Код сообщения
wParam: WPARAM; // W параметр
lParam: LPARAM; // L параметр
time: DWORD; // Время посылки сообщения
pt: TPoint; // Координаты мыши в момент отправки сообщения
end;
TCopyDataStruct= record // Структура передаваемых данных
dwData: Integer; // Прямо передаваемые 4 байта
cbData: Integer; // Длина передаваемых данных
lpData: Pointer; // Указатель на начало передаваемых данных
end;
Текст примера:
// Текст файла проекта сервера
Program server;
Uses Forms, windows,
userver in 'userver.pas' {Form1}, // Включение в проект модуля Userver
Udata1 in 'Udata1.pas' {DataModule1: TDataModule};
// Подключение модуля данных
Type TNewObject=class // Объявляем новый класс
// Определяем классовый обработчик сообщений для сервера
class procedure AppMsgHandler(var Msg:TMsg; var Handled:Boolean);
end;
{$R *.res}
class procedure TNewObject.AppMsgHandler;
var i:Integer;
ClientWnd:Thandle;
Begin
ClientWnd:=THandle(Msg.WParam); // Получаем номер окна клиента
if Msg.message=WM_ST then Begin
for i:=0 to MaxClient-1 do Begin
if TimeClientList[i]=0 then Begin
TimeClientList[i]:=ClientWnd;
// Запоминаем номер окна в списке клиентов
Handled:=True;
exit;
end;
end;
end;
if Msg.Message=WM_UT then Begin
for i:=0 to MaxClient-1 do Begin
if TimeClientList[i]=ClientWnd then Begin
// Удаляем клиента из списка
TimeClientList[i]:=0;
Handled:=True;
exit;
end;
end;
end;
end;
var i:Integer;
begin
// Очищаем список клиентов
for i:=0 to MaxClient-1 do TimeClientList[i]:=0;
// Регистрируем в системе новые коды сообщений для окон
// Код соединения с сервером
WM_ST:=RegisterWindowMessage('WM_ST');
// Код отсоединения
WM_UT:=RegisterWindowMessage('WM_UT');
Application.Initialize;
// Определяем обработчик Windows сообщения для сервера
Application.OnMessage:=TNewObject.AppMsgHandler;
// Создаем формы
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TDataModule1, DataModule1);
// Запускаем обработчик сообщений сервера
Application.Run;
end.
// Текст модуля данных
Unit Udata1;
interface
uses SysUtils, Classes;
type
TDataModule1 = class(TDataModule)
end;
// Определяем глобальные переменные и константы сервера
var
DataModule1: TDataModule1;
WM_ST,WM_UT:THAndle;
const maxclient=64; // Максимальное число клиентов
var TimeClientList:Array[0..maxclient] of integer;
implementation
{$R *.dfm}
end.
// Текст модуля формы сервера
Unit userver;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls,Udata1;
Type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// Метод обработки тиков таймера сервера
Procedure TForm1.Timer1Timer(Sender: TObject);
var dt:TDateTime;
i:Integer;
cds:TCopyDataStruct; // Структура передаваемых данных
begin
dt:=Now; // Определяем текущее время
cds.cbData:=sizeof(dt); // Запоминаем длину передаваемых данных
cds.lpData:=@dt; // Запоминаем указатель на передаваемые данные
for i:=0 to MaxClient-1 do Begin
if TimeClientList[i]<>0 then
// Посылаем данные всем зарегистрированным клиентам
SendMessage(TimeClientList[i],WM_COPYDATA,Self.Handle,
LongInt(@cds));
end;
end;
end.
// Текст модуля формы клиента
Unit Uclient1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;
Type
TForm1 = class(TForm)
SpeedButton1: TSpeedButton;
Label1: TLabel;
Label2: TLabel;
procedure SpeedButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
// Метод обработки сообщения WM_COPYDATA для клиента
procedure WMCopyData(var msg:TMessage);message WM_COPYDATA;
end;
var
Form1: TForm1;
WM_ST,WM_UT:THandle;
implementation
{$R *.dfm}
// Текст метода обработки сообщения WM_COPYDATA
Procedure TForm1.WMCopyData(var msg:TMessage);
var dt:TDateTime;
Begin
if PCopyDataStruct(msg.LParam)^.lpData <> nil then Begin
dt:=TDateTime(PCopyDataStruct(msg.LParam)^.lpData^);
// Выводим на форму клиента врямя, переданное сервером
Label2.Caption:=TimetoStr(dt);
end;
end;
Procedure TForm1.SpeedButton1Click(Sender: TObject);
var ServerHandle:THandle;
begin
// Получаем номер окна сервера
ServerHandle:=FindWindow(nil,'server');
if ServerHandle<>0 then Begin
if SpeedButton1.Down then Begin
// Посылаем серверу сообщение для установления с ним соединения
PostMessage(ServerHandle,WM_ST,Integer(Self.Handle),0);
SpeedButton1.Caption:='Соединение есть!';
end
else Begin
// Посылаем серверу сообщение о прекращении с ним связи
PostMessage(ServerHandle,WM_UT,Integer(Self.Handle),0);
SpeedButton1.Caption:='Connect';
Label2.Caption:='';
end;
end;
end;
Procedure TForm1.FormCreate(Sender: TObject);
Begin
// Регистрируем в системе новые коды сообщений со стороны клиента
WM_ST:=RegisterWindowMessage('WM_ST');
WM_UT:=RegisterWindowMessage('WM_UT');
end;
end.
Вид окна клиента может быть следующим:
Рис.25.1. Вид формы клиента
- Программирование в среде Delphi
- Программирование в среде Delphi
- 1. История развития вычислительной техники, системы счисления и единицы информации.................................................7
- 2. Структура персонального компьютера и операционные системы.........................................................................13
- 3. Основы алгоритмизации и работа в delphi..........................18
- 4. Базовые элементы delphi...................................................................26
- 5. Стандартные функции и подпрограммы................................30
- 6. Операторы delphi......................................................................................33
- 7. Операторы циклов....................................................................................35
- 18. Выделение памяти под объект и прародитель всех классов – tobject..........................................................................................84
- 19. Обработка исключительных ситуаций................................87
- 20. Основные классы и общие свойства компонентов...93
- 26. Технология com.....................................................................................129
- 1. История развития вычислительной техники, системы счисления и единицы информации
- 1.1. История развития вычислительной техники
- 1.2. Системы счисления
- 1.3. Единицы информации
- 2. Структура персонального компьютера и операционные системы
- 2.1. Структура персонального компьютера.
- 2.2. Операционные системы
- 3. Основы алгоритмизации и работа в delphi
- 3.1. Основы программирования
- 3.2. Программирование в среде Delphi
- 4. Базовые элементы delphi
- 4.1. Алфавит среды Delphi
- 4.2. Константы
- 4.3. Переменные
- 4.4. Основные типы переменных
- 4.5. Операции над переменными и константами
- 5. Стандартные функции и подпрограммы
- 5.1. Математические функции
- 5.2. Функции преобразования
- 5.3. Дополнительные системные подпрограммы и функции
- 6. Операторы delphi
- 6.1. Оператор присваивания
- 6.2. Оператор безусловной передачи управления
- 6.3. Условный оператор if
- 6.4. Оператор разветвления Case
- 6.5. Составной оператор
- 7. Операторы циклов
- 7.1. Оператор цикла For
- 7.2. Оператор цикла Repeat
- 7.3. Оператор цикла While
- 8. Работа с массивами
- 9. Работа со строками
- 9.1. Процедуры работы со строками
- 9.2. Функции работы со строками
- 10. Работа с записями
- 11. Процедуры и функции
- 12. Модуль unit
- 13. Работа со множествами
- 14. Работа с файлами
- 14.1. Текстовые файлы
- 14.2. Типированные файлы
- 14.3. Нетипированные файлы
- 15. Работа с файлами и каталогами
- 16. Динамические переменные и структуры данных
- 16.1. Динамические переменные
- 16.2. Работа со стеком
- 16.3. Работа со списками или очередями
- 16.4. Работа с деревьями
- 17. Основы объектно–ориентированного программирования
- 17.1. Объекты и классы
- 17.2. Области видимости класса
- 17.3. Свойства (Property) и инкапсуляция
- 17.4. Методы, наследование и полиморфизм
- 17.5. События (Events)
- 18. Выделение памяти под объект и прародитель всех классов – tobject
- 18.1. Выделение памяти под объект
- 18.2. Описание класса tObject
- 18.3. Операторы приведения типов классов
- 19. Обработка исключительных ситуаций
- 19.1. Два вида оператора Try
- 19.2. Программное создание исключительной ситуации
- 19.3. Основные исключительные ситуации
- 20. Основные классы и общие свойства компонентов
- 20.1. Класс tList
- 20.2. Класс tStrings
- 20.3. Общие свойства компонентов
- 21. Графические возможности delphi
- 21.1. Класс Tcanvas
- 21.2. Классы тGгарhic и тРicture
- 21.3. Классы tFont, tPen и tBrush
- 21.4. Работа с изображениями
- 22. Визуальные компоненты delphi
- 22.1. Компонент tBitBtn
- 22.2. Компоненты tDrawGrid и tStringGrid
- 22.3. Компонент tPageControl
- 22.4. Компонент tTimer
- 22.5. Компонент tGauge
- 22.6. Компонент tСolorGrid
- 23. Стандартные диалоговые окна и типовые диалоги
- 23.1. Стандартные диалоговые окна
- 23.2. Типовые диалоги
- 24. Форма, приложение и глобальные объекты
- 24.1. Форма и ее свойства
- 24.2. Объект Application
- 24.3. Глобальные объекты
- Объект ClipBoard
- Объект Screen
- Объект Printer
- 25. Межпрограммное взаимодействие
- 25.1. Обмен сообщениями
- 25.2. Динамический обмен данными
- 25.3. Совместное использование общей памяти
- 25.4. Каналы
- 25.5. Сокеты
- 26. Технология com
- 26.1. Интерфейс
- 27. Технология автоматизации
- 27.1. Основы ole Automation
- 27.2. Примеры использования серверов автоматизации
- 27.3. Компоненты ActiveX
- 28. Динамические библиотеки
- 28.1. Создание dll
- 28.2. Использование dll
- 28.3. Пример написания dll
- 29. Работа с базами данных
- 29.1. Основные определения
- 29.2. Взаимодействие приложения на Delphi с базами данных
- 29.3. Компоненты взаимодействия с базами данных
- If adoTable1.Locate(’fio,stag’,varArrayOf([’Иванов’,’10’]),[])Then …;
- 29.4. Работа с локальной базой данных
- 30. Основы языка sql
- 30.1. Составные части sql
- 30.2. Команда select
- 30.3. Пример использования запросов в Delphi
- 31. Создание собственных компонентов
- 32. Работа с реестром
- 33. Перспективы программирования в delphi
- Литература
- 220013, Минск, п.Бровки, 6