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

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

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.03.2012, 14:49   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,442
По умолчанию Правильно передавать строку любой длинны через WM_COPYDATA, без зависаний.

Доброго времени суток!

Есть 2 приложения(оба мои), между ними нужно делать обмен сообщениями, с ответами данных на них.

Вот отвечающий "сервер":
Код:
procedure TMessageHandler.WMCopyData(var aMsg: TWMCopyData);
var
  aCDS: TCopyDataStruct;
  s: string;
begin
  case aMsg.CopyDataStruct.dwData of
    CMD_GETVERSION:
      begin
        ZeroMemory(@aCDS, SizeOf(TCopyDataStruct));
        s := MyVersion(ParamStr(0)) + #0;
        aCDS.cbData := Length(s) * SizeOf(Char);
        aCDS.dwData := RCV_GETVERSION;
        aCDS.lpData := PChar(s);
        SendMessage(aMsg.From, WM_COPYDATA, Handle, Integer(@aCDS));
      end;

    CMD_GETHLRPATH:
      begin
        ZeroMemory(@aCDS, SizeOf(TCopyDataStruct));
        s := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
        aCDS.cbData := Length(s) * SizeOf(Char);
        aCDS.dwData := RCV_GETHLRPATH;
        aCDS.lpData := PChar(s);
        SendMessage(aMsg.From, WM_COPYDATA, Handle, Integer(@aCDS));
      end;
  end;
end;
а это запрашивающий "клиент":
Код:
var
  MainForm: TMainForm;
  aVersion:string;
  aPath:string;

implementation

{$R *.dfm}

procedure TMainForm.UpdateInfoBtnClick(Sender: TObject);
var
  aCDS: TCopyDataStruct;
begin
  ZeroMemory(@aCDS, SizeOf(TCopyDataStruct));
  aCDS.dwData := CMD_GETVERSION;
  SendMessage(FindWindow(PAnsiChar(cHLR_RECIVEWNDCLASS),nil), WM_COPYDATA, Handle, Integer(@aCDS));
end;

procedure TMainForm.WMCopyData(var aMsg: TWMCopyData);
var
  PStr:Pointer;
begin
  case aMsg.CopyDataStruct.dwData of
    RCV_GETVERSION:
      begin
        PStr:=aMsg.CopyDataStruct^.lpData;
        if (PStr <> nil) then
        aVersion:=string(PChar(PStr));
      end;

    RCV_GETHLRPATH:
      begin
        PStr:=aMsg.CopyDataStruct^.lpData;
        if (PStr <> nil) then
        aPath:=string(PChar(PStr));
      end;
  end;
  ShowMessage(aVersion+#10#13+aPath);
end;
Сообщение уходит на сервер и сервер отвечает, но он подвисает в момент ответа.

Как быть?

P.s. и правильно ли я передаю строку как PChar?
Человек_Борща вне форума Ответить с цитированием
Старый 25.03.2012, 09:02   #2
Rock-n-Rolla
Форумчанин
 
Регистрация: 11.01.2012
Сообщений: 178
По умолчанию

при выполнении вот этой строки
Код:
SendMessage(FindWindow(PAnsiChar(cHLR_RECIVEWNDCLASS),nil), WM_COPYDATA, Handle, Integer(@aCDS));
поток блокируется и принимать сообщения не может, он ждёт когда адресат обработает сообщение. адресат в свою очередь при обработке сообщения, тоже вызывает функцию SendMessage для отправки ответа
Код:
SendMessage(aMsg.From, WM_COPYDATA, Handle, Integer(@aCDS));
но отправка не выполучается так как адресат заблокирован и его обработать не может.

таким образом получается зависание.

и вообще не рекомендуется вызывать функции SendMessage в обработчиках (пусть даже случай будет самым безобидным, но это очень плохой приём)
progromore.i2p - первый русскоязычный портал программистов в скрытосети

Последний раз редактировалось Rock-n-Rolla; 25.03.2012 в 09:04.
Rock-n-Rolla вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
передавать сигналы от геймпада через интернет entusiast Помощь студентам 6 03.01.2011 21:25
Передавать большие файлы через IdUDP SoftKoc Работа с сетью в Delphi 6 20.11.2010 14:05
Как передавать (и через что) файлы? TwiX Работа с сетью в Delphi 5 17.03.2010 16:30
Передавать файл через сокет частями NieL Работа с сетью в Delphi 0 08.12.2009 16:42
Как при нажатии на строку в Listbox передавать нажатую строку в переменную Михаил Юрьевич Общие вопросы Delphi 5 16.03.2009 12:59