将字符串数据从线程发送到主窗体 [英] Send string data from Thread to main form

查看:127
本文介绍了将字符串数据从线程发送到主窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Dephi中,我创建了一个这样的线程,该线程将不时将消息发送到主表单中

In Dep I create a thread, like this, which will send message to main form from time to time

Procedure TMyThread.SendLog(I: Integer);
Var
  Log: array[0..255] of Char;
Begin
  strcopy(@Log,PChar('Log: current stag is ' + IntToStr(I)));
   PostMessage(Form1.Handle,WM_UPDATEDATA,Integer(PChar(@Log)),0);
End;

procedure TMyThread.Execute;
var
  I: Integer;
begin
  for I := 0 to 1024 * 65536 do
  begin
    if (I mod 65536) == 0 then
    begin
      SendLog(I);
    End;
  End;
end;

其中WM_UPDATEDATA是自定义消息,定义如下:

where WM_UPDATEDATA is a custom message, defined below:

const
  WM_UPDATEDATA = WM_USER + 100;

在主要形式下,它将执行以下操作以更新列表:

And in main form, it will do as follows to update the list:

procedure TForm1.WMUpdateData(var msg : TMessage);
begin
  List1.Items.Add(PChar(msg.WParam));
end;

但是,由于发送到主窗体的Log字符串是一个局部变量,在调用SendLog之后将销毁该变量. TForm1.WMUpdateData异步处理该消息时,因此,在调用该消息时,Log字符串可能已被破坏.如何解决这个问题?

However, as the Log string sent to the main form is a local variable, which will be destroyed after calling SendLog. While TForm1.WMUpdateData process the message asynchronously, so it is possible that when it is invoked, the Log string has already been destroyed. How to solve this problem?

我认为也许我可以在全局系统空间中分配字符串空间,然后将其传递给消息,然后在TForm1.WMUpdateData处理该消息之后,它可以破坏全局空间中的字符串空间.那是可行的解决方案吗?如何实现呢?

I think maybe I can allocate the string space in a global system space, and then pass it to the message, then after TForm1.WMUpdateData processes the message, it can destroy the string space in the global space. Is that a workable solution? How to implement this?

谢谢

推荐答案

如果您使用的是D2009或更高版本,则还有另一种方法可以将消息发布到您的主表单中. TThread.Queue 是来自线程的异步调用,其中有方法或过程可以在主线程中执行.

If you have D2009 or later version, there is another way to post messages to your main form. TThread.Queue is an asynchronous call from a thread, where a method or procedure can be executed in the main thread.

这里的优点是用于建立消息传递的框架不太复杂.在创建线程时只需传递回调方法即可.没有处理,也没有显式处理字符串分配/取消分配.

The advantage here is that the frame to set up the message passing is less complex. Just pass your callback method when creating your thread. No handles and no explicit handling of string allocation/deallocation.

Type
  TMyCallback = procedure(const s : String) of object;

  TMyThread = class(TThread)
    private
      FCallback : TMyCallback;
      procedure Execute; override;
      procedure SendLog(I: Integer);
    public
      constructor Create(aCallback : TMyCallback);
  end;

constructor TMyThread.Create(aCallback: TMyCallback);
begin
  inherited Create(false);
  FCallback := aCallback;
end;

procedure TMyThread.SendLog(I: Integer);
begin
  if not Assigned(FCallback) then
    Exit;
  Self.Queue(  // Executed later in the main thread
    procedure
    begin
      FCallback( 'Log: current stag is ' + IntToStr(I));
    end
  );
end;

procedure TMyThread.Execute;
var
  I: Integer;
begin
  for I := 0 to 1024 * 65536 do
  begin
    if ((I mod 65536) = 0) then
    begin
      SendLog(I);
    End;
  End;
end;


procedure TMyForm.TheCallback(const msg : String);
begin
  // Show msg
end;

procedure TMyForm.StartBackgroundTask(Sender : TObject);
begin
  ... 
  FMyThread := TMyThread.Create(TheCallback);
  ...
end;

这篇关于将字符串数据从线程发送到主窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆