Multithreading – how to update GUI from thread using Delphi

I am using Delphi anonymous thread to execute code

If I do this from within the thread, changes will occur, but once the thread stops They disappeared, and then the application gave me an old window handler error... (this is expected)

System error No.: 1400 Invalid window handle

I try to use synchronize (update UI); Execute the changed methods (move them to a separate function), but I get an error on the syncronize e2066 missing operator or semicolon, which makes no sense to me

I searched page after page, and they seemed to call it that, but when I did, I got the above error

Am I wrong?

Code:

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;

UpdateUI:

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';


Scroll@R_495_2419@1.Color := clwhite;
end;

Solution

Use TThread Synchronize and pass another anonymous function You can then call updateui in the anonymous function.

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

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

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

Synchronization is usually expensive (about performance) They can do it only when they really need it If you extend the updateui method to reduce drawing operations, you can improve performance

This can be done via WM_ Setredraw calls SendMessage:

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

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

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

Add a call to stopdrawing () at the top of updateui () and call continuedrawing () at the end of updateui () The call to continuedrawing () should be in finally - block This ensures that the window is drawn even after an exception occurs during the update UI execution

Example:

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;
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>