Сообщение об ошибке «Блокировка объекта не принадлежит» - это сообщение EMonitorLockException
, которое задокументировано, чтобы вызываться «всякий раз, когда поток пытается снять блокировку на не принадлежащем монитору».Поскольку вы не ответили на мой запрос о MCVE, и я не смог воспроизвести эту ошибку, я не могу подтвердить, связана ли она с неудачной установкой блокировки через Canvas.BeginScene
или с чем-то еще.
Вы можете использовать TImage
или TPaintBox
для вашего рисунка.Использование TImage
дает много преимуществ, таких как прямая загрузка файла изображения, рисование на этом изображении и сохранение вашего изображения в файл непосредственно в различных форматах, таких как .bmp
, .jpg
или .png
(возможно, и другие).TPaintBox
является более легким и не имеет собственного растрового изображения, но использует поверхность родительских компонентов для рисования (следовательно, необходим обработчик OnPaint()
).Загрузка из файла / его сохранение в файл должны выполняться, например, с помощью отдельной карты TBitmap.
Так что да, вы можете продолжать использовать элемент управления TImage, если хотите, но в этом случае не используйте событие OnPaint
длярисунок как ты сейчас.TImage имеет встроенный механизм для рисования себя, когда это необходимо.Вам нужно только один раз нарисовать рисунок на встроенном растровом холсте.В следующем коде изображение нарисовано в событии ButtonClick()
.Также обратите внимание, что с изображением TImage вы должны правильно использовать BeginScene
- EndScene
, как описано в документе.
Вы также должны установить TImage.Bitmap.Size
перед тем, как рисовать на нем.Если это не было указано в другом месте в вашем коде того, что вы показали, то это может быть еще одна причина, по которой ваш код не создавал изображения.
Нарисуйте свое изображение на Image1.Bitmap.Canvas
, например, в OnClick()
событиикнопка:
procedure TTabbedForm.Button1Click(Sender: TObject);
var
p1, p2, p3, p4, p5, p6: TPointF;
prst1: TRectF;
i: integer;
begin
Image1.Bitmap.SetSize(300, 300); // must be set before call to BeginScene
if Image1.Bitmap.Canvas.BeginScene then
try
Image1.Bitmap.Canvas.Stroke.Color := TAlphaColors.Black;
Image1.Bitmap.Canvas.Stroke.Thickness := 1;
p1 := TPointF.Create(px, py);
for i := 0 to 360 do
if (i mod 15) = 0 then
begin
pp := i;
p2 := TPointF.Create(Round(px + pp * sin(i * pi / 180)),
Round(py + pp * cos(i * pi / 180)));
Image1.Bitmap.Canvas.DrawLine(p1, p2, 100);
end;
for i := 0 to pp do
...
for i := 0 to 400 do
...
for i := 0 to 400 do
....
finally
Image1.Bitmap.Canvas.EndScene;
end;
end;