Форум: "Основная";
Текущий архив: 2007.04.01;
Скачать: [xml.tar.bz2];
Внизнекорректный ClipRect при resize TCustomControl а Найти похожие ветки
← →
Leff © (2007-02-05 14:32) [0]Создаю компонент-потомок TCustomControl. Размещаю его на форме, делаю Align = alClient и у меня возникает проблема при изменении размеров компонента (как при уменьшении, так и при увеличении) - он перерисовывается ПОЛНОСТЬЮ, причем, сначала область занятая компонентом заполняется цветом формы, после чего отрисовывается весь компонет, что вызывает очень неприятные мерцания. Вот пример процедуры отрисовки:
procedure TMyControl.PaintWindow(DC: HDC);
var
y: integer;
begin
if ot then exit else ot := true;
with canvas.ClipRect do for y := top to bottom do begin
if odd(y div 2) then canvas.Pen.Color := $A0A0A0 else canvas.Pen.Color := $C0C0C0;
canvas.MoveTo(left,y);
canvas.LineTo(right,y);
end;
end;
при установке DoubleBuffered у компонента в True, он вообще перестает корректно прорисовываться и я вижу только цвет формы.
при вставке этого-же куска кода в OnPaint формы все происходит как надо - отрисовываются только действительно измененные участки изображения (например те области, которые появились после увеличения размеров формы)
подскажите как решить проблему
← →
RASkov (2007-02-05 17:14) [1]Может перекрыть метод Paint лучше...
procedure TMyControl.Paint;
var Y: Integer;
begin
with Canvas do for y := ClipRect.Top to ClipRect.Bottom do begin
if odd(y div 2) then canvas.Pen.Color := $A0A0A0 else canvas.Pen.Color := $C0C0C0;
Canvas.MoveTo(ClipRect.Left, y);
Canvas.LineTo(ClipRect.Right, y);
end;
end;
← →
Leff © (2007-02-07 09:24) [2]изначально я Paint и перекрывал - результат тот-же :)
← →
KSergey © (2007-02-07 09:51) [3]Leff © (05.02.07 14:32)
> Создаю компонент-потомок TCustomControl. Размещаю его на
> форме, делаю Align = alClient и у меня возникает проблема
> при изменении размеров компонента
1) А разве при Align = alClient размеры компонента можно менять?!
2) Речь про DesignTime или RunTime?
← →
Leff © (2007-02-07 10:26) [4]Речь идет конечно о Run-Time, размеры компонента при Align = alClient можно минять изменяя размер клиентской области, в данном случае формы
← →
Leff © (2007-02-07 11:21) [5]Пытаюсь сделать потомок TWinControl, перекрываю WM_PAINT. В BeginPaint опять получаю обласьть отрисовки во весь control... Чувствую засада здесь в SetBounds TWinControl"а, должен же быть способ обойти это, StringGrid не мерцает вроде.... :-\
← →
RASkov (2007-02-07 14:17) [6]> [2] Leff © (07.02.07 09:24)
Я вот только, что так попробывал, все нормально:
type
TMyControl = class(TCustomControl)
procedure Paint; override;
end;
TForm1 = class(TForm)
Panel1: TPanel; {Align=alLeft}
Panel2: TPanel; {Align=alTop}
Button1: TButton; //на форме, не на панелях
ListBox1: TListBox; //на форме, не на панелях
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Ctr: TMyControl;
implementation
{$R *.dfm}
{ TMyControl }
procedure TMyControl.Paint;
var Y: Integer;
begin
with Canvas do for y := ClipRect.Top to ClipRect.Bottom do begin
if odd(y div 2) then Pen.Color := $A0A0A0 else Pen.Color := $C0C0C0;
MoveTo(ClipRect.Left, y);
LineTo(ClipRect.Right, y);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
with TMyControl.Create(Self) do begin
Parent:=Self;
Align:=alClient;
SendToBack;
DoubleBuffered:=True; //Вот без этой строки "моргает"
end;
end;
Моргает когда размер моего контрола(его канва) меняется, так, что здесь все нормально и двойная буферизация помогает.
Иначе сам агоритм, рисования полосок, нужно переделывать... имхо. Хотя в голову не приходит ничего, как это сделать.
Можно на временном битмапе рисовать и подсовывать, но это тоже самое, что и DoubleBuffered:=True;
← →
capkoh © (2007-02-07 22:49) [7]Читайте в MSDN о сообщении WM_ERASEBKGND... Его нужно перекрыть пустой функцией (но вернуть результат = 0), если, конечно, не сделать параметр hbrBackground = 0. Небольшая выдержка:
hbrBackground
When this member is NULL, an application must paint its own background whenever it is requested to paint in its client area. To determine whether the background must be painted, an application can either process the WM_ERASEBKGND message or test the fErase member of the PAINTSTRUCT structure filled by the BeginPaint function.
← →
Leff © (2007-02-08 09:23) [8][6] RASkov (07.02.07 14:17)
проблема не в мерцании как таковом, а в том что перерисовывается вся область, так как там будут не полосочки а намного более сложная функция отрисовки содержимого окна, отрисовка только измененных участков повысила бы производительность
[7] capkoh © (07.02.07 22:49)
на счет WM_ERASEBKGND спасибо, действительно помогло против мерцаний :)
тем не менее содержимое окна, к сожалению, перерисовывается полностью :(
← →
Leff © (2007-02-08 11:31) [9]Всем спасибо, проблема решена - в качестве предка использую TScrollingWinControl (планируется использование скроллинга), сам создаю канву и обрабатываю WM_PAINT. Теперь отрисовка производится только в измененных областях :)
← →
GrayFace © (2007-02-09 01:35) [10]Все дело в наличии CS_VREDRAW и CS_HREDRAW в Params.WindowClass.Style.
← →
Leff © (2007-02-09 09:57) [11]> [10] GrayFace © (09.02.07 01:35)
Блин, как я раньше не заметил, достаточно было сравнить исходники TScrollingWinControl.CreateParams и TWinControl.CreateParams :)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.04.01;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.054 c