Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.10.2012, 01:39   #1
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию Канва и многопоточность (Canvas does not allow drawing)

Доброго времени суток!

Задача состоит в следующем. Есть поток, есть канва. В потоке нужно делать скриншот окна, и потом производить с ним определенные действия. Казалось бы, все просто - берем новую канву, устанавливаем ей нужный контекст устройства, копируем с одной канвы на другую с помощью CopyRect. Но именно в момент использования CopyRect приложение валится с исключением EInvalidOperation, выкидывая сообщение "Canvas does not allow drawing".

В сети вычитал, что дело именно в многопоточности - один поток залочил канву и второй теперь не в состоянии ее прочитать. Я попытался даже заново создавать целевую канву прямо в функции снятия скриншота, но толку ноль. Полный ее код такой (функция вызывается в потоке):
Код:
Screenshot = new TCanvas;
RECT* Rect = new RECT;
GetWindowRect(hTargetWindow, Rect);

TCanvas* canvas = new TCanvas;
canvas -> Handle = GetDC(hTargetWindow);
Screenshot -> CopyRect(TRect(0, 0, Rect -> right - Rect -> left, Rect -> bottom - Rect -> top), canvas, TRect(*Rect));
delete canvas;

delete Rect;
Естественно, в однопоточном варианте все нормально работает.

Подскажите, в чем тут проблема, или как вообще сделать скриншот в многопоточном приложении (используется он исключительно в том потоке, где и делается).
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 19.10.2012, 20:57   #2
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Проверил на совсем элементарном примере:
Код:
DWORD WINAPI f(LPVOID param)
   {
   TCanvas* canvas = new TCanvas;
   canvas -> Rectangle(10, 10, 210, 210);
   delete canvas;
   }
То же самое. А вот так работает:
Код:
DWORD WINAPI f(LPVOID param)
   {
   Graphics::TBitmap* img = new Graphics::TBitmap;
   img -> Canvas -> Rectangle(10, 10, 210, 210);
   delete img;
   }
Канва, оказывается, штука очень социальная. Сама по себе не хочет рисовать.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 19.10.2012, 22:36   #3
LynXzp
Пользователь
 
Аватар для LynXzp
 
Регистрация: 04.10.2012
Сообщений: 95
По умолчанию

Вообще-то VCL не потокобезопасная библиотека.

Когда создаешь поток видишь комментарий в исходном коде? Вот-вот, а там это написано и как обойти.

Смотри функцию synchronize. Вся работа с VCL только в одном потоке. С помощью этой функции вызываемой из второго потока, приостанавливаются потоки 1 и 2, и происходит выполнение функции в контексте первого потока (сама функция находится в cpp файле второго потока). Для вызова synchronize нужно передать адрес функции, ест-но никаких возвращаемых и принимаемых параметров. Поэтому все параметры через глобальные (в файле / потоке) переменные.
Пишу на чистом С, плюсы спилил.
LynXzp вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Canvas does not allow drawing andrey.vadimovich Общие вопросы Delphi 1 17.06.2012 20:24
Canvas does not allow drawing kettanaito Компоненты Delphi 5 12.01.2012 23:54
System.Drawing.dcuil KyzDmitry Компоненты Delphi 3 14.08.2009 17:08
Error: "Canvas does not allow drawing", Delphi7 VVM Общие вопросы Delphi 2 19.07.2009 16:38
Canvas (Канва) - заливка фигуры произвольной формы Albenous Общие вопросы Delphi 13 24.02.2007 13:21