![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
EOutOfResources [D7, WinXP]
Handle © (2006-05-05 10:08:00)Подскажите где ошибка, возникает
EOutOfResourcesчерез некоторое время и как исправить?
procedure TForm1.Timer1Timer(Sender: TObject);
var
P: TPoint;
bmp: TBitmap;
DC: HDC;
begin
Timer1.Interval:= 1;
Image1.Picture:= nil;
GetCursorPos(P);
bmp:=TBitmap.Create;
bmp.Height:=Screen.Height;
bmp.Width:=Screen.Width;
DC:=GetDC(0);
BitBlt(bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height,
DC, P.X, P.Y , SRCCOPY);
bmp.Width:= 32;
bmp.Height:= 32;
Image1.Picture.Bitmap:= bmp;
bmp.Free;
ReleaseDC(0, DC);
end;
ancara (2006-05-06 12:27:00) [1]>У чего здесь убийственного?
Хм, и правда, ничего. Что ж, сорри, погорячился. :)
Просто я не удосужился проверить, а сделал поспешный вывод. Ведь если мы
присвоим указателю на объект значение nil, а затем попытаемся вызвать метод у этого объекта, эти дейстия должны будут привести к AV, не так ли?
Но в случае с TPicture.Bitmap этого не происходит, я так думаю в связи с тем, что
в методе TPicture.GetBitmap присутствует вызов
ForceType(TBitmap);
который и воссоздает объект FGraphic (в этом случае типа TBitmap)
ДО ТОГО, как мы обратимся к его методам.
Я просто пытаюсь найти объяснение этому "явлению".
В чем я ошибаюсь?
А в процедуре автора вопроса локальная переменная bmp действительно лишняя, можно же в таймере сразу с десктопа копировать на Picture.Bitmap.Canvas, тем же BitBlt?
ЮЮ (2006-05-06 03:50:00) [2]
>
> > Image1.Picture.Bitmap := nil;
> > Image1.Picture.Bitmap.Assign(bmp);
>
> убийственно.
У чего здесь убийственного? Первый оператор вовсе не означает потери ссылки на объект TBitmap, а его уничтожение.
Без этого Image1 не хотел перерисовываться, правда тогда я пытался использовать Image1.Picture.Bitmap, а не пересоздавать bmp в таймере.
При создании каждый раз нового экземпляра TBitmap - это лишнее.
ancara (2006-05-05 15:09:00) [3]
> Image1.Picture.Bitmap := nil;
> Image1.Picture.Bitmap.Assign(bmp);
убийственно.
Мне кажется надо перед запуском таймера создать bitmap на Image:
Image1.Picture.Bitmap := TBitmap.Create;
Image1.Picture.Bitmap.Width:=32;
Image1.Picture.Bitmap.Height:=32;
а в таймере делать так
//тут создание bmp и получение картинки с десктопа
//все как было написано выше...
Image1.Picture.Bitmap.Canvas.Draw(0,0, bmp);
bmp.Free;
han_malign (2006-05-05 14:59:00) [4]Image1.Picture.Bitmap.Handle:= bmp.ReleaseHandle;
bmp.Free;
ЮЮ (2006-05-05 12:34:00) [5]Похоже, все дело в изменении размеров непустого TBitmap.
Такой код, похоже, не жрет лишних ресурсов:
procedure TForm1.Timer1Timer(Sender: TObject);
var
P: TPoint;
bmp: TBitmap;
DC: HDC;
begin
bmp:=TBitmap.Create;
bmp.Width:= 32;
bmp.Height:= 32;
DC:=GetDC(0);
try
Timer1.Interval:= 1;
GetCursorPos(P);
BitBlt(bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height,
DC, P.X, P.Y , SRCCOPY);
Image1.Picture.Bitmap := nil;
Image1.Picture.Bitmap.Assign(bmp);
finally
bmp.Free;
ReleaseDC(0, DC);
end;
end;
Да и проц на 100% не грузит :) На кой тебе весь экран в BitBlt, если интересует только 32х32 ?
evvcom (2006-05-05 11:48:00) [6]
> А ещё лучше вместо
> > Image1.Picture.Bitmap:= bmp;
> использовать
> Image1.Picture.Assign(bmp);
> и в этом случае bmp.Free остаётся.
Там (в TPicture.SetGraphic) собственно и делается Assign(bmp).
Хотя и в TImage.SetPicture делается FPicture.Assign(Value). Поэтому
> Вместо Picture:= nil освобождай Picture.Bitmap.
вроде как тоже не причина. Взгляд был поверхностный, с графикой особо не работал, так что может в чем-то и не прав. Но я бы, наверное, MemProof все же погонял.
Плохиш (2006-05-05 10:36:00) [7]А ещё лучше вместо
> Image1.Picture.Bitmap:= bmp;
использовать
Image1.Picture.Assign(bmp);
и в этом случаеbmp.Freeостаётся.
Плохиш (2006-05-05 10:31:00) [8]
> Image1. Picture:= nil;
..
> bmp:=TBitmap.Create;
..
> Image1. Picture.Bitmap:= bmp;
> bmp.Free;
Что делаем?
После такого, возникающая ошибка является самой безопасной.
ВместоPicture:= nilосвобождай Picture.Bitmap. А строчкуbmp.Freeвыкинуть нафик.