Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Непонятное поведение Canvas.Handle


Автор: serI 7.1.2008, 15:48
Добрый вечер.
Вообще проблема такая, пишу клон арканойда, задание в универе.
Вот вроде сделал, осталось не так много. И столкнулся с тем что
Canvas.Handle самопроизвольно меняется, возможно ошибка в структуре классов  smile 

Кто может, гляньте пожалуйста код, может будут какие-нибудь рекомендации...

Game -> New Game если смотреть в отладчике то
Код

procedure TBoat.drawBoat(var psbd: TBitmap);
begin
  pFsbd:=psbd;
  BitBlt(Fbuf.Canvas.Handle, Fx, Fy, Fsprite.Width, Fsprite.Height, psbd.Canvas.Handle,0,0, SRCPAINT);
  BitBlt(psbd.Canvas.Handle, Fx, Fy, Fsprite.Width, Fsprite.Height, Fsprite.Canvas.Handle,0,0, SRCCOPY);
end;


psbd.Canvas.Handle - тут имеет одно значение

если нажать любую кнопку то
Код

procedure TGame.KeyDown(Key: Word; Shift: TShiftState);
begin
  FBoat.moveBoat(100,100);
  ReDraw;   // ? почему HANDLE дрУГОЙ!!
end;

procedure TBoat.moveBoat(x, y: Integer);  // и тут уже другой Handle соотвественно и рисует оно не там где надо (
begin
  BitBlt(pFsbd.Canvas.Handle, Fx, Fy, Fbuf.Width, Fbuf.Height, Fbuf.Canvas.Handle,0,0, SRCCOPY);
  Fx:=x;  Fy:=y;   
  BitBlt(pFsbd.Canvas.Handle, 300, 400, Fsprite.Width, Fsprite.Height, Fsprite.Canvas.Handle,0,0, SRCCOPY);
end;



Автор: MetalFan 7.1.2008, 20:00
да, меняется. и что? оно и должно меняться

Автор: serI 7.1.2008, 22:56
Цитата(MetalFan @ 7.1.2008,  20:00)
да, меняется. и что? оно и должно меняться

Интересное кино,
как же мне тогда передать ссылку на канву или битмап на котором bitblt сможет
рисовать если hadnle постоянно меняется...

Автор: MetalFan 7.1.2008, 23:28
дык не постоянно... а периодически)
непойму в какой момент у тебя чего меняется

Автор: maxim1000 8.1.2008, 00:37
Цитата(serI @  7.1.2008,  22:56 Найти цитируемый пост)
Интересное кино,
как же мне тогда передать ссылку на канву или битмап на котором bitblt сможет
рисовать если hadnle постоянно меняется...

так canvas же не меняется... меняется только handle: какое отношение это имеет к процессу передачи ссылок на canvas?

Автор: Alexeis 8.1.2008, 01:26
Canvas.Handle это DC - дескриптор который выдается на не продолжительное время, по прошествию которого становиться недействительным.

Автор: serI 8.1.2008, 09:51
Цитата(maxim1000 @ 8.1.2008,  00:37)
Цитата(serI @  7.1.2008,  22:56 Найти цитируемый пост)
Интересное кино,
как же мне тогда передать ссылку на канву или битмап на котором bitblt сможет
рисовать если hadnle постоянно меняется...

так canvas же не меняется... меняется только handle: какое отношение это имеет к процессу передачи ссылок на canvas?


Действительно объект должен оставаться самим собой, но если я взял canvas.handle и поместил его в myHandle 
и при этом не использовал  trylock, чтобы заблокировать handle. Он изменится и где-то в коде где используется myHandle, а не вызов canvas.handle произойдет ошибка, точнее вывод будет в пустоту. Собствено тот факт, что handle у canvas меняется с учетом выше изложенного привел меня в замешательство.

Значит Canvas обертка на DC, и включает в себя функции API MoveTo, LineTo... Просто когда используется чистое API там не каких TryLock нету, контекст он и в африке контекст



Автор: MetalFan 8.1.2008, 10:17
Цитата(serI @  8.1.2008,  09:51 Найти цитируемый пост)
Просто когда используется чистое API там не каких TryLock нету

ну так и получай HDC перед отрисовкой...

Автор: serI 8.1.2008, 10:38
Вообще спасибо всем кто откликнулся на зов о помощи. Разобрался вроде и сделал некоторые выводы:

Предположим у вас есть некоторая совокупность классов отражающая функциональность
вашей программы. И вам требуется передавать своим классам указатель на TCanvas формы
или друго обьекта со свойством Canvas. Рассмотрим возможные варианты:

1. Передать классу handle нужного canvas, но перед этим нужно обязательно заблокировать
handle вызовом метода trylock или lock.

2. Передать TCanvas по ссылке

и встречный вопрос 
Код

procedure Test(var cc: TCanvas)

и  

procedure Test(cc: TCanvas)

это одно и тоже? передача экземпляра класса по ссылке?
тогда var получает издержки производства   smile

Существует ли какая-либо статья в которая ставит все точки над i в 
особенности реализации классов в Delphi и их отличия от C++?

Автор: MetalFan 8.1.2008, 11:39
Цитата(serI @  8.1.2008,  10:38 Найти цитируемый пост)
и встречный вопрос

эта тема освещена в любом учебнике по паскалю

Автор: ivan219 8.1.2008, 14:04
Цитата(serI @  8.1.2008,  10:38 Найти цитируемый пост)
procedure Test(cc: TCanvas)

Вот так будет правильнее так как cc это не обект а ссылка на обект.
Правда есть один вопрос это копия ссылки или это таже самая ссылка???

Автор: Alexeis 8.1.2008, 15:00
Цитата(ivan219 @  8.1.2008,  13:04 Найти цитируемый пост)
Правда есть один вопрос это копия ссылки или это таже самая ссылка??? 

  Ссылка это такое понятие, что копия ссылки это по сути та же самая ссылка, потому совершенно никакой разницы, хотя самой ссылкой тут и не пахнет, тут просто везде копируется указатель на объект. В делфи вообще нет понятия ссылки как сущности, можно передать объект по ссылке в функцию как var параметр, но ссылка создается неявно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)