Ошибка — Canvas does not allow drawing |
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|
|
Windows 8.1 |
|
Популярное |
|
I want to Draw a Screenshot from the entire screen to a TForm1 Canvas.
This code works well in Delphi XE3
procedure TForm1.Button1Click(Sender: TObject);
var
c,scr: TCanvas;
r,r2: TRect;
begin
c := TCanvas.Create;
scr := TCanvas.Create;
c.Handle := GetWindowDC(GetDesktopWindow);
try
r := Rect(0, 0, 200, 200);
form1.Canvas.CopyRect(r, c, r);
finally
ReleaseDC(0, c.Handle);
c.Free;
end;
Now I want to copy the screenshot to another canvas first.
Is there a way to do this without getting this error?
procedure TForm1.Button1Click(Sender: TObject);
var
c,scr: TCanvas;
r,r2: TRect;
begin
c := TCanvas.Create;
scr := TCanvas.Create;
c.Handle := GetWindowDC(GetDesktopWindow);
try
r := Rect(0, 0, 200, 200);
scr.CopyRect(r,c,r); <-- Error, canvas does not allow drawing
form1.Canvas.CopyRect(r, scr, r); <-- Error, canvas does not allow drawing
finally
ReleaseDC(0, c.Handle);
c.Free;
end;
В чем вопрос-то? Куда нажать, чтобы увидеть? На свежей альфе? Знаете-ка что…. Этой ошибке ТРИСТА ЛЕТ! Посмотрите на дату исходного сообщения — март 2006 года.
Никуда не нажать. Эта ошибка возникает сама по себе и непредсказуемо. И чем дальше бат деградирует (с увеличением номера версии) — тем чаще.
Я ж сказал — на форумах по дельфи про такую проблему знают, знают про ее причины и знают, что надо делать, чтобы она не возникала. И всяких новичков терпеливо учат, как надо программировать многопоточные приложения.
Также, когда я искал информацию об этой ошибке, я видел много релизов РАЗНЫХ программ, в описании к которым было указано, что в этой версии «исправлена ошибка, приводящая к Canvas does not allow drawing и к Acsess violation at address».
Отрицать очевидное бессмысленно — ошибка в Бате есть, и причина ее — корявое программирование, рассинхронизация процессов, утечки памяти.
Беда в том, что эту ошибку в Бате уже НИКОГДА не исправить!!! Слишком все запущено. Я представляю, сколько кода надо перелопатить. А код уже давно такой, что в одном месте тронешь — в трех других сразу рассыпается.
Solution 1
If you need to work with an additional canvas you will have to assign a HDC e.g.
var
WindowHandle:HWND;
ScreenCanvas,BufferCanvas: TCanvas;
r,r2: TRect;
ScreenDC,BufferDC :HDC;
BufferBitmap : HBITMAP;
begin
WindowHandle := 0;
ScreenCanvas := TCanvas.Create;
BufferCanvas := TCanvas.Create;
ScreenDC:=GetWindowDC(WindowHandle);
ScreenCanvas.Handle := ScreenDC;
BufferDC := CreateCompatibleDC(ScreenDC);
BufferCanvas.Handle := BufferDC;
BufferBitmap := CreateCompatibleBitmap(ScreenDC,
GetDeviceCaps(ScreenDC, HORZRES),
GetDeviceCaps(ScreenDC, VERTRES));
SelectObject(BufferDC, BufferBitmap);
try
r := Rect(0, 0, 200, 200);
BufferCanvas.CopyRect(r,ScreenCanvas,r);
form1.Canvas.CopyRect(r, BufferCanvas, r);
finally
ReleaseDC(WindowHandle, ScreenCanvas.Handle);
DeleteDC(BufferDC);
DeleteObject(BufferBitmap);
BufferCanvas.Free;
ScreenCanvas.Free;
end;
end;
Solution 2
It’s a time to toss my solution into the pot!
procedure TForm1.FormClick(Sender: TObject);
var
ScreenCanvas: TCanvas;
begin
ScreenCanvas := TCanvas.Create;
try
ScreenCanvas.Handle := GetWindowDC(GetDesktopWindow);
Win32Check(ScreenCanvas.HandleAllocated);
Canvas.CopyRect(Canvas.ClipRect, ScreenCanvas, ScreenCanvas.ClipRect);
finally
ReleaseDC(GetDesktopWindow, ScreenCanvas.Handle);
ScreenCanvas.Free;
end;
end;
Comments
-
I want to Draw a Screenshot from the entire screen to a TForm1 Canvas.
This code works well in Delphi XE3
procedure TForm1.Button1Click(Sender: TObject); var c,scr: TCanvas; r,r2: TRect; begin c := TCanvas.Create; scr := TCanvas.Create; c.Handle := GetWindowDC(GetDesktopWindow); try r := Rect(0, 0, 200, 200); form1.Canvas.CopyRect(r, c, r); finally ReleaseDC(0, c.Handle); c.Free; end;
Now I want to copy the screenshot to another canvas first.
Is there a way to do this without getting this error?procedure TForm1.Button1Click(Sender: TObject); var c,scr: TCanvas; r,r2: TRect; begin c := TCanvas.Create; scr := TCanvas.Create; c.Handle := GetWindowDC(GetDesktopWindow); try r := Rect(0, 0, 200, 200); scr.CopyRect(r,c,r); <-- Error, canvas does not allow drawing form1.Canvas.CopyRect(r, scr, r); <-- Error, canvas does not allow drawing finally ReleaseDC(0, c.Handle); c.Free; end;
-
Once you do that,
scr
is rather pointless. You may as well just draw directly tobmp.Canvas
. -
@RobKennedy I know it was an example, could have been another DC too.
-
This is very tangled and intricate example: you don’t that excess canvas at all, it is actually a unobvious clone of bmp’s MemDC.
Recents
Related
kessor 4 / 4 / 2 Регистрация: 27.10.2014 Сообщений: 90 |
||||
1 |
||||
15.02.2016, 13:09. Показов 9798. Ответов 6 Метки нет (Все метки)
после N запусков вот этой функции
программа вылетает с ошибкой canvas does not allow drawing
0 |
Пишу на Delphi…иногда 1423 / 1278 / 286 Регистрация: 03.12.2012 Сообщений: 3,914 Записей в блоге: 5 |
|
15.02.2016, 13:25 |
2 |
как исправить? GetWindowDC After painting is complete, the ReleaseDC function must be called to release the device context. Not releasing the window device context has serious effects on painting requested by applications.
0 |
kessor 4 / 4 / 2 Регистрация: 27.10.2014 Сообщений: 90 |
||||
15.02.2016, 14:06 [ТС] |
3 |
|||
то есть просто добавить строчку
?
0 |
588 / 455 / 147 Регистрация: 09.12.2013 Сообщений: 2,385 Записей в блоге: 2 |
|
15.02.2016, 16:20 |
4 |
Зачем вообще TCanvas? Просто HDC возьмите. И да, освобождать надо.
canvas does not allow drawing Это логически не может быть из-за показанного кода. Вы там ничего не рисуете. В другом месте наверное что-то делается. Добавлено через 22 секунды
0 |
kessor 4 / 4 / 2 Регистрация: 27.10.2014 Сообщений: 90 |
||||
15.02.2016, 17:27 [ТС] |
5 |
|||
а так можно цвет пикселя получать?
0 |
BOGG ART 588 / 455 / 147 Регистрация: 09.12.2013 Сообщений: 2,385 Записей в блоге: 2 |
||||
15.02.2016, 18:40 |
6 |
|||
РешениеЯ же говорю — возьмите переменную HDC, освобождайте.
1 |
4 / 4 / 2 Регистрация: 27.10.2014 Сообщений: 90 |
|
18.02.2016, 17:03 [ТС] |
7 |
после ~100 итераций начинает выдавать всегда одно и то же значение(для G — 255)
0 |