![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как устранить флики
Danger © (2007-06-22 21:00:00)Вопрос по ходу портирования одного компонента: как ликвидировать мигания при перерисовках контрола? (контрол представляет собой нечто вроде прогресс-бара, поэтому должен обновляться часто и без фликов).
Вот куски кода, ответственные за перерисовку:
// ----------------------------------------------------------
function QProgBar_WndProc( Control: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
var
PaintStruct: TPaintStruct;
begin
Result := False;
case Msg.message of
WM_PAINT:
begin
BeginPaint( Control.Handle, PaintStruct );
PQProgressBar( Control ).Paint;
EndPaint( Control.Handle, PaintStruct );
Result:= True;
Rslt:= 0;
end;
WM_SIZE:
PQProgressBar( Control ).Resize;
end; // case
end;
Функция QProgBar_WndProc аттачена к обработке событий при создании компонента:
// ----------------------------------------------------------
function NewQProgressBar( AParent: PControl ): PQProgressBar;
.........
begin
.........
Result.AttachProc( QProgBar_WndProc );
end;
Сама процедура отрисовки, полностью:
// ----------------------------------------------------------
procedure TQProgressBar.Paint;
// Main loop. Called each time a setting changes, notably, each time
// a new position is sent.
// Surround is drawn first, then the bar itself. Caption is added lastly (if needed).
var i,k,sp: Integer;
OldBkMode : Integer;
D: PQDataObj;
begin
D:= PQDataObj( CustomObj );
// -1- Bevel
if ( D.fHasShape ) then
with Canvas^ do
begin
Pen.PenWidth := 1;
Brush.BrushStyle := bsSolid;
Brush.Color := D.fBkgClr;
Pen.Color := D.fShapeClr;
RoundRect (0, 0, Width, Height, D.fCorner, D.fCorner);
end;
// -2- The bar itself
case D.fOrientation of
boHorizontal :
begin
for i := ( D.fBorderSize - 1 ) to D.fPosition do
begin
if ( D.fByBlock ) then
begin
if ( D.fPosDescr[i].isInBlock = true) then
begin
if ( (D.fFullBlock) and (D.fPosition >= D.fPosDescr[i].blkLimit) )
or not( D.fFullBlock ) then
for k := (D.fBorderSize - 1) to (Height - (D.fBorderSize))
do Canvas.Pixels [i,k] := D.fPixDescr[i,k]
else if (D.fShowInactPos) then
for k := (D.fBorderSize - 1) to (Height -(D.fBorderSize))
do Canvas.Pixels [i,k] := D.fInactDescr[k];
end;
end else
begin
for k := (D.fBorderSize - 1) to (Height -(D.fBorderSize)) do
Canvas.Pixels [i,k] := D.fPixDescr[i,k];
end;
end;
// Now dealing with inactive positions, if they're to be drawn.
if ( D.fShowInactPos ) then
begin
if (D.fPosition < 3) then sp := 3
else sp := D.fPosition + 1;
for i := sp to D.fUSefullDrawSpace do
begin
if (D.fByBlock) then
begin
if (D.fPosDescr[i].isInBlock = True) then
begin
for k := (D.fBorderSize -1) to (Height -(D.fBorderSize)) do
Canvas.Pixels [i,k] := D.fInactDescr[k];
end;
end else //If not(byBlock), all pixels must be drawn
begin
for k := (D.fBorderSize - 1) to (Height -(D.fBorderSize)) do
Canvas.Pixels [i,k] := D.fInactDescr[k];
end;
end; {for}
end; {inactive}
end; {boHorizontal}
boVertical :
begin
for i := (D.fUSefullDrawSpace-1) downto Height - D.fPosition do
begin
if (D.fByBlock) then
begin
if (D.fPosDescr[i].isInBlock = true) then
begin
if ( (D.fFullBlock) and ((Height - D.fPosition) <= D.fPosDescr[i].blkLimit) )
or not( D.fFullBlock ) then
for k := (D.fBorderSize - 1 ) to (Width - (D.fBorderSize))
do Canvas.Pixels [k,i] := D.fPixDescr[i,k]
else if ( D.fShowInactPos ) then
for k := (D.fBorderSize - 1) to (Width -(D.fBorderSize))
do Canvas.Pixels [k,i] := D.fInactDescr[k];
end;
end
else
for k := (D.fBorderSize - 1) to (Width -(D.fBorderSize))
do Canvas.Pixels [k,i] := D.fPixDescr[i,k];
end;
// inactive positions :
if (D.fShowInactPos) then
begin
if ( D.fPosition < 3 ) then sp := D.fUSefullDrawSpace
else sp := Height - D.fPosition - 1;
for i := sp downto D.fBorderSize do
begin
if ( D.fByBlock ) then
begin
if ( D.fPosDescr[i].isInBlock = true ) then
begin
for k := (D.fBorderSize - 1) to (Width -(D.fBorderSize)) do
Canvas.Pixels [k,i] := D.fInactDescr[k];
end;
end else
for k := (D.fBorderSize - 1) to (Width -(D.fBorderSize))
do Canvas.Pixels [k,i] := D.fInactDescr[k];
end; {for... downto}
end; {inactive}
end; {boVertical}
end; // Case
// caption management. The font is the canvas' one. Can be overrided
// using the Font property :
if ( D.fCaptionOvr ) then
if ( D.fShowPosAsPct ) then _SetCaption( Double2Str( D.fUSerPosPct ) + '%')
else SetCaption( Int2Str(D.fUSerPos) );
if ( D.fHasCaption ) then
begin
OldBkMode := SetBkMode(Canvas.Handle, Windows.TRANSPARENT);
with Canvas^ do
begin
TextOut(D.fCapPos.X, D.fCapPos.Y, Caption);
end;
SetBkMode(Canvas.Handle, OldBkMode);
end;
end;
В чем может быть проблема, что при перерисовке контрол сильно мигает? Подскажитте, как можно исправить?
homm (2007-08-30 08:36:00) [1]> [34] Jimmy Lee (30.08.07 08:17)
> а зачем разбираться в чужом, глючном, да еще и медленном коде...
Ба, сколько эппитетов! :) Только «наезжать на всех это не сложно, но к сожалению не конструктивно». Сам то в этом как приуспел?
> А теперь о конструктивном:
Морево конечно :) «А теперь я выскажусь конструктивно: Давайте делайте что-б было все хоршо». Очень констрктивно :)
Jimmy Lee (2007-08-30 08:31:00) [2]Жаль что нельзя удалять свои сообщения, я уже раскаялся за эти наезды, и хочу попросить прощения...все написаное выше, под воздействием усталости и раздражения
Jimmy Lee (2007-08-30 08:17:00) [3]2 homm:
> >Сегодня день перлов что-ли? :)
а что непонятного? или надо было расписать подробно, что графика де рисуется НЕ на битмапе с последующим трансфером этого битмапа на экран, а сразу в контексте устойства получаемом в BeginPaint, что в свою очередь, подразумевает медленный вывод графики, и что несмотря на это фликов все равно меньше?
> Пока в КОЛ даблбуфер и transparent моей реализации, готов
> поспорить что когда исходник откроешь, у тебя духу не хватит
> в нем разобратся.
а зачем разбираться в чужом, глючном, да еще и медленном коде...
как видишь, я в ответ тоже могу наехать, наезжать на всех это не сложно, но к сожалению не конструктивно. А теперь о конструктивном:
Флики - это причина по которой я ваяю приложение без KOL, и мне очень тягостно далось это решение. В KOL очень многое реализовано, и писать самому - конечно лень. Но, приложение должно выглядеть профессионально, и не мерцать, когда его ресайзят, заказчик привередливый.
exero (2007-08-30 08:14:00) [4]Я и не пытался найти виноватого, просто есть проблема и все.
homm (2007-08-30 08:01:00) [5]> А что я делаю не так:
Лучше чем есть все равно для RichEdit не сделать (тут ксати уж я совсем не причем, все вопросы к Microsoft). Единственное применение прозрачного RE — запретить в него вообще вставлять курсор.
exero (2007-08-30 07:51:00) [6]
> homm © (30.08.07 00:08) [21]
> > Это пока единственная реализация работающая от 95 до висты.
>
К сожалению это не так, под 98 (не поленился, проверил) тот же пример при включении прозрачности ведет себя некорректно - не отображает содержимое файла - оно появляется при щелчке мышкой и выделении - но у меня при потере фокуса окна содержимое снова пропадало.
exero (2007-08-30 07:29:00) [7]Уважаемый homm, хорош флудить! А что я делаю не так: качаем вашу прогу:
Load - Transparent - щелкаем на тексте и нажимаем клавишу стрелка влево (вправо) - что получится думаю увидите сами. А после этого скажите что никаких проблем нет и что это у меня кривые руки.
homm (2007-08-30 01:41:00) [8]> [28] Andrey_rus © (30.08.07 01:17)
> и выполняемый файл неизвестного происхождения
Вот она, вся твоя упертость, будешь меня в лицо упректь, что я факты поттсовываю, вместо того, что-бы самому проверить, так ли обстоят дела как ты думаешь.
Andrey_rus (2007-08-30 01:17:00) [9]
> НЕ верный вывод. Попробуй еше раз.
А по моему, все логично, перечитай свои посты.
> Блин, что я вечно делаю не так? :) http://homm86.narod.ru/files/rtf.rar
Тем, что предлагаешь для ознакомления в архиве - "Delphi 6 Release Notes
" и выполняемый файл неизвестного происхождения. Хочешь запустить мой. :)
homm (2007-08-30 00:57:00) [10]> > Все.
> Вывод - код, во всех библиотеках осуществляющих отображение
> контролов, написан тобой?
НЕ верный вывод. Попробуй еше раз.
> [11] Andrey_rus © (29.08.07 18:00)
> не работает с RichEdit
Блин, что я вечно делаю не так? :)
http://homm86.narod.ru/files/rtf.rar
Andrey_rus (2007-08-30 00:51:00) [11]> Сделай скриншот, покажи, мне этьот контрол :)
Открой в Office любое окно где много контролов.
> Пока в КОЛ даблбуфер и transparent моей реализации
> Это пока единственная реализация работающая от 95 до висты.
> Имеется ввиду не только КОЛ.
А что еще?
> Все.
Вывод - код, во всех библиотеках осуществляющих отображение контролов, написан тобой?
homm (2007-08-30 00:44:00) [12]При многократном наведении эффект усиливаеться и контрол становиться почти черным.
homm (2007-08-30 00:43:00) [13]Офис тоже не может похвастаться безглючной работой с темами. Пример прилагаеться:
http://homm86.narod.ru/files/office.png
homm (2007-08-30 00:33:00) [14]> Есть ли какие нибудь предположения относительно скорости
> прорисовки контролов в Office?
Сделай скриншот, покажи, мне этьот контрол :)
Принимаются возражения только по темам XP, сделать это можно, но будет гемора не меньша чем с экспишным темами в графических контроллах.
Насчет медленно и глючно — много быстрее и безглючнее чем предъидущаяя версия. Есть способ сделать еше быстрее, но там тоже камней подводных будет, глюков.
> А что еще?
Все.
> Есть ли какие нибудь предположения относительно скорости
> прорисовки контролов в Office?
NewDibBitmap?
Andrey_rus (2007-08-30 00:19:00) [15]> пока ты ту флуд разводишь.
Где то я уже это видел... и не раз...
> Пока в КОЛ даблбуфер и transparent моей реализации
Огромное спасибо! Серьезно. Вот только пользоваться ими проблематично, по причине описанной мной выше.
>> Это пока единственная реализация работающая от 95 до висты.
> Имеется ввиду не только КОЛ.
А что еще?
Есть ли какие нибудь предположения относительно скорости прорисовки контролов в Office?
homm (2007-08-30 00:08:00) [16]> Это пока единственная реализация работающая от 95 до висты.
Имеется ввиду не только КОЛ.
homm (2007-08-30 00:04:00) [17]> [19] Andrey_rus © (29.08.07 23:56)
> homm, Не в обиду, хорош флуд разводить.
пока ты ту флуд разводишь. Пока в КОЛ даблбуфер и transparent моей реализации, готов поспорить что когда исходник откроешь, у тебя духу не хватит в нем разобратся. Это пока единственная реализация работающая от 95 до висты. Наишешь лучше — возьму свои слова обратно, но пока, ты кроме как на тот орех, что я процетировал не тянешь.
Andrey_rus (2007-08-29 23:56:00) [18]>NewDibBitmap
Хороший пример... :)
homm, Не в обиду, хорош флуд разводить.
homm (2007-08-29 23:48:00) [19]NewDibBitmap
Andrey_rus (2007-08-29 23:24:00) [20]> Да нет, не зря.
homm... homm...
> Временный битмап? Кто мешает его сделать в своем приложении?
Как?