【问题标题】:Postmessage LParam truncationPostmessage LParam 截断
【发布时间】:2012-03-29 19:30:28
【问题描述】:

我的应用程序有一个工作线程,我使用 PostMessage 向主线程发送一个字符串。对于 1 条消息,字符串在到达主线程中的消息处理程序时会被截断。

字符串是在工作线程中从一串像这样的原始数据构造的。它在最后一个 '20' 结束。

'01010000000030000102000008850008855343414E204544474520000000000000000000'

解码成我要发送的字符串看起来是这样的,没错:

'0100 0.50000 LSB0288.588.5扫描边缘'

创建“扫描边缘”部分并发布它的代码是: 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

我该如何纠正这个问题?

【问题讨论】:

    标签: multithreading delphi delphi-7 postmessage


    【解决方案1】:

    您正在发布一个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 位和跨平台的支持发展。如果您没有正确匹配正确的数据类型,则可能会在运行时导致范围检查错误等。

    【讨论】:

    • 它只能在同一个进程中工作。对于使用消息的进程间通信,请使用 WM_COPY,它将按预期编组内容。
    • 你想的是WM_COPYDATA
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 2012-10-29
    • 1970-01-01
    • 2012-06-02
    • 2016-07-15
    • 2023-03-31
    • 2018-10-12
    相关资源
    最近更新 更多