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