Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.12.27;
Скачать: CL | DM;

Вниз

Самодельная отрисовка мигает   Найти похожие ветки 

 
Kolan ©   (2009-11-10 15:35) [0]

Есть самодельный элемент управления — наследник TCustomControl.

По смыслу он похож на выдачу «Яндекс.Картинок». Внизу скролл и квадратики.

Я про него уже спрашивал. Только пост не могу найти. Игорь Шевченко мне еще тогда помог.

Скриншот:
http://www.ksoftware.ru/xlam/Control.jpg

Отрисовка происходит следующим образом:

procedure TCalibrationsListWidget.Paint;
var
P: TPoint;
Image: TCalibrationIcon;
R, Clipper: TRect;

ImageWidth, ImageHeight: Integer;
ImagesStartPoint: TPoint;
begin
 inherited;

 Canvas.Brush.Color := clWhite;
 Canvas.FillRect(Self.ClientRect);

{Нарисовать квадраты для разных блоков контрола.}
 Canvas.Brush.Color := $eeeeee;
 Canvas.FrameRect(ListRect);
 Canvas.FrameRect(InfoScrollRect);
 //Canvas.FillRect(Rect(10, 10, 20, 20));

 Clipper := ListRect;

 IntersectClipRect(Canvas.Handle, Clipper.Left, Clipper.Top, Clipper.Right,
   Clipper.Bottom);

 if FCalibrationsIconsList.Count > 0 then
 begin
   ImageWidth := FCalibrationsIconsList[0].Width;
   ImageHeight := FCalibrationsIconsList[0].Height;

  {Вычислить координаты точки начала рисования картинок.}

   ImagesStartPoint.Y := ListRectMiddle - (FCalibrationsIconsList[0].Height div 2);
   ImagesStartPoint.X := ImagesStartPoint.Y + (FImagesPos);

   P := ImagesStartPoint;

   for Image in FCalibrationsIconsList do
   begin
     Image.Left := P.X;
     Image.Top := P.Y;
    {Сами картинки}
     Image.Repaint;

     Inc(P.X, ImageWidth + ImagesStartPoint.Y);
   end;

   FScroller.Top := InfoScrollRect.Top;
   FScroller.Width := EvalScrollWidth;
   FScroller.Left := Round((Abs(FImagesPos)*FScroller.Width)/Width);
   FScroller.Height := InfoScrollRectHeight;
   FScroller.Repaint;
 end;

end;


Так вот. Вы не поверите, мигает, когда таскаешь за скролл. Как сделать, чтобы не мигал?


 
clickmaker ©   (2009-11-10 17:08) [1]

рисуй через memory-dc


 
Игорь Шевченко ©   (2009-11-10 17:09) [2]


> рисуй через memory-dc


И че ?


 
DVM ©   (2009-11-10 17:10) [3]


> Kolan ©   (10.11.09 15:35)  


> Скриншот:
> http://www.ksoftware.ru/xlam/Control.jpg

А чем это отличается от ListView ?


 
DVM ©   (2009-11-10 17:12) [4]


> Kolan ©   (10.11.09 15:35)  

Мигает, потому что стирается фон, а твое рисование выполняется долго, вот фон и успевает мелькнуть. Как вариант - запретить стирание фона.


 
Kolan ©   (2009-11-10 18:53) [5]

DVM, а листвью подойдет? Мне нужно, чтобы рисунки и надписи свои + скролл свой.


 
DVM ©   (2009-11-10 20:05) [6]


> Kolan ©   (10.11.09 18:53) [5]


> DVM, а листвью подойдет?

Ну рисунки и надписи без проблем. Со скроллом сложнее, придется переопределять его отрисовку, возни много.


 
Kolan ©   (2009-11-11 11:59) [7]

А как не стирать фон? И вообще, что считается стиранием фона, эти две строчки?
Canvas.Brush.Color := clWhite;
Canvas.FillRect(Self.ClientRect);


 
DVM ©   (2009-11-11 12:10) [8]


> А как не стирать фон?

Ну есть много способов, красивые и не очень.

Попробуй переопределить WM_ERASEBKGND в оконной процедуре своего контрола. Ну а там просто результ нужный надо вернуть, не помню какое число, посмотри в справке.

Это первое.

Второе - выводи сначала все на битмап в памяти, а затем сам битмап выводи на канву. Разница будет.


 
DVM ©   (2009-11-11 12:15) [9]


> Kolan ©   (11.11.09 11:59) [7]


> И вообще, что считается стиранием фона, эти две строчки?
>
> Canvas.Brush.Color := clWhite;
> Canvas.FillRect(Self.ClientRect);

Нет эти строчки как раз тебе будут нужны, если ты заблокируешь стрирание фона в обработчике WM_ERASEBKGND.
А сейчас у тебя получается такая штука:
1) Какая то область окна нуждается в перерисовке.
2) Windows шлет окну сообщение WM_ERASEBKGND
3) Окно заливает себя каким то цветом.
4) Windows шлет WM_PAINT
5) Ты еще раз заливаешьт окно цветом
6) Долго-долго рисуешь что-то. Надо заметить, что пока ты рисуешь виден фон окна, более того между посылкой сообщений тоже проходит время.
7) Наконец появляется нарисованное.


 
Омлет ©   (2009-11-11 12:50) [10]

Перехватывать WM_ERASEBKGND. Всё рисовать на bitmap в памяти, а при OnPaint выводить ClipRect с битмапа через BitBlt.

Еще вот это подозрительно:
> FScroller.Repaint;
Точно нужна полная перерисовка FScroller?


 
Kolan ©   (2009-11-11 13:27) [11]

На счет полной перерисовке скрола — не знаю. Там будет инфоскроллер потом...

Благодарю, DVM, пойду читать про WM_ERASEBKGND, не знал об этом сообщении.


 
Kolan ©   (2009-11-11 14:01) [12]

DVM, а как правильно применить ListView для сабжа? Скролл не трогаем, просто вывод квадратиков.


 
Kolan ©   (2009-11-11 14:09) [13]

Особенно не понятно как положить скролл вниз и сделать, чтобы иконки не переносились.


 
DVM ©   (2009-11-11 14:55) [14]


> Kolan ©   (11.11.09 14:09) [13]

Можно поковыряться со стилями окна листвью и функциями или комбинациями функций ShowScrollBar SetScrollRange


 
Kolan ©   (2009-11-11 15:13) [15]

Понял.

 ShowScrollBar(CalibrationsListView.Handle, SB_HORZ, True);
 ShowScrollBar(CalibrationsListView.Handle, SB_VERT, False);


Такой вариант, совмещенный с моей кривизной рук, глючит меньше.


 
Kolan ©   (2009-11-11 15:32) [16]

Еще вопросик. Как отодвинуть рисунки от верха компонента. Слишком близко прижимаются. На скриншоте расстояние, которое хочется увеличить показано красным.
http://img-fotki.yandex.ru/get/4001/ksoftware.f/0_36421_fd047bc7_orig


 
Игорь Шевченко ©   (2009-11-11 15:33) [17]


> Как отодвинуть рисунки от верха компонента



>   ImagesStartPoint.Y := ListRectMiddle - (FCalibrationsIconsList[0].
> Height div 2);


изменить значение ? :)


 
Kolan ©   (2009-11-11 15:37) [18]

Не, Игорь, я решил попробовать, по советам DVM, ListView. Как с ним быть?


 
DVM ©   (2009-11-11 15:57) [19]


> Kolan ©   (11.11.09 15:32) [16]
> Еще вопросик. Как отодвинуть рисунки от верха компонента.
>  

Ты отрисовывай итемы сам, и задавай размер с запасом. При рисовании просто отступишь. Готового макроса или сообщения для увеличения отступа я не знаю, хотя не исключено что есть.


 
Kolan ©   (2009-11-11 15:59) [20]

Ладненько, понял.


 
DVM ©   (2009-11-11 16:01) [21]


> Kolan ©  

Кстати, если у тебя там планируется много элементов то самое правильное перевести ListView в виртуальный режим. Виртуальный режим + собственная отрисовка элементов позволяют сделать практически все что угодно.


 
Kolan ©   (2009-11-11 16:06) [22]

Понял. Я просто хотел инфоскроллер там сделать, поэтому и затеялся со своей отрисовкой.


 
Kolan ©   (2009-11-11 16:07) [23]

Кстати, раз уж про мигание ветка.

Вот стандартный PageControl тоже при резайзе жутко мигает. Это как-нибудь лечится?


 
DVM ©   (2009-11-11 16:16) [24]


> Kolan ©   (11.11.09 16:07) [23]


> Вот стандартный PageControl тоже при резайзе жутко мигает.
>  Это как-нибудь лечится?

Вот тут посмотри http://andy.jgknet.de/blog/?page_id=288
Тебе надо искать что-то типа Flicker Reduce там есть.


 
DVM ©   (2009-11-11 16:19) [25]

да точно есть: QC #56252: TPageControl flickers a lot with active theming


 
Kolan ©   (2009-11-11 16:25) [26]

Ух, страшновато патчить VCL, пусть мигает. Но за ссылку благодарю.


 
DVM ©   (2009-11-11 16:27) [27]


> Kolan ©   (11.11.09 16:25) [26]


> Ух, страшновато патчить VCL, пусть мигает

Не надо ничего патчить. Просто модуль подключи и все. Там к PageControl относится строк 50, остальное можно выкинуть.


 
Kolan ©   (2009-11-11 16:32) [28]

Круто! Мигает, все равно, конечно, но почти незаметно.


 
DVM ©   (2009-11-11 16:35) [29]


> Kolan ©   (11.11.09 16:32) [28]


> Мигает, все равно, конечно

скорее всего мигает уже содержимое. DoubleBuffered не забудь. У меня вообще мигать перестало.


 
Kolan ©   (2009-11-11 16:39) [30]

Помигивает лейбл лежащий на пейдж контроле и корешки закладок. ДаблБуфферд пейджконтролу сделал лучше, но окончательно не помог.

Кажется это уже ловля блох. Благодарю. Полезная ветка вышла.


 
Игорь Шевченко ©   (2009-11-11 16:41) [31]

Kolan ©   (11.11.09 15:37) [18]


> Как с ним быть?


Уважать отвечающих для начала


 
Kolan ©   (2009-11-11 16:47) [32]

Я, вроде, уважаю. Что не так?


 
Игорь Шевченко ©   (2009-11-11 17:34) [33]

Kolan ©   (11.11.09 16:47) [32]

Кода с listview не даешь, вопросы задаешь, не уважаешь


 
Kolan ©   (2009-11-11 20:58) [34]

А какой там код? Я настроил свойства, подключил картинки и в цикле создаю Items. Собственной отрисовки не делал.

Простите, не хотел выказать не уважение.



Страницы: 1 вся ветка

Текущий архив: 2009.12.27;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.016 c
6-1211196570
KuH
2008-05-19 15:29
2009.12.27
Авторизация через TServerSocket


15-1256506209
Юрий
2009-10-26 00:30
2009.12.27
С днем рождения ! 26 октября 2009 понедельник


2-1252914724
VirEx(home)
2009-09-14 11:52
2009.12.27
сервис + приложение (обмен данными)


15-1256455692
Киря
2009-10-25 10:28
2009.12.27
Треугольник


4-1226050103
pushkin42
2008-11-07 12:28
2009.12.27
А какое сообщение возникает когда...