Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

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

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


Ответ
 
Опции темы
Старый 29.08.2012, 10:42   #1
avd
Форумчанин
 
Регистрация: 06.06.2010
Сообщений: 79
Репутация: 21
По умолчанию Передача сообщений между окнами

....
private
message WM_COPYDATA;
....
Код:

// с помощью этой ф. окно Петя передаёт сообщение окну Вовочка
procedure TForm1.SendMess(s: string);
var
  CDS: TCopyDataStruct;
begin
  CDS.dwData := 1000; // Тип команды
  CDS.cbData := length(s) + 1; // Длина передаваемых данных
  getMem(CDS.lpData, CDS.cbData);
  try
    StrPCopy(CDS.lpData, s); // Данные в буфер
    SendMessage(FindWindow(nil, 'Вовочка'), WM_COPYDATA, Handle, integer(@CDS));
  finally
    FreeMem(CDS.lpData, CDS.cbData);
  end;
end;

Код:

// А так Вовочка принимает
procedure TForm1.WMCopyData(var MessageData: TWMCopyData);
begin
  if MessageData.CopyDataStruct.dwData = 1000 then
  begin
    if PChar(MessageData.CopyDataStruct.lpData) = '1' then
    begin
      jvLed1.Status := true; // Зажечь светодиод
    end;
    if PChar(MessageData.CopyDataStruct.lpData) = '2' then
    begin
      jvLed1.Status := false; // Погасить
    end;
  end;
end;

Ф. SendMess вызывается по срабатыванию таймера 2 раза в сек.
Проблема в том, что приём идёт как-то нестабильно, то есть, то нет.
avd вне форума   Ответить с цитированием
Старый 29.08.2012, 10:55   #2
Человек_Борща
Модератор
Заслуженный модератор
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Адрес: Республика Беларусь, г. Минск
Сообщений: 11,478
Репутация: 2769
По умолчанию

Код:

CDS.cbData := length(s) + 1;

Неа.
Код:

CDS.cbData := length(s) + SizeOf(s)*SizeOf(Char);

Человек_Борща вне форума   Ответить с цитированием
Старый 29.08.2012, 11:01   #3
avd
Форумчанин
 
Регистрация: 06.06.2010
Сообщений: 79
Репутация: 21
По умолчанию

С П А С И Б О! З А Р А Б О Т А Л О!
avd вне форума   Ответить с цитированием
Старый 29.08.2012, 20:01   #4
GunSmoker
Профессионал
 
Регистрация: 13.08.2009
Адрес: Россия, Тверь
Сообщений: 2,581
Репутация: 1066

icq: 436815515
skype: RandomClear
По умолчанию

Код:

length(s) + SizeOf(s)*SizeOf(Char);

Боже, что ЭТО?

Должно быть:
Код:

procedure TForm1.SendMess(const s: string);
var
  CDS: TCopyDataStruct;
  Buffer: UTF8String;
begin
  Buffer := UTF8Encode(S);

  CDS.dwData := 1000; // Тип команды

  CDS.cbData := Length(Buffer) + 1; 
  CDS.lpData := Pointer(Buffer);

  SendMessage(FindWindow(nil, 'Вовочка'), WM_COPYDATA, Handle, LParam(@CDS));
end;

Код:

procedure TForm1.WMCopyData(var MessageData: TWMCopyData);
var
  Buffer: UTF8String;
  Data: String;
begin
  if MessageData.CopyDataStruct.dwData = 1000 then
  begin
    Buffer := PAnsiChar(MessageData.CopyDataStruct.lpData);
    Data := UTF8ToString(Buffer);

    if Data = '1' then
      jvLed1.Status := true
    else
    if Data = '2' then
      jvLed1.Status := false; // Погасить
  end;
end;

Ещё лучше:
Код:

procedure TForm1.EnableLED(const AEnable: Boolean);
var
  CDS: TCopyDataStruct;
  Buffer: BOOL;
begin
  Buffer := AEnable;

  CDS.dwData := 1000; // Тип команды

  CDS.cbData := SizeOf(Buffer); 
  CDS.lpData := @Buffer;

  SendMessage(FindWindow(nil, 'Вовочка'), WM_COPYDATA, Handle, LParam(@CDS));
end;

Код:

procedure TForm1.WMCopyData(var MessageData: TWMCopyData);
var
  Buffer: BOOL;
begin
  if MessageData.CopyDataStruct.dwData = 1000 then
  begin
    Buffer := PBOOL(MessageData.CopyDataStruct.lpData)^;

    jvLed1.Status := Buffer;
  end;
end;

__________________
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума   Ответить с цитированием
Старый 29.08.2012, 20:57   #5
Человек_Борща
Модератор
Заслуженный модератор
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Адрес: Республика Беларусь, г. Минск
Сообщений: 11,478
Репутация: 2769
По умолчанию

Цитата:
Боже, что ЭТО?
И правда, очипятка
Код:

CDS.cbData:=length(s)*SizeOf(Char);

Очевидно, способ решения проблем без чудо конвертирования UTF8.

Последний раз редактировалось Человек_Борща; 29.08.2012 в 21:01.
Человек_Борща вне форума   Ответить с цитированием
Старый 29.08.2012, 21:13   #6
GunSmoker
Профессионал
 
Регистрация: 13.08.2009
Адрес: Россия, Тверь
Сообщений: 2,581
Репутация: 1066

icq: 436815515
skype: RandomClear
По умолчанию

Это верно, но только если речь идёт об обмене данных внутри одной программы (и даже - одного модуля). Как только ты выставляшь обмен данными наружу, то String, Char, PChar - уже "вне закона". Потому что это не настоящие типы, а псевдонимы. И они могут переопределяться. Поэтому простая перекомпиляция может изменить состояние с "работает" на "не работает" и обратно.

Вместо типов с плавающим размером нужно использовать типы с фиксированным размером (AnsiString, AnsiChar, PAnsiChar, UnicodeString, WideChar, PWideChar, UTF8String, WideString). Я использовал UTF-8, но это не принципиально. Можно было и UTF-16. А вот использовать ANSI для внешнего обмена будет уже не такой удачной идеей.

Но в любом случае, главное - не String/Char.
__________________
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума   Ответить с цитированием
Старый 29.08.2012, 22:27   #7
Человек_Борща
Модератор
Заслуженный модератор
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Адрес: Республика Беларусь, г. Минск
Сообщений: 11,478
Репутация: 2769
По умолчанию

Цитата:
Это верно, но только если речь идёт об обмене данных внутри одной программы (и даже - одного модуля).
аналогично проблеме передаче строк между DLL и процессом?
Человек_Борща вне форума   Ответить с цитированием
Старый 29.08.2012, 22:36   #8
GunSmoker
Профессионал
 
Регистрация: 13.08.2009
Адрес: Россия, Тверь
Сообщений: 2,581
Репутация: 1066

icq: 436815515
skype: RandomClear
По умолчанию

Примерно да. В обоих случаях при обмене обе стороны должны использовать компиляторно-независимый формат данных.
__________________
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума   Ответить с цитированием
Старый 29.08.2012, 22:48   #9
Человек_Борща
Модератор
Заслуженный модератор
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Адрес: Республика Беларусь, г. Минск
Сообщений: 11,478
Репутация: 2769
По умолчанию

GunSmoker, значит и в C++ оно тоже актульно?
Человек_Борща вне форума   Ответить с цитированием
Старый 29.08.2012, 22:53   #10
GunSmoker
Профессионал
 
Регистрация: 13.08.2009
Адрес: Россия, Тверь
Сообщений: 2,581
Репутация: 1066

icq: 436815515
skype: RandomClear
По умолчанию

Разумеется. К примеру, _TCHAR (аналог Char в Delphi) - это маппинг или на char (аналог AnsiChar в Delphi) или на wchar_t (аналог WideChar в Delphi).
__________________
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переходы между окнами Ark Общие вопросы Delphi 5 22.04.2009 00:22
Как сделать так, чтобы переключение между окнами было автоматическим? barand Свободное общение 9 07.07.2008 23:54
Копирование файлов и каталогов перетаскиваением между двумя окнами SANTA_KLAUD Общие вопросы Delphi 3 28.05.2008 21:52
Передача данных между окнами/приложениями? Dexer Win Api 11 23.05.2007 16:23
Как запретить переход между диалоговыми окнами. dnkR Общие вопросы Delphi 1 18.01.2007 07:59


03:05.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru