![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DoubleBuffered:=true [D6, WinXP]
MixAnOL © (2006-03-10 16:41:00)Здорово всем!
Возникла проблема с сабжем.
Ситуация: есть несколько TImage на форме, некоторые из них прозрачные. При нажатии на кнопку перерисовывается одно из прозрачных имаджей. Для предотвращения моргания всего этого хозяйства указал сабж для формы.
При нажатии на кнопку, и перерисовке рисунка кот. должен при этом обновляться загрузка приложения составляет 100%.
Пытался оптимизировать что бы не было такой загрузки, переписал перерисовку через ScanLine в памяти и без прозрачности, но результат только чуть-чуть улучшился, до процентов 90-95...
Попробовал отключить сабж - и о чудо, все стало быстро, но моргает....
Как же мне избавиться от моргания?
MixAnOL (2006-03-10 19:04:00) [1]понял))) спасибо...
API (2006-03-10 19:02:00) [2]но мне нужно чтобы вся строка выделялась
Ну так и рисуйте выделение отдельно. А данную функцию я привел, чтобы Вы не делали вот этого:
if tempBmp.Canvas.TextWidth(s)>r.Right then // укорачивание строки
begin
while tempBmp.Canvas.TextWidth(s+'...')>=r.Right do
s:=copy(s,1,length(s)-1);
s:=s+'...';
MixAnOL (2006-03-10 18:53:00) [3]
DrawText(tempBMP.Canvas.Handle, PChar(s), Length(s), r,
DT_LEFT or DT_END_ELLIPSIS or DT_SINGLELINE);
хорош, но мне нужно чтобы вся строка выделялась, а не только фон текста...
MixAnOL (2006-03-10 18:47:00) [4]Добавил csOpaque в свойства и все стало нормально!
Только я так и не понял что такое csOpaque, зачем это надо... Хотя в хелпарь заглянул...
API (2006-03-10 18:44:00) [5]
if tempBmp.Canvas.TextWidth(s)>r.Right then // укорачивание строки
begin
while tempBmp.Canvas.TextWidth(s+'...')>=r.Right do
s:=copy(s,1,length(s)-1);
s:=s+'...';
end;
tempBmp.Canvas.TextRect(r,2,h*(i-LBAlbums.TopIndex)+1,s);
Это все - в одну строку:
DrawText(tempBMP.Canvas.Handle, PChar(s), Length(s), r,
DT_LEFT or DT_END_ELLIPSIS or DT_SINGLELINE);
Это подправьте:
for i:=LBAlbums.TopIndex to LBAlbums.TopIndex+(LBAlbums.Height div LBAlbums.ItemHeight) do
if ((i-LBAlbums.TopIndex)<=count-1)and(i<LBAlbums.Count)
Но вообще, я ничего криминального не вижу.
Вы уверены, что нет множественной прорисовки?
API (2006-03-10 18:32:00) [6]Для того что бы не делать его прозрачным, я скопировал фон под этим имаджом и на нем рисую
Тогда зачем DoubleBuffered? Установите csOpaque для Image, и рисуйте.
Для формы обрабатывайте WM_ERASEBKGND, чтобы лишний раз не мигала.
Привели бы код отрисовки, а?
MixAnOL (2006-03-10 18:29:00) [7]Вот процедура перерисовки, так как много применял способов, то тут есть и мусор, вроде как безвредный...
procedure RedrawImage;
var
i: integer;
r,r2: TRect;
s: string;
line,line2: PByteArray;
begin
r.Left:=1;
r.Right:=Image.Width;
r.Top:=1;
r.Bottom:=Image.Height;
r2:=r;
tempBmp.Canvas.Font.Name:='Times New Roman';
tempBmp.Canvas.Font.Size:=12;
tempBmp.Canvas.Font.Color:=clBlack;
tempBmp.Canvas.Brush.Style:=bsClear;
tempBmp.Assign(BmpFon);
for i:=LBAlbums.TopIndex to LBAlbums.TopIndex+(LBAlbums.Height div LBAlbums.ItemHeight) do
if ((i-LBAlbums.TopIndex)<=count-1)and(i<LBAlbums.Count) then // ограничение по длине списка
begin
r.Top:=h*(i-LBAlbums.TopIndex)+1;
r.Bottom:=h*(i-LBAlbums.TopIndex)+h;
s:=LBAlbums.Items[i];
if s[1]<>' ' then
s:=' '+s;
if LBAlbums.ItemIndex=i then
begin
tempBmp.Canvas.Brush.Color:=$004080FF;
tempBmp.Canvas.Brush.Style:=bsSolid;
end
else
begin
tempBmp.Canvas.Brush.Color:=clBlack;
tempBmp.Canvas.Brush.Style:=bsClear;
end;
if tempBmp.Canvas.TextWidth(s)>r.Right then // укорачивание строки
begin
while tempBmp.Canvas.TextWidth(s+'...')>=r.Right do
s:=copy(s,1,length(s)-1);
s:=s+'...';
end;
tempBmp.Canvas.TextRect(r,2,h*(i-LBAlbums.TopIndex)+1,s);
end;
for i:=0 to Image.Height-1 do
begin
line:=tempBmp.ScanLine[i];
line2:=Image.Picture.Bitmap.ScanLine[i];
CopyMemory(line2,line,IAlbums.Width*3);
end;
Image.Invalidate;
end;
MixAnOL (2006-03-10 18:24:00) [8]tempBmp: TBitmap, созданный при создании формы...
BmpFon: TBitmat - содержит фон под Image, т.е. как бы эмулируется прозрачность, т.к. думал что это в ней косяк...
MixAnOL (2006-03-10 18:21:00) [9]На форме имадж сверху.
Имадж кот. перерисовывается лежит поверх фонового. Для того что бы не делать его прозрачным, я скопировал фон под этим имаджом и на нем рисую.
Да, в данный момент происходит дублирование списка из ListBox.
Отрисовка происходит вызовом вышепоказанной процедуры из события KeyPressed у ListBox.
Прорисовка происходит только при возникновении события. Сначала в памяти рисуется в tempBmp, а потом уже копируется в Image.
antonn (2006-03-10 18:15:00) [10]MixAnOL (10.03.06 16:41)
DoubleBuffered:=true - довольно каверзная штука, может нервы подпортить при случае...
а что за tempBMP?
API (2006-03-10 18:03:00) [11]Не совсем понятно - как отрисовывается фон на форме?
На OnPaint или это просто Image положен?
Если Image, то тот ли это Image, на котором отрисовывается список?
Вы хотите дублировать список из ListBox'а на Imag'е?
Как и при каких событиях производится прорисовка списка на этом Image?
У меня возникает подозрение, что у Вас происходит множественная прорисовка Image. Отладчиком проходили?
Правда, если у вас отрисовка в Image.Paint, отладчиком не совсем удобно пользоваться - лучше в лог писать.
И вообще, лучше бы привести код прорисовки списка на Image.
MixAnOL (2006-03-10 17:24:00) [12]Image.Picture.Bitmap.Assign(tempBMP) использовал уже, тоже самое...только по-моему медленнее...
Хочу сначала так релиазовать, а потом уже оформлю в виде компонента..
Задача:
Есть ListBox, в нем элементы, когда нажимаешь клавишу, то они скролируются. У формы есть фон-рисунок. Хочу показать этот список в виде TImage, при изменении в ListBoxe - обновляется и рисунок...
Конечно, такой подход - изврат, можно было просто перерисовывать элемент ListBoxа в событии, но мне захотелось сейчас так сделать... тем более позже функциональность не бедет совпадать с LB, поэтому придется еще выбрать от кого наследовать при разработке компонента...
API (2006-03-10 17:12:00) [13]Опишите конкретнее задачу и решение.
Насчет "копирования": Image.Picture.Bitmap.Assign(tempBMP)
MixAnOL (2006-03-10 17:05:00) [14]картинка вообще не обновляется...
API (2006-03-10 17:03:00) [15]Уберите Image.Invalidate; и посмотрите, что получится. Сделайте выводы.
MixAnOL (2006-03-10 16:59:00) [16]Уточню, а то не так написал:
кнопка=клавиша
Перерисовка - вызывается процедурка в которой:
tempBmp.Assign(BmpFon);
...//Рисование в tempBmp
// копирование
for i:=0 to Image.Height-1 do
begin
line:=tempBmp.ScanLine[i];
line2:=Image.Picture.Bitmap.ScanLine[i];
CopyMemory(line2,line,Image.Width*3);
end;
Image.Invalidate;
API (2006-03-10 16:43:00) [17]При нажатии на кнопку перерисовывается одно из прозрачных имаджей.
Как он прорисовывается?