Postmessage LParam truncation

天大地大妈咪最大 提交于 2019-12-08 04:09:32

问题


My app has a worker thread, and I use PostMessage to send a string to the main thread. For 1 message, the string is truncated when it gets to the message handler in the main thread.

The string is constructed in the worker thread from a string of raw data that is like this. It ends at the last '20'.

'01010000000030000102000008850008855343414E204544474520000000000000000000'

Decoded into the string I want to send it looks like this, which is correct:

'0100 0.50000 LSB0288.588.5SCAN EDGE '

The code that creates the 'SCAN EDGE ' portion and posts it is: tmp and s_out are strings

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)));

The message handler in the main thread is: i is a string

i := pChar(msg.LParam);

when it gets to the main thread i looks like this in the debugger:

'0100 0.50000 LSB0288.588.5SCAN EDG'#0

How can I correct this?


回答1:


You are posting the contents of a String variable that is local to the thread procedure that is calling PostMessage(). If the String goes out of scope and gets freed before the main thread processes the posted message, the memory will be garbage.

You need to either:

1) use SendMessage() instead of PostMessage() so the String stays in scope until the message handler exits:

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

2) dynamically allocate a String in memory, fill it as needed, post it, and then let the main message handler free it when it is done copying it:

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: notice I also changed your Integer() cast to LPARAM(). This is very important if you ever upgrade to Delphi XE2 or later. PostMessage() and SendMessage() use LPARAM, not Integer. You can get away with it in Delphi 7 because LPARAM is an alias for Integer in that version, but that is not the case anymore in modern Delphi versions. LPARAM is an alias for NativeUInt now. LPARAM has always been an unsinged type in the Win32 API, Delphi just got it wrong in the early versions, but Embarcadero has really been pushing for type-correctness in the RTL/VCL since adding support for 64-bit and cross-platform development. If you don't match the right data types correctly, you can cause range checks errors and such at runtime.



来源:https://stackoverflow.com/questions/9932164/postmessage-lparam-truncation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!