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

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

TLabel; Не рисуется T Canvas при запуске формы.


Страницы:   1 2 3

JetAPI ©   (2007-08-17 21:48:00) 

Здравствуйте всем.
Помогите пожалуйста понять: почему, при запуске программы, в TLabel, не работает TCanvas? Что нужно сделать?.. Никак не могу понять?
Если сделать в обработчичике OnClick (кнопки), то все рисуется. А вот при запуске, этого не происходит.
Вот код:

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Label1: TLabel;
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Width:=150;
Label1.AutoSize:=False;
Label1.Canvas.Brush.Color:=clWindow;
Label1.Canvas.FillRect(clientrect);
Label1.Canvas.Font.Color:=clLime;
Label1.Canvas.TextOut(6,0,'01');
Label1.Canvas.Font.Color:=clBlue;
Label1.Canvas.TextOut(26,0,'02');
end;

end.

Спасибо за любой ответ.


JetAPI   (2007-08-18 15:41:00) [21]

to RaskovДа... Да... Прочитал.
Просто разбираюсь и с одним и другим....


{RASkov}   (2007-08-18 15:24:00) [22]

Все что в [8] и у тебя в [19] - это и есть метод OnPaint у формы :)

Можно было и проще:

procedure TForm1.Paint();
begin
 Label1.Width:=150;
 Label1.AutoSize:=False;
 Label1.Canvas.Brush.Color:=clWindow;
 Label1.Canvas.FillRect(clientrect);
 Label1.Canvas.Font.Color:=clLime;
 Label1.Canvas.TextOut(6,0,'01');
 Label1.Canvas.Font.Color:=clBlue;
 Label1.Canvas.TextOut(26,0,'02');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Invalidate;
end;
:o)


{RASkov}   (2007-08-18 15:21:00) [23]

> [19] JetAPI ©   (18.08.07 15:08)


> Identifier redeclared

И зачем два раза реализовал WMPaint????

А [17,18] прочитал?


JetAPI   (2007-08-18 15:16:00) [24]

Ко всем...
Я только учусь... Только постигаю... Поэтому для меня важна каждая мелочь.
Каждое ваше слово ловлю и мотаю на "ус".
Если очень дотошен и назойлив... прошу прощения!
Постарайтесь понять ламмера.  
Все равно спасибо всем.

ЗЫ.
Все ваши примеры и коментарии сохраняю в отдельной папке. Это для меня, как учебник.
Спасибо огромное всем.


JetAPI   (2007-08-18 15:08:00) [25]

tmp
Нет... именно все так и поняли... По нажатию кнопки выполнить прорисовку в Лайбл2. Это делает... Но как только добавляю...

procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
begin
inherited;
Button1Click(self);
end;

Не могу откомпилировать... выдает 2 ошибки...

[Pascal Error] TLabel02_Unit1.pas(47): E2004 Identifier redeclared: 'TForm1.WMPaint'
[Pascal Fatal Error] TLabel02_Project.dpr(5): F2063 Could not compile used unit 'TLabel02_Unit1.pas'

Вот весь код целиком...

unit TLabel02_Unit1;

interface

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

type
 TForm1 = class(TForm)
   Label1: TLabel;
   Label2: TLabel;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 procedure WMPaint(var MsgPaint: TWMPaint); message WM_PAINT;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
begin
inherited;
Button1Click(self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Label2.Width:=150;
Label2.AutoSize:=False;
Label2.Canvas.Brush.Color:=clWindow;
Label2.Canvas.FillRect(clientrect);
Label2.Canvas.Font.Color:=clLime;
Label2.Canvas.TextOut(6,0,'01');
Label2.Canvas.Font.Color:=clBlue;
Label2.Canvas.TextOut(26,0,'02');
end;

procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
begin
inherited;
Label1.Width:=150;
Label1.AutoSize:=False;
Label1.Canvas.Brush.Color:=clWindow;
Label1.Canvas.FillRect(clientrect);
Label1.Canvas.Font.Color:=clLime;
Label1.Canvas.TextOut(6,0,'01');
Label1.Canvas.Font.Color:=clBlue;
Label1.Canvas.TextOut(26,0,'02');
end;

end.

В чем же ошибка?.. Вроде же все правильно написал...


{RASkov}   (2007-08-18 15:03:00) [26]

> > procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
> > begin
> > inherited;   - // первый раз
> >   Label1.Width:=150;
> >   Label1.AutoSize:=False;

Да еще и размеры менять в этом методе..... не серьезно....
Я понимаю, что это было для примера, но..... нужно и это учесть. В методе прорисовки, лучше не менять ничего не касающего TPen, TBrush, TFont....

И вот еще.... я все прорисовка да прорисовка... объясняю:
есть у меня понятие рисование и прорисовка
первое - это как бы разовое. Нарисовали и забыли...
а второе - то самое первое, но рисуется(прорисовывается) тогда когда необходимо....например по сообщению WM_PAINT...
И поэтому мы контролы видим такими какими мы их видим, потому что они прорисовываются при необходимости....


{RASkov}   (2007-08-18 14:54:00) [27]

> [9] JetAPI ©   (18.08.07 13:49)
> Сейчас стараюсь понять, что же предпочтительней и практичней.

Да ты не "заморачивайся" на этом вопросе.... главное пойми как в Windows происходит прорисовка....
и здесь ты выйдешь на procedure WMPaint(var MsgPaint: TWMPaint); message WM_PAINT;
Которое в TGraphicControl'ах реализовано процедурой Paint, и если ты перекроешь ее у себя, то можешь рисовать все, что захочешь и где захочешь(TgraphicControl, например TLabel, TPaintBox)...
Inherited; - это, как уже обяснили, вызов того же самого метода у предка.... поэтому если эту строку убрать, то можно полностью заменить "рисунок" в контроле..... и еще отсюда же - нет смысла вызывать inherited в последнюю очередь.... так как все старания затрутся методом предка.
Я бы так [8], в конкретном случае, не делал.... зачем рисовать два раза на одном и том же месте?

> procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
> begin
> inherited;   - // первый раз
>   Label1.Width:=150;
>   Label1.AutoSize:=False;
>   Label1.Canvas.Brush.Color:=clWindow;
>   Label1.Canvas.FillRect(clientrect);  //все стерли и ниже второй раз

Имхо.... я уже упомянул, об..... зачем извращатся над не преднозначенными для этого контролами (TLabel)..... почему-бы не использовать Паинт?
А уж стандартную метку в нем(в его методе Paint) изобразить раз плюнуть....


tmp   (2007-08-18 14:24:00) [28]

Практичней - не всегда предпочтительней. Если воспользоваться примером, который привёл для тебя Leonid Troynovsky, т.е. создать своего наследника и переопределить процедуру Paint - не будут происходить лишние манипуляции с канвой для вывода текста Caption'а. Если же воспользоваться перехватом WM_PAINT, то сначала отрисуется всё стандартное, а потом - что хочешь ты, но в этом случае меньше стучать по клавишам:)


Leonid Troyanovsky   (2007-08-18 14:24:00) [29]


> JetAPI ©   (18.08.07 14:06) [10]

> в Label2 тоже происходила прорисовка чего-нибудь (не важно
> чего)?

Прорисовка не важно чего происходит в TImage.

--
Regards, LVT.


Leonid Troyanovsky   (2007-08-18 14:17:00) [30]


> JetAPI ©   (18.08.07 13:49) [9]

> Сейчас стараюсь понять, что же предпочтительней и практичней.

Вот и изучай [1].
OnPaint - это значит этот обработчик надо назначить OnPaint формы.

--
Regards, LVT.


tmp   (2007-08-18 14:16:00) [31]


> JetAPI ©   (18.08.07 14:06) [10]

Не совсем понял, что ты хочешь. Может так?


procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
begin
 inherited;
 Button1Click(self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Label2.Width:=150;
   Label2.AutoSize:=False;
   Label2.Canvas.Brush.Color:=clWindow;
   Label2.Canvas.FillRect(clientrect);
   Label2.Canvas.Font.Color:=clLime;
   Label2.Canvas.TextOut(6,0,'01');
   Label2.Canvas.Font.Color:=clBlue;
   Label2.Canvas.TextOut(26,0,'02');
end;


Leonid Troyanovsky   (2007-08-18 14:15:00) [32]


> JetAPI ©   (18.08.07 13:07) [6]


> Caption := 'MyLabel';, и каким образом влияет на прорисовку?

А ширину будет задавать Пушкин? Width := 50;

> Захотел вывести , точно таким же образом, второй лейбл -
>  т.е., чтобы было, например: MyLabel1, MyLabel2, и никак
> не могу.

Меняй второй метке координаты.

--
Regards, LVT.


tmp   (2007-08-18 14:11:00) [33]


> JetAPI ©   (18.08.07 13:49) [9]

Здесь ничего особенного не происходит: просто перехватывется сообщение Windows на отрисовку WM_PAINT, где инструкцией inheritedвызываются стандартные процедуры отрисовки, в том числе и метод Paint Label'а, который выводит на канву содержание Caption, а уже потом затираем выведенное ранее и помещаем на канву нечто своё.
 А вот, если сначала попытаться манипулировать канвой Label'а, а уже потом вызвать inherited, стандартная процедура отрисовки Label'а Paintвыведет на канву содержание Caption.


JetAPI   (2007-08-18 14:06:00) [34]

to tmp  
А как сделать теперь, если, скажем, мы на форму положили 2-ой Label2 и еще кнопку (Button1), по нажатию которой, в Label2 тоже происходила прорисовка чего-нибудь (не важно чего)?
Как Label2 привязать к procedure WMPaint(var MsgPaint: TWMPaint); message WM_PAINT; ?
Можете еще один пример показать?.. (если не трудно).


JetAPI   (2007-08-18 13:49:00) [35]

to mp
Да... Это тоже работает... И работает без создание какого-либо класса. После сворачивания в панель, данные тоже не затираются... Вот это!..
Ламмеру есть чему удивиться.!
Сейчас стараюсь понять, что же предпочтительней и практичней.


tmp   (2007-08-18 13:22:00) [36]


type
 TForm1 = class(TForm)
   Label1: TLabel;
   procedure FormCreate(Sender: TObject);
 private
   procedure WMPaint(var MsgPaint: TWMPaint); message WM_PAINT;
 public
 end;

var
 Form1: TForm1;

implementation

procedure TForm1.WMPaint(var MsgPaint: TWMPaint);
begin
 inherited;
   Label1.Width:=150;
   Label1.AutoSize:=False;
   Label1.Canvas.Brush.Color:=clWindow;
   Label1.Canvas.FillRect(clientrect);
   Label1.Canvas.Font.Color:=clLime;
   Label1.Canvas.TextOut(6,0,'01');
   Label1.Canvas.Font.Color:=clBlue;
   Label1.Canvas.TextOut(26,0,'02');
end;


JetAPI   (2007-08-18 13:10:00) [37]

to Leonid Troyanovsky
Ой!.. код забыл...

procedure TMyLabel.Paint;
begin
inherited;
{Canvas.Brush.Style := bsClear;}
Canvas.Brush.Color:=clWindow;
Canvas.FillRect(clientrect);
Canvas.Font.Color:=clLime;
Canvas.TextOut(6,0,'01');
Canvas.Font.Color:=clBlue;
Canvas.TextOut(26,0,'02');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
with Tmylabel.Create(Self) do begin
 Parent := Self;
 Left:=20;
 Top:=20;
 Caption := 'MyLabel';
{ SetBounds(0, 0, 50, 20);}
end;
end;


JetAPI   (2007-08-18 13:07:00) [38]

Ой!.. сейчас... всё попорядочку...
to Raskovво-первых, самое искреннее спасибо за ответ и на достаточно понятное объяснение! Теперь...

> А у тебя хватает размеров Лэйблы для вывода функцией TextOut?

Да. К тому же тексАут в 30 пикселей шириной сделал... хватает

> В общем ты наверное не понимаешь, что такое канва и как
> происходит на нее вывод...

!00% понял, что прорисовка в Делфи это не такое уж простое дело. Шагу ступить не возможно, чтоб не споткнуться... Впрочем, это может только у меня так.

> Окно получило сообщение на перерисовку... оно перерисовалось
> и нарисовало на канве метки - '02', (пусть будет так - Label1.
> Canvas.TextOut(0, 0, '02'); - это все в твоем примере из
> [2]), но следом перерисовалась сама метка(У нее тоже есть
> Paint) вот оно и затерло "твое художество"...

Теперь я это понимаю... Но до этого-то, я это не знал.... Голову всем морочу, зато узнал. Там даже сложнее все... Виндос  компоненту посылает сообщение WM_PAINT, чтобы сам себя перересовал. Я до такого уровня еще не дошел... Вот поэтому и поселился на форуме...

> Так вот там ты нарисовал "это дело" на канве, пусть даже
> на форме... да на любой, а что происходит потом.... потом
> идет вызов еще кучи методов, такие как например OnResize,
>  OnActivate, OnShow.... и последним OnPaint... т.е. хоть
> у тебя в [1] и не было ничего в этом(OnPaint) обработчике,
>  но окно получило команду перерисоваться и ему(окну) пофик
> что ты рисовал на его создании.... ведь рисунок на канве
> нигде не храниться.... все что мы видим все перерисовывается.
> ...

Блин... Как все сложно... Как все сложно... Но хотя бы, хоть чуть стало кое-что развеиваться...

> И в заключении..... зачем использовать TLabel если нам нужна
> канва на которой мы хотим что-то рисовать??? А TPaintBox
> чем не устроил?

100% Вы правы... Вначале, я думал, что TLabel TPaintBox разница мизер... В общем найвный. А теперь вот столкнулся, и вижу: что нет... TPaintBox это TPaintBolx, а TLabel это TLabel, и каждый предназначен для своего.
Для рисования, TPaintBox, это действитель, оптимальный вариант.

> Нужен пример?

Да... Примеры, это лучше все... Но вы уже и Leonid Troyanovsky ©, привели... Сейчас в редактор "забью", и буду смотреть...  Спасибо.

Leonid Troyanovsky, спасибо большое ответ!
Это то!!!!!!!
Все получается и работает... Я только код чуть подправил под себя - чтобы проще понимать было.

В общем понятно: чтобы перерисовать, мы создали свой класс - TMyLabel/
Теперь, как я понял, Виндоус нам никаких команд не посылает.
Но тут, у меня сразу другой вопрос возник, который, мне кажется, еще сложней.
Разбейся на осколки, но понять не могу: причем здесь свойствой Caption?
Вот причем?!.. Если мы уберем эту строку:

 Caption := 'MyLabel';

,..нам ничего не нарисуется. Я просто не понимаю: как   Caption := 'MyLabel';, и каким образом влияет на прорисовку?
Прошу, пожалуйста, объясните... Иначе, все впустую будет, если не понимать, что и как.

И вот сразу еще одна непонятность возникла...
Захотел вывести , точно таким же образом, второй лейбл - т.е., чтобы было, например: MyLabel1, MyLabel2, и никак не могу.
Попробовал так... Попробовал по другому,.. Ничего не получается.
Подскажите, если не затруднит, как это правильно делается.
Спасибо.


Leonid Troyanovsky   (2007-08-18 11:26:00) [39]


> JetAPI ©   (17.08.07 23:08) [2]

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


type
 TMyLabel = class(TLabel)
   procedure Paint; override;
 end;

procedure TMyLabel.Paint;
begin
 inherited;
 Canvas.Font.Color := clBlue;
 Canvas.Brush.Style := bsClear;
 Canvas.TextOut(0, 0,'---');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 with Tmylabel.Create(Self) do
   begin
     Parent := Self;
     Caption := 'mylabel';
     SetBounds(0, 0, 50, 20);
   end;
end;


--
Regards, LVT.


{RASkov}   (2007-08-18 03:33:00) [40]

> А у тебя хватает размеров Лэйблы для вывода функцией TextOut?

Сорри... не особо обратил внимание на размеры метки и автосайз, так как смысла всего в [1] в FormCreate - нет.

Ладно вот попробуй, чисто для примера, но не прямой ответ на твой вопрос.
Брось на форму TPaintBox и TCheckBox и вот ихи обработчики:

procedure TForm1.PaintBox1Paint(Sender: TObject);
var R: Trect;  // Это нужно Var-параметром для DrawText.....
begin
 R:=PaintBox1.ClientRect;  // ..... но можно и не использовать DrawText, и соответственно R будет не нужна.
 DrawText(PaintBox1.Canvas.Handle, 'Текст метки', -1, R, DT_RIGHT); //Выводим текст "якобы" метки
 if CheckBox1.Checked then begin          // Если какие-то дополнительные параметры рисования
  PaintBox1.Canvas.Font.Color:=clBlue;    // то выстовляем параметры...
  PaintBox1.Canvas.TextOut(0, 0, '02');   // ...и собственно рисуем
 end;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
 PaintBox1.Invalidate; //Просто застовляем обновится(перерисоваться) ПаинтБокс
end;


Кстати... еслиб мы делали так
PaintBox1.Font.Color:=clBlue;Вместо PaintBox1. Canvas.Font.Color:=clBlue;
то нам пришлось бы восстанавливать каждый раз фонт перед прорисовкой...


Страницы:   1 2 3

Наверх

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