Show activity indicator while the main thread is blocked (continue)

前端 未结 3 1669
温柔的废话
温柔的废话 2021-02-04 20:35

Continue with previous question I want to be able to show some activity indicator even if the main thread is blocked. (based on this article).

Problems

3条回答
  •  渐次进展
    2021-02-04 20:52

    Initially this always crashed. Then I found the solution:

    1) Wrap the while loop inside a try-finally structure with FBitmap.Canvas.Lock;:

    FBitmap.Canvas.Lock;
    try
      while not Terminated do
      begin
        with FBitmap.Canvas do
        begin
          StretchDraw(FImageRect, FbkPattern);
          case State of
            incRight:
              begin
                Inc(Right, Increment);
                if Right > FImageRect.Right then
                begin
                  Right := FImageRect.Right;
                  Inc(State);
                end;
              end;
            incLeft:
              begin
                Inc(Left, Increment);
                if Left >= Right then
                begin
                  Left := Right;
                  Inc(State);
                end;
              end;
            decLeft:
              begin
                Dec(Left, Increment);
                if Left <= 0 then
                begin
                  Left := 0;
                  Inc(State);
                end;
              end;
            decRight:
              begin
                Dec(Right, Increment);
                if Right <= 0 then
                begin
                  Right := 0;
                  State := incRight;
                end;
              end;
          end;
    
          StretchDraw(Rect(Left, FImageRect.Top, Right, FImageRect.Bottom), FfgPattern);
        end; { with }
    
        // Synchronize(PaintTargetWindow); // not painting when the main thread is blocked
        PaintTargetWindow;
    
        SleepEx(FInterval, False);
      end; { While }
    finally
      FBitmap.Canvas.Unlock;
    end;
    

    2) In FormCreate of your application call this procedure:

    procedure DisableProcessWindowsGhosting;
    var
      DisableProcessWindowsGhostingProc: procedure;
    begin
      DisableProcessWindowsGhostingProc := GetProcAddress(GetModuleHandle('user32.dll'), 'DisableProcessWindowsGhosting');
      if Assigned(DisableProcessWindowsGhostingProc) then
        DisableProcessWindowsGhostingProc;
    end;
    

    Now it works perfectly - never crashed so far! Delphi XE2, Win7 x64

提交回复
热议问题