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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 01.04.2013, 23:02   #1
GrayDragon
Новичок
Джуниор
 
Регистрация: 01.04.2013
Сообщений: 2
По умолчанию Проблемы с TBitmap в потоке

Поискал по форуму подобные темы, нашел несколько, но нигде так и не было дано грамотного ответа, почему так происходит и как с этим бороться.

Собственно, сама проблема:
при использовании в потоке некоторых функций TBitmap (таких, как копирование канвы, загрузка изображений из файла) возникает системная ошибка №6 "неверный дескриптор".

Вот, набросал простой пример кода:
Код:
procedure TMyThread.Execute;
begin
  inherited;

  while not Terminated do
  begin
    CopyImage;
    sleep(1);
  end;
end;

procedure TMyThread.CopyImage;
var
  BM1, BM2  : TBitmap;
  Res       : LongBool;
begin
  BM1 := TBitmap.Create;
  BM2 := TBitmap.Create;
  try
    BM1.PixelFormat := pf24bit;
    BM2.PixelFormat := pf24bit;

    BM1.LoadFromFile('C:\1.bmp');
    if (BM1.Canvas.Handle = 0) or (BM1.Canvas.Handle = INVALID_HANDLE_VALUE) then
      raise Exception.Create('LoadFromFile: ' + SysErrorMessage(GetLastError));

    BM2.SetSize(BM1.Width, BM1.Height);
    Res := BitBlt(BM2.Canvas.Handle, 0, 0, BM2.Width, BM2.Height,
                  BM1.Canvas.Handle, 0, 0, SRCCOPY);

    if not Res then
      raise Exception.Create('BitBlt: ' + SysErrorMessage(GetLastError));
  finally
    BM1.Free;
    BM2.Free;
  end;
end;
При исполнении этого кода периодически возникает то первое исключение, то 2-е. Причем, чем меньше изображение 1.bmp, тем ошибка возникает чаще. Еще чаще ошибки возникают если "двигать" окно программы.
Естественно, если все это делать в основном потоке, то ошибок нет. Но это не интересно, т.к. что LoadFromFile, что BitBlt(StretchBlt) могут выполняться довольно продолжительное время (при большом объеме исходной бмпешки). По той же причине не интересен Synchronize. Да и вообще, по логике вещей synchronize тут не нужен, т.к. нет обращения к визуальным компонентам.

Если кто может что подсказать - буду очень признателен, а то уже мозг сломал. :-)
GrayDragon вне форума Ответить с цитированием
Старый 01.04.2013, 23:27   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

По моему при работе с канвас в многопоточном приложении нужно использовать Canvas.Lock перед изменением и соответственно Unlock после сохранения. Даже если эта канвас не имеет ни какого отношения к основному потоку. Вроде некая кривизна в VCL
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 01.04.2013 в 23:32.
Аватар вне форума Ответить с цитированием
Старый 02.04.2013, 00:37   #3
GrayDragon
Новичок
Джуниор
 
Регистрация: 01.04.2013
Сообщений: 2
По умолчанию

Спасибо большое! Действительно помогло, а то я уже не знал, в какую сторону рыть.
GrayDragon вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как из метода X в потоке А, вызвать метод Y и чтобы он работал в потоке B ? lawliet93 C# (си шарп) 0 09.03.2013 18:16
TBitmap stalker1995s Общие вопросы Delphi 2 08.03.2013 18:23
Создание/изменение/удаление файлов в потоке. Мониторинг файлов в потоке. The Real Kos Общие вопросы Delphi 5 22.10.2012 23:58
Можно ли использовать TBitMap в потоке? TwiX Мультимедиа в Delphi 10 29.09.2010 21:20
Thread. проблемы с работой потока. Моментально исчезают созданные в потоке формы. Casper-SC Общие вопросы .NET 3 24.04.2010 12:28