Форум: "Основная";
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];
ВнизНе рисуется компонента, и все тут... Найти похожие ветки
← →
Aleksandr (2001-12-18 13:03) [0]Уважаемые коллеги!
Понадобилось это мне создать компоненту. Создал, породив от TGraphicControl. Ставлю на форму - все в порядке, проперти видны, но вот не рисуется, и все тут... Код таков
type
TWayTree = class(TGraphicControl)
private
...
protected
procedure Paint;override;
public
constructor Create(AOwner : TComponent);
published
...
property Color default clWhite;
property Visible default true;
end;
procedure Register;
implementation
procedure TWayTree.Paint;
var
ARect : TRect;
begin
Inherited;
Canvas.Brush.Color:=Color;
ARect.Left:=Left;
ARect.Top:=Top;
ARect.Bottom:=Top+Height;
ARect.Right:=Left+Width;
Canvas.FillRect(ARect)
end;
constructor TWayTree.Create;
begin
Inherited Create(AOwner);
...
end;
procedure Register;
begin
RegisterComponents("WayTrees", [TWayTree])
end;
end.
Мало того, когда я еще пытаюсь добавить свойства FPen и FBrush (для отдельного доступа в дизайн-тайме):
TWayTree = class(TGraphicControl)
private
FPen : TPen;
FBrush : TBrush;
procedure RePaintRequest(Sender : TObject);
procedure SetBrush(Value : TBrush);
procedure SetPen(Value : TPen);
protected
procedure Paint;override;
public
constructor Create(AOwner : TComponent);
destructor Destroy;
published
property Color default clWhite;
property Visible;
property Brush : TBrush read FBrush write SetBrush;
property Pen : TPen read FPen write SetPen;
end;
procedure Register;
implementation
procedure TWayTree.Paint;
var
ARect : TRect;
begin
Inherited;
Canvas.Pen:=FPen;
Canvas.Brush:=FBrush;
Canvas.Brush.Color:=Color;
ARect.Left:=Left;
ARect.Top:=Top;
ARect.Bottom:=Top+Height;
ARect.Right:=Left+Width;
Canvas.FillRect(ARect);
Canvas.TextOut(ARect.Left,ARect.Top,"AAA");
end;
destructor TWayTree.Destroy;
begin
FPen.Free;
FBrush.Free;
inherited Destroy
end;
constructor TWayTree.Create;
begin
Inherited Create(AOwner);
FPen:=TPen.Create;
FBrush:=TBrush.Create;
FPen.OnChange:=RepaintRequest;
FBrush.OnChange:=RepaintRequest
end;
procedure TWayTree.SetBrush;
begin
if Value=nil then
Exit;
FBrush.Assign(Value);
Invalidate
end;
procedure TWayTree.SetPen;
begin
if Value=nil then
Exit;
FPen.Assign(Value);
Invalidate
end;
procedure TWayTree.RePaintRequest;
begin
Invalidate
end;
procedure Register;
begin
RegisterComponents("WayTrees", [TWayTree]);
end;
end.
компонента при вставлении в форму ругается, что не может установить Pen в nil. Pen и Brush в Инспекторе появляются, но при нажатии на + нифига не выпадает, при изменении размеров компоненты та же ошибка... Чего я тут не так делаю?
← →
csf (2001-12-18 13:09) [1]Перезапусти Delphi, говорят, помогает.
Про stored можно еще почитать...
← →
Aleksandr (2001-12-18 13:11) [2]Сорри, мне пора на свалку... Разобрался, что забыл override напротив констрактора с дестрактором нарисовать... Интересно, как можно к этой компоненте подключить вертикальный ScrollBar...
← →
csf (2001-12-18 13:19) [3]... хорошо бы проверять при Paint FPen & FBrush на nil...
← →
Юрий Зотов (2001-12-18 14:30) [4]> csf
1. > Перезапусти Delphi, говорят, помогает.
Ценнейший совет.
2. > Про stored можно еще почитать...
Можно. Только к сабжу это не имеет никакого отношения.
3. > ... хорошо бы проверять при Paint FPen & FBrush на nil...
Зачем? Oни созданы в конструкторе компонента. Nil там быть никак не может.
Итого: Вы написали 3 фразы и все 3, извините, чушь. Стоило ли писать? Стоит ли вообще отвечать на вопросы, тема которых Вам, мягко говоря, не очень хорошо знакома?
> Aleksandr
С override Вы уже сами разобрались, но это еще не все - у Вас идет двойная перерисовка:
procedure TWayTree.SetBrush;
begin
if Value=nil then // Это лишнее и даже вредно - маскирует ошибки юзера
Exit;
FBrush.Assign(Value); // Генерит FBrush.OnChange и вызов RePaintRequest
Invalidate // Это лишнее - идет повторная перерисовка
end;
И то же самое в SetPen. Кроме того, переменная ARect в Paint совершенно не нужна - используйте ClientRect или Canvas.ClipRect.
Наконец, главное - свои FBrush и FPen абсолютно ни к чему - только лишние ресурсы гробят. Используйте встроенные в Canvas:
published
property Pen: TPen read GetPen write SetPen;
...
function ...GetPen: TPen;
begin
Result := Canvas.Pen
end;
procedure ...SetPen(const Value: TPen);
begin
Canvas.Pen.Assign(Value)
end;
Вывод - даже такие простейшие компоненты надо продумывать более тщательно и делать более акккуратно.
← →
Aleksandr (2001-12-18 15:50) [5]2 Юрий Зотов
Спасибо за инфу. Однако, прямое обращение к свойствам канвы вызовет то, что не будет "стандартов" по умолчанию - она всегда будет продолжать рисовать тем цветом, который использовался последним. И, соответственно, на OnChange ничего посадить нельзя - будет происходить элементарное зацикливание - установка цвета канвы вызывает OnChange, он вызывает перерисовку, а в перерисовке опять меняется цвет Canvas.
Остался один вопрос на повестке: как засобачить в компоненту TScrollBar? Что-то у меня не получается нифига сделать двойное наследование - от TGraphicControl и от TScrollBar...
← →
DieHard (2001-12-18 16:01) [6]Двойное наследование не пройдет.
Попробуй наследовать от TScrollBox.
← →
MBo (2001-12-18 16:02) [7]двойного наследования нет.
может, наследовать от TWinControl?
← →
Polevi (2001-12-18 16:19) [8]TCustomControl
← →
Aleksandr (2001-12-18 16:19) [9]Мда... ладно, оставим сие пока... Вот как истчо избежать постоянного мерцания компоненты при изменении размеров формы?
← →
panov (2001-12-18 16:31) [10]>Aleksandr © (18.12.01 16:19)
Попробуй указать Enabled := False перед изменением размеров
← →
Юрий Зотов (2001-12-18 17:25) [11]> Aleksandr © (18.12.01 15:50)
> она всегда будет продолжать рисовать тем цветом, который использовался последним.
Что и требуется.
> И, соответственно, на OnChange ничего посадить нельзя
И не нужно. Ваш метод Paint будет вызван автоматически, а больше ничего и не требуется.
> будет происходить элементарное зацикливание - установка цвета канвы
> вызывает OnChange, он вызывает перерисовку, а в перерисовке опять
> меняется цвет Canvas.
Во-первых, Вы сами подтверждаете, что смена свойств канвы автоматически вызывает Ваш метод Paint. Значит, Вы должны согласиться с предыдущим пунктом - никакие обработчики OnChange Вам не нужны (обработчики OnChange дают только лишнюю перерисовку - отсюда и лишнее моргание).
Во-вторых, в перерисовке НЕ НУЖНО менять свойств канвы. Зачем? Ведь если Вы завяжете свойства компонента на свойства канвы, то при вызове метода Paint эти свойства канвы УЖЕ будут установлены, как надо. С ними и рисуйте, ничего не меняя. И тогда не будет никакого зацикливания.
В общем, советую попробовать - увидите сами. Думаю, и мерцание значительно уменьшится.
Далее, по поводу мерцания и ScrollBar - прислушайтесь к совету Polevi. TCustomControl - это окно. ScrollBar"ы туда вставляются простым выставлением стилей WS_HSCROLL/WS_VSCROLL в CreateParams, а уменьшить мерцание можно установкой свойства DoubleBuffered.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.006 c