Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Самодельная отрисовка мигает


Страницы:   1 2

Kolan ©   (2009-11-10 15:35:00) 

Есть самодельный элемент управления — наследник 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;


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


DVM   (2009-11-11 14:55:00) [21]


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

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


Kolan   (2009-11-11 14:09:00) [22]

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


Kolan   (2009-11-11 14:01:00) [23]

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


Kolan   (2009-11-11 13:27:00) [24]

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

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


Омлет   (2009-11-11 12:50:00) [25]

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

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


DVM   (2009-11-11 12:15:00) [26]


> 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) Наконец появляется нарисованное.


DVM   (2009-11-11 12:10:00) [27]


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

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

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

Это первое.

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


Kolan   (2009-11-11 11:59:00) [28]

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


DVM   (2009-11-10 20:05:00) [29]


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


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

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


Kolan   (2009-11-10 18:53:00) [30]

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


DVM   (2009-11-10 17:12:00) [31]


> Kolan ©   (10.11.09 15:35)  

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


DVM   (2009-11-10 17:10:00) [32]


> Kolan ©   (10.11.09 15:35)  


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

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


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


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


И че ?


clickmaker   (2009-11-10 17:08:00) [34]

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо