Postmessage LParam усечение - PullRequest
       10

Postmessage LParam усечение

1 голос
/ 29 марта 2012

В моем приложении есть рабочий поток, и я использую PostMessage для отправки строки в основной поток.Для 1 сообщения строка усекается, когда он попадает в обработчик сообщений в главном потоке.

Строка создается в рабочем потоке из строки необработанных данных, подобной этой.Он заканчивается на последний '20'.

'01010000000030000102000008850008855343414E204544474520000000000000000000'

Декодированный в строку, которую я хочу отправить, выглядит так, что это правильно:

'0100 0.50000LSB0288.588.5SCAN EDGE '

Код, который создает часть' SCAN EDGE 'и публикует ее: tmp и s_out являются строками

x := 35;
for i := 1 to 10 do
begin
  tmp := '$' + copy(s,x,2);
  TryStrToInt(tmp,dec);
  s_out := s_out + chr(dec);
  x := x + 2;
end;
PostMessage(MainHandle,UM_CLONE, UM_756, Integer(PChar(s_out)));

Обработчик сообщений в основном потоке:я являюсь строкой

i := pChar(msg.LParam);

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

'0100 0.50000 LSB0288.588.5SCAN EDG' # 0

Как я могу это исправить?

1 Ответ

12 голосов
/ 30 марта 2012

Вы публикуете содержимое переменной String, которая является локальной для процедуры потока, вызывающей PostMessage(). Если String выходит из области видимости и освобождается до того, как основной поток обработает опубликованное сообщение, память станет мусором.

Вам нужно либо:

1) используйте SendMessage() вместо PostMessage(), поэтому String остается в области действия до выхода из обработчика сообщений:

SendMessage(MainHandle, UM_CLONE, UM_756, LPARAM(PChar(s_out)));

2) динамически распределяет String в памяти, заполняет его по мере необходимости, публикует его, а затем позволяет основному обработчику сообщений освободить его, когда он закончит копирование:

var
  s_out: PString;

New(s_out);
...
s_out^ := s_out^ + chr(dec);
...
if not PostMessage(MainHandle, UM_CLONE, UM_756, LPARAM(s_out)) then
  Dispose(s_out);

.

var
  ps: PString;
  i: String;

ps := PString(msg.LParam);
i := ps^;
Dispose(ps);

PS: обратите внимание, я также изменил ваш Integer() актерский состав на LPARAM(). Это очень важно, если вы когда-нибудь обновитесь до Delphi XE2 или новее. PostMessage() и SendMessage() использовать LPARAM, а не Integer. Вы можете избежать неприятностей в Delphi 7, потому что LPARAM - это псевдоним для Integer в этой версии, но это не так в современных версиях Delphi. LPARAM является псевдонимом для NativeUInt сейчас. LPARAM всегда был незапятнанным типом в Win32 API, Delphi просто ошибался в ранних версиях, но Embarcadero действительно настаивал на корректности типов в RTL / VCL, так как добавил поддержку 64-битной и кроссплатформенной развитие. Если вы не соответствуете правильным типам данных, вы можете вызвать ошибки проверки диапазона и тому подобное во время выполнения.

...