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

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

Как провести линию на форме? [D7, WinXP]


isasa ©   (2005-08-18 14:23:00) 

Дурацкий вопрос, но на форме лежит TFrame у которого нет Canvas.
TImage.Canvas.LineTo рисует, но вертикальную линию, например, я не могу провести
до  нижнего конца формы(появляется "мертвая зона"). Тот-же еффект при ReSize.
TPanel работает нормально, но у него нет Canvas. :)

Поделитесь идеями рисования.


isasa   (2005-08-18 21:46:00) [1]

Все Ok! Спасибо. Классическое решение. Снимаю шляпу.


Юрий Зотов   (2005-08-18 17:34:00) [2]

> isasa ©   (18.08.05 16:34) [8]

> Как соединить два объекта, находящихся во фрейме,
> вертикальной линией. Связь не должна разрываться при
> изменении размеров фрейма.

Вот с ЭТОГО и надо было начинать. Теперь задача понятна.

type
 TFrame1 = class(TFrame)
   Edit1: TEdit;
   Edit2: TEdit;
 private
   FCanvas: TCanvas;
   FOnPaint: TNotifyEvent;
   procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
 protected
   procedure DoPaint; dynamic;
   procedure Resize; override;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   property Canvas: TCanvas read FCanvas;
   property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
 end;

constructor TFrame1.Create(AOwner: TComponent);
begin
 inherited;
 FCanvas := TControlCanvas.Create;
 TControlCanvas(FCanvas).Control := Self;
 Edit1.Align := alTop;
 Edit2.Align := alBottom
end;

destructor TFrame1.Destroy;
begin
 FCanvas.Free;
 inherited
end;

procedure TFrame1.DoPaint;
begin
 if Assigned(FOnPaint) then
   FOnPaint(Self)
end;

procedure TFrame1.WMPaint(var Message: TWMPaint);
begin
 inherited;
 DoPaint
end;

procedure TFrame1.Resize;
begin
 inherited;
 Invalidate
end;

Мы ввели в класс фрейма канву и событие OnPaint, а кроме того заставили его перерисовываться при изменении размеров. Теперь можем все это спокойно использовать где и как угодно. Например:

type
 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
 private
   FFrame: TFrame1;
   procedure FramePaint(Sender: TObject);
 end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FFrame := TFrame1.Create(Self);
 with FFrame do
 begin
   OnPaint := FramePaint;
   Parent := Self;
   Align := alClient
 end
end;

procedure TForm1.FramePaint(Sender: TObject);
begin
 with FFrame, Canvas do
 begin
   Brush.Color := Color;
   FillRect(ClipRect);
   with Edit1 do
     MoveTo(Left + Width div 2, Top + Height);
   with Edit2 do
     LineTo(Left + Width div 2, Top)
 end
end;


isasa   (2005-08-18 17:08:00) [3]

>положи, например, на фрейм tpaintbox и рисуй в нем

:)
клал TImage, с ним проблемы. Попробую TPaintBox.


Суслик   (2005-08-18 17:03:00) [4]


> положи, например, на фрейм tpaintbox и рисуй в нем

in event onpaint


Суслик   (2005-08-18 16:59:00) [5]

положи, например, на фрейм tpaintbox и рисуй в нем


isasa   (2005-08-18 16:35:00) [6]

Defunct ©   (18.08.05 16:11) [7]

Интересно, как провести линию на фрайме. Пример.


isasa   (2005-08-18 16:34:00) [7]

Тааак. Пошли пинать ногами.

Изменю формулировку вопроса.

Как соединить два объекта, находящихся во фрейме, вертикальной линией. Связь не должна разрываться при изменении размеров фрейма.

Фрейм вписан(Client) в элемент TTabSheet. TTabSheet
в свою очередь вписан в TForm дочерного окна приложения.


Defunct   (2005-08-18 16:11:00) [8]

> если учитывать координаты объектов находящихся во фрейме,
с заранее не известной позицией.


Причем тут фрейм вообще?
Что за дурь ты пишешь?

Если контейнером изображения у тебя является фрейм, то рисуй только на фрейме. Если форма - на форме. На кой черт котлеты с мухами лепить?


Юрий Зотов   (2005-08-18 15:31:00) [9]

> isasa ©   (18.08.05 15:25) [5]

Вы правы, быть категоричным действительно не стоит. Ведь, в конце концов, что, где, чем и как рисовать - дело хозяйское. Пробовать советы в деле, или не пробовать - тоже дело хозяйское.


isasa   (2005-08-18 15:25:00) [10]

Не надо быть столь категоричным.
Форму с вышеперечесленным бредом составил только для проверки
существования эффекта.
А рисовать  на канве самой формы можно, но неудобно,
если учитывать координаты объектов находящихся во фрейме,
с заранее не известной позицией.

OnPaint хорошо, но зачем дергать все изображение.


Юрий Зотов   (2005-08-18 15:13:00) [11]

> isasa ©   (18.08.05 15:00) [2]

> Для того, чтобы нарисовать линию на фрейм кладу TImage.

Вместо того, чтобы посмотреть справку или хотя бы просто в Инспектор Объектов.

> Интересный эффект
> Self.Canvas.LineTo прорисовывает до конца,
> а Image1.Canvas.LineTo нет.

Человек задает вопрос, но не читает ответов. Действительно, эффект интересный.

> Зависит от первоначального размера окна.

Если рисовать в OnResize (!!!) - то еще как зависит.

> Размер Image1 изменяется нормально.

Ну, хоть это хорошо.

> (куча кода)

Все выбрасываем в помойку, пишем обработчик OnPaint и в нем рисуем все, что угодно на канве самой формы .

И не имеем никаких проблем.


Суслик   (2005-08-18 15:11:00) [12]


>  [2] isasa ©   (18.08.05 15:00)


не в том методе рисуешь


isasa   (2005-08-18 15:00:00) [13]

Для того, чтобы нарисовать линию на фрейм кладу TImage.
TForm->TFrame->TImage

Интересный эффект
Self.Canvas.LineTo прорисовывает до конца, а
Image1.Canvas.LineTo нет.
Зависит от первоначального размера окна.
Размер Image1 изменяется нормально.


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls;

type
 TForm1 = class(TForm)
   Panel1: TPanel;
   Image1: TImage;
   Label1: TLabel;
   procedure FormResize(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormResize(Sender: TObject);
begin
 Image1.Top:=0;
 Image1.Height:=Image1.Parent.Height;
 Image1.Canvas.Brush:=Image1.Parent.Brush;
 Image1.Canvas.FillRect(Image1.ClientRect);
 Image1.Canvas.MoveTo(0,0);
 Image1.Canvas.LineTo(0,Image1.Height-5);
 Image1.Canvas.MoveTo(0,Image1.Height-5);
 Image1.Canvas.LineTo(Image1.Width,Image1.Height-5);
 Label1.Caption:=format('Image1 Width=%d Height=%d',[Image1.Width,Image1.Height]);
 Self.Canvas.FillRect(Self.ClientRect);
 Self.Canvas.MoveTo(Panel1.Width+10,0);
 Self.Canvas.LineTo(Panel1.Width+10,Self.ClientRect.Bottom-10);
 Self.Canvas.MoveTo(Panel1.Width+10,ClientRect.Bottom-10);
 Self.Canvas.LineTo(Self.Width,ClientRect.Bottom-10);
end;

end.


Юрий Зотов   (2005-08-18 14:48:00) [14]

> на форме лежит TFrame у которого нет Canvas.

Зато у него есть DC. Это практически то же самое.

> TImage.Canvas.LineTo рисует

На форме лежал фрейм. Откуда же взялся TImage?

> вертикальную линию, например, я не могу провести
> до  нижнего конца формы(появляется "мертвая зона").

Если линия рисуется на канве TImage, то, естественно, только в пределах TImage она и может рисоваться. Что тут странного?

> TPanel работает нормально, но у него нет Canvas.

1. На форме лежал фрейм. Потом откуда-то же взялся TImage. Потом откуда-то взялась еще и панель. Остается только догадываться, что же Вам все-таки нужно получить.

2. У панели есть Canvas, но он в protected. Получить к нему доступ можно так:

type
 TFriendPanel = class(TPanel);
...
 with TFriendPanel(Panel1).Canvas do ...

> Поделитесь идеями рисования.

Как уже отмечалось, можно только догадываться, что же Вам все-таки нужно, но если нужно рисовать прямо на форме, то для этого у формы есть Canvas и событие OnPaint.


Наверх

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