Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.12.2011, 00:15   #1
iCaesy
In progress...
Форумчанин
 
Регистрация: 25.09.2011
Сообщений: 161
По умолчанию Delphi win api функции посылка сообщений

Суть программы:
Есть две программы "Клиент" и "Сервер" Клиент посылает сообщение серверу с помощью PostMessage, при получении сообщения "Сервер" выполняет некую ф-цию (ищет директорию Windows), и отправляет строку с директорией винды обратно клиенту.

Клиент:

Код:
unit cliUnit;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons;
 
  var WM_SUBSCRIBETIME, WM_UNSUBSCRIBETIME,
  WM_SUBSCRIBEMEM, WM_UNSUBSCRIBEMEM : Cardinal;
 
type
  TClientForm = class(TForm)
    TimeSpeedButton: TSpeedButton;
    procedure TimeSpeedButtonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
   procedure WMCopyData(var msg: TMessage);message WM_COPYDATA;
  end;
 
var
  ClientForm: TClientForm;
 
implementation
 
{$R *.DFM}
 
procedure TClientForm.TimeSpeedButtonClick(Sender: TObject);
var srvhandle : THandle;
begin
 srvhandle := FindWindow(nil ,'Server');
 if srvhandle<>0 then
  if TimeSpeedButton.Down then
   PostMessage(srvhandle,WM_SUBSCRIBETIME,integer(Self.Handle),0)
  else
   begin
   PostMessage(srvhandle,WM_UNSUBSCRIBETIME,integer(Self.Handle),0);
   TimeSpeedButton.Caption := 'WinDir';
   end;
end;
 
 
procedure TClientForm.WMCopyData(var msg: TMessage);
 var
  m : cardinal; windir: string;
 begin
 m := PCopyDataStruct(msg.lParam)^.dwData;
 if PCopyDataStruct(msg.lParam)^.lpData<>nil then
 windir := String(PCopyDataStruct(msg.lParam)^.lpData^);
 end;
 
initialization
  WM_SUBSCRIBETIME := RegisterWindowMessage('WM_SUBSCRIBETIME');
  WM_UNSUBSCRIBETIME:= RegisterWindowMessage('WM_UNSUBSCRIBETIME');
  WM_SUBSCRIBEMEM:= RegisterWindowMessage('WM_SUBSCRIBEMEM');
  WM_UNSUBSCRIBEMEM:= RegisterWindowMessage('WM_UNSUBSCRIBEMEM');
end.
Код:
Сервер:

unit srvUnit;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;
 
type
  TServerForm = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
const MaxClients = 32;
 
  var WM_SUBSCRIBETIME, WM_UNSUBSCRIBETIME,
  WM_SUBSCRIBEMEM, WM_UNSUBSCRIBEMEM : Cardinal;
var
  ServerForm: TServerForm;
 
  MemClientList : array[0..MaxClients-1] of THandle;
  TimeClientList : array[0..MaxClients-1] of THandle;
 
implementation
 
 
{$R *.DFM}
procedure TServerForm.Timer1Timer(Sender: TObject);
 var  WinDir: string;
  buffer: array [0..255] of char;
  i : Integer;
  var CDS : TCopyDataStruct;
begin
  GetWindowsDirectory(buffer, SizeOf(buffer));
  windir:=buffer;
 // CDS.dwData := ms.dwAvailPageFile + ms.dwAvailPhys;
  CDS.cbData := SizeOf(windir);
  CDS.lpData := @windir;
 
  for i:=0 to MaxClients-1 do
   begin
   if TimeClientList[i]<>0 then
    SendMessage(TimeClientList[i],WM_COPYDATA,Self.Handle,longint(@CDS) );
   if (MemClientList[i]<>0) and (TimeClientList[i]<>MemClientList[i]) then
    SendMessage(MemClientList[i],WM_COPYDATA,Self.Handle,longint(@CDS) );
   end;
end;
 
initialization
  FillChar( MemClientList, SizeOf(MemClientList), 0);
  FillChar( TimeClientList, SizeOf(TimeClientList), 0);
finalization
 
end.

Делал на основе примера, там использовался Таймер в сервере, пытаюсь переделать под себя.
Что нужно исправить в сервере, и как передать результат ф-ции GetWindowsDirectory обратно клиенту, а там его вывести ?
iCaesy вне форума Ответить с цитированием
Старый 17.12.2011, 08:39   #2
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Межпроцессный обмен осуществляется 5 известными мне способами:
1) файловый маппинг
2) буфер обмена
3) атомы ОС
4) DDE-сервер/клиент (устаревший)
5) TCP/IP

Чтобы передать строку из одного приложения в другое, сообщения тут не помогут, ибо программа не может использовать адресное пространство доругого процесса напрямую (вернее, может, но вам это не нужно делать).

Самый легкий способ - использовать атомы виндовса.
Функции GlobalAddAtom, GlobalFindAtom, GlobalDeleteAtom.
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 17.12.2011, 16:11   #3
iCaesy
In progress...
Форумчанин
 
Регистрация: 25.09.2011
Сообщений: 161
По умолчанию

"Клиент" "Сервер" это просто названия форм, по сути это две программы, две формы, которые обмениваются сообщениями с помощью WinAPI ф-ций.
Просто в задании, для простоты они именуются как "Клиент" и "Сервер", хотя на самом деле сетевой связи между ними нет.
iCaesy вне форума Ответить с цитированием
Старый 18.12.2011, 18:52   #4
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Я так и понял, потому уже ответил на ваш вопрос в своем предыдущем посте.
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Правильная посылка последовательностей сообщений VintProg Общие вопросы Delphi 3 15.11.2011 20:21
Посылка и обработка сообщений Delphi iCaesy Помощь студентам 2 06.11.2011 01:49
С++ Builder и функции Win API Assemblerru C++ Builder 15 09.08.2011 10:23
Win API, чайник и Delphi Crabobass Общие вопросы Delphi 2 19.04.2011 11:29