gpt4 book ai didi

multithreading - 如何使用 Delphi 从 Thread 更新 GUI

转载 作者:行者123 更新时间:2023-12-03 14:52:08 25 4
gpt4 key购买 nike

我正在使用Delphi匿名线程来执行代码。在线程中间,必须进行一些 GUI 更新、一些标签更改等。

如果我从线程内部执行此操作,更改就会发生,但一旦线程停止。它们消失了,然后应用程序给我旧的窗口处理程序错误...(这是预期的)

系统错误。代码:1400。无效的窗口句柄

我尝试使用 Syncronize(updateui); 方法来执行更改(将它们移至单独的函数),但我在syncronize 上收到错误 E2066 缺少运算符或分号 这对我来说根本没有意义......

我一页又一页地搜索,他们似乎都这样调用它,但是当我这样做时,我得到了上面的错误......

我是不是说错了?

代码:

TThread.CreateAnonymousThread(
procedure
begin
main.Enabled:=false;
Loading.show;
label52.caption:=getfieldvalue(datalive.users,'users','credit_amount','user_id',user_id );
CoInitialize(nil);
if (length(maskedit1.Text)=maskedit1.MaxLength) and (pingip(serverip)=true) then
begin
if (strtofloat(label52.caption)>0) then
begin
....do some work....

Synchronize(updateui);
end
else Showmessage('Insufficient Funds. Please add funds to continue.');
end
else if (length(maskedit1.Text)<>maskedit1.MaxLength) then
begin
Showmessage('ID Number not long enough.');
end
else
begin
Showmessage('Could not connect to the server. Please check your internet connection and try again.');
end;
CoUnInitialize;
loading.close;
main.Enabled:=true;
end).start;

更新用户界面:

procedure TMain.updateui;
var
birthdate,deathdate:TDate;
begin
Panel3.Show;

Label57.Caption := 'Change 1';
Label59.Caption := 'Change 2';
Label58.Caption := 'Change 3';
Label60.Caption := 'Change 4';
Label62.Caption := 'Change 5';
Label70.Caption := 'Change 6';


ScrollBox1.Color := clwhite;
end;

最佳答案

使用TThread.Synchronize并向其传递另一个匿名函数。然后你可以在匿名函数中调用updateui:

TThread.CreateAnonymousThread(
procedure
begin
// do whatever you want

TThread.Synchronize(nil,
procedure
begin
updateui();
end);

// do something more if you want
end
).Start();

同步通常很昂贵(就性能而言)。仅在确实有必要时才执行这些操作。如果扩展 updateui 方法来减少绘制操作,则可以提高性能。

可以调用 SendMessageWM_SETREDRAW :

procedure StopDrawing(const Handle: HWND);
const
cnStopDrawing = 0;
begin
SendMessage(Handle, WM_SETREDRAW, cnStopDrawing, 0);
end;

procedure ContinueDrawing(const Handle: HWND);
const
cnStartDrawing = 1;
begin
SendMessage(Handle, WM_SETREDRAW, cnStartDrawing, 0);

// manually trigger the first draw of the window
RedrawWindow(Handle, nil, 0,
RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;

updateui() 顶部添加对 StopDrawing() 的调用,并在末尾添加对 ContinueDrawing() 的调用em>updateui()。对 ContinueDrawing() 的调用应位于 finally-block 中。这将确保即使在执行 updateui 期间发生异常后也能绘制窗口。

示例:

procedure TMain.updateui;
begin
try
StopDrawing(Handle);

Panel3.Show;

Label57.Caption := 'Change 1';
Label59.Caption := 'Change 2';

// ...
finally
// Code under finally gets executed even if there was an error
ContinueDrawing(Handle);
end;
end;

关于multithreading - 如何使用 Delphi 从 Thread 更新 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31433680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com