TBitmap.Canvas suffer from same issue that I have when trying to use ShowMessage() - TForm.Canvas - in a multithread application. This piece of code in dialog.pas causes randomly AV's, 'cause the Canvas DC get's freed by main thread.
function GetAveCharSize(Canvas: TCanvas): TPoint; var I: Integer; Buffer: array[0..51] of Char; begin for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A')); for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a')); GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result)); Result.X := Result.X div 52; end;
My current solution, I just change the code to:
Function GetAveCharSize(Canvas: TCanvas): TPoint; Var I: Integer; Buffer: Array[0..51] Of Char; Begin For I := 0 To 25 Do Buffer[I] := Chr(I + Ord('A')); For I := 0 To 25 Do Buffer[I + 26] := Chr(I + Ord('a')); If IsMultiThread Then Canvas.Lock; Try GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result)); Finally If IsMultiThread Then Canvas.Unlock; End; Result.X := Result.X Div 52; End;
So, it's detect's via "IsMultiThread" function, if there is another thread, doing the lock to prevent problems... in normal applications - single threaded - the lock is never called, since there is no time to garbage collector cut the DC of canvas...