Delphi - 将记录作为窗口消息发送

use*_*073 3 delphi message record

Delphi Tokyo - 我想通过Windows Messages在表单之间发送记录结构.具体来说,我有一个"显示运行状态"类型的窗口.当行为发生在我的应用程序的其他地方时,我需要发送一个"更新状态窗口"类型的消息.我找到了一个通过Windows消息传递记录的示例(但只在同一个进程中),但是我遇到了使它工作的问题.具体来说,在接收方,我无法编译Windows消息处理程序代码.我有一个'不兼容类型'错误,但我无法弄清楚如何进行类型转换以使其正常工作.以下是适用的代码段.

在globals.pas单元中,所有单元都可以访问.

// Define my message
  const WM_BATCHDISPLAY_MESSAGE = WM_USER + $0001;
...
// Define the record which is basically the message payload
type
 TWMUCommand = record
    Min: Integer;
    Max: Integer;
    Avg: Integer;
    bOverBudget: Boolean;
    Param1: Integer;
    Param2: String;
  end;

...
// define a global variable
PWMUCommand : ^TWMUCommand;
Run Code Online (Sandbox Code Playgroud)

现在发送消息.这只是一个按钮,以便测试.

procedure TMainForm.BitBtn1Click(Sender: TObject);
var
  msg_prm: ^TWMUCommand;
begin
  New(msg_prm);
  msg_prm.Min := 5;
  msg_prm.Max := 10;
  msg_prm.Avg := 7;
  msg_prm.bOverBudget := True;
  msg_prm.Param1 := 0;
  msg_prm.Param2 := 'some string';
  PostMessage(Handle, WM_BATCHDISPLAY_MESSAGE, 0, Integer(msg_prm));
end;
Run Code Online (Sandbox Code Playgroud)

在接收表单上,也就是我的状态表单...声明我的消息监听器

procedure MessageHandler(var Msg: TMessage); message WM_BATCHDISPLAY_MESSAGE;
Run Code Online (Sandbox Code Playgroud)

现在定义消息处理程序.

procedure TBatchForm.MessageHandler(var Msg: TMessage);
var
   msg_prm: ^TWMUCommand;
begin
  try

    // Next line fails with Incompatible types
    msg_prm := ^TWMUCommand(Msg.LParam);
    ShowMessage(Format('min: %d; max: %d; avg: %d; ovrbdgt: %s; p1: %d; p2: %s',
                [msg_prm.Min, msg_prm.Max, msg_prm.Avg, BoolToStr(msg_prm.bOverBudget, True),
                 msg_prm.Param1, msg_prm.Param2]));
  finally
    Dispose(msg_prm);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如何将Msg.LParam重新投射到记录结构中?

Dav*_*nan 7

首先,为记录声明指针类型更容易:

type
  PWMUCommand = ^TWMUCommand;
  TWMUCommand = record
    ...
  end;
Run Code Online (Sandbox Code Playgroud)

然后在发布消息的方法中,将指针声明为PWMUCommand.

您的Integer演员假设为32位代码.最好转换为该论证的真实类型LPARAM.

PostMessage(..., LPARAM(msg_prm));
Run Code Online (Sandbox Code Playgroud)

在函数中接收消息,使用指针类型声明局部变量:

var
  msg_prm: PWMUCommand;
Run Code Online (Sandbox Code Playgroud)

把它像这样:

msg_prm := PWMUCommand(Msg.LParam);
Run Code Online (Sandbox Code Playgroud)

请注意,当您打电话时PostMessage,应检查返回值以防发生故障.如果失败,那么你需要处理内存.

if not PostMessage(..., LPARAM(msg_prm)) then
begin
  Dispose(msg_prm);
  // handle error
end;
Run Code Online (Sandbox Code Playgroud)

最后,正如我认为你知道的那样,这种方法只有在发送方和接收方处于同一进程中时才有效.