How to update GUI from Thread using Delphi

后端 未结 1 1447
名媛妹妹
名媛妹妹 2020-12-18 02:24

I am using Delphi anonymous thread to execute code. In the middle of the thread, a couple of GUI updates have to take place, a couple of labels changing etc.

If I do

相关标签:
1条回答
  • 2020-12-18 03:04

    Use TThread.Synchronize and pass another anonymous function to it. Then you can 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();
    

    Synchronizations are generally expensive (regarding performance). Only do them when they are really neccessary. You can increase the performance if you extend the updateui-method to reduce paint-operations.

    This is possible to a call to SendMessage with WM_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;
    

    Add a call to StopDrawing() at the top of updateui() and a call to ContinueDrawing() at the end of updateui(). The call to ContinueDrawing() should be in a finally-block. This will ensure that the window will be painted even after an exception has occured during the execution of updateui.

    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;
    
    0 讨论(0)
提交回复
热议问题