![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Самодельная отрисовка мигает
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