- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在Dephi中,我创建了一个线程,像这样,它会不时向主窗体发送消息
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 是自定义消息,定义如下:
const
WM_UPDATEDATA = WM_USER + 100;
在主窗体中,它将执行以下操作来更新列表:
procedure TForm1.WMUpdateData(var msg : TMessage);
begin
List1.Items.Add(PChar(msg.WParam));
end;
但是,由于发送到主窗体的Log字符串是一个局部变量,调用SendLog后该变量就会被销毁。而 TForm1.WMUpdateData 异步处理消息,因此当调用它时,Log 字符串可能已经被销毁。如何解决这个问题?
我想也许我可以在全局系统空间中分配字符串空间,然后将其传递给消息,然后TForm1.WMUpdateData处理消息后,可以销毁全局空间中的字符串空间。这是一个可行的解决方案吗?如何实现这个?
谢谢
最佳答案
除了您发布局部变量这一事实之外,TWinControl.Handle
属性也不是线程安全的。您应该使用 TApplication.Handle
属性,或者使用 AllocateHWnd()
创建您自己的窗口。
您确实需要在堆上动态分配字符串,将该指针发布到主线程,然后在使用完毕后释放内存。
例如:
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMessage;
// or use a TApplicationEvents component...
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Application.OnMessage := nil;
end;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var
S: PString;
begin
if Msg.Message = WM_UPDATEDATA then
begin
S := PString(msg.LParam);
try
List1.Items.Add(S^);
finally
Dispose(S);
end;
Handled := True;
end;
end;
procedure TMyThread.SendLog(I: Integer);
var
Log: PString;
begin
New(Log);
Log^ := 'Log: current stag is ' + IntToStr(I);
if not PostMessage(Application.Handle, WM_UPDATEDATA, 0, LPARAM(Log)) then
Dispose(Log);
end;
或者:
var
hLogWnd: HWND = 0;
procedure TForm1.FormCreate(Sender: TObject);
begin
hLogWnd := AllocateHWnd(LogWndProc);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if hLogWnd <> 0 then
DeallocateHWnd(hLogWnd);
end;
procedure TForm1.LogWndProc(var Message: TMessage);
var
S: PString;
begin
if Message.Msg = WM_UPDATEDATA then
begin
S := PString(msg.LParam);
try
List1.Items.Add(S^);
finally
Dispose(S);
end;
end else
Message.Result := DefWindowProc(hLogWnd, Message.Msg, Message.WParam, Message.LParam);
end;
procedure TMyThread.SendLog(I: Integer);
var
Log: PString;
begin
New(Log);
Log^ := 'Log: current stag is ' + IntToStr(I);
if not PostMessage(hLogWnd, WM_UPDATEDATA, 0, LPARAM(Log)) then
Dispose(Log);
end;
关于multithreading - 将字符串数据从线程发送到主窗体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19060027/
对于一个科学实验,我写了一个turtle.py ,它会打开一个 800x480 的窗口并绘制一个缓慢增长的黑点。 turtle.py以 C:\Users\kaza>python C:\Users\ka
我开发了一个 swing 应用程序,但每次运行应用程序时都会打开一个新窗口。我希望如果一个窗口已经打开,则其他窗口不允许打开。 最佳答案 Here是一个 Java 单一应用实例的例子: A singl
有没有办法检测主进程中 Electron 的结构? process.platform 似乎也在 x64 机器上返回 win32,我没有在文档中找到任何获取架构的选项。 最佳答案 你试过 process
public short[] HanningWindow(short[] signal_in ,int pos ,int size) { for (int i= pos; i < pos+si
我有一个具有这些属性的 Electron 窗口: mainWindow = new BrowserWindow({ width: 800, height: 600, title: "Aqu
我有一个 Ubuntu 工作站,我正在尝试引导一个 Windows 节点。 Windows 节点在端口 2222 上打开了 ssh。我一直在关注 http://docs.opscode.com/plu
我是一名优秀的程序员,十分优秀!