@257

Почему линия не прорисовывается с права?

Работаю в Delphi 7 .
Создаю лейблы , прорисовываю линии между ними , но почему то с права от левого лейбла не до конца прорисовывается линия .
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;

    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
   p,c,z,j:integer;
  function rez(p:integer): integer;
  function toside(j:integer): integer;
  var MyLabel,MyLabel2:TLabel;

implementation

{$R *.dfm}



procedure TForm1.Button2Click(Sender: TObject);


begin
 rez(p);
 p:=c;
  toside(j);
  j:=z;


MyLabel := TLabel.Create(Form1);
MyLabel.Parent := Form1;
MyLabel.Left:=300 ;
MyLabel.Top:=Mylabel.Top+c;
MyLabel.Caption:='1';


MyLabel2 := TLabel.Create(Form1);
MyLabel2.Parent := Form1;
MyLabel2.Left:=MyLabel.Left+z ;
MyLabel2.Top:=Mylabel.Top;
MyLabel2.Caption:='3';

  with Form1.Canvas do
 begin
 Pen.Color:=clRed;
 MoveTo(MyLabel.left,MyLabel.top+(MyLabel.Font.Size+MyLabel.Font.Size div 2) div 2);
 LineTo(MyLabel2.left,MyLabel2.top+(MyLabel2.Font.Size+MyLabel2.Font.Size div 2) div 2);
 end;
end;




function rez(p:integer): integer;
   begin
   c:=p+20;

   end;


  function toside(j:integer): integer;
  begin
   z:=j+38;

   end;



procedure TForm1.FormCreate(Sender: TObject);
begin
j:=11;
end;






end.
  • Вопрос задан
  • 215 просмотров
Пригласить эксперта
Ответы на вопрос 2
@kisaa
Скриншот бы приложили, что ли :)
Предположу, что линия рисуется до границы Label'а, которая не видна, но есть. А вам, наверное, надо подтянуть ее поближе к тексту (цифре "1").
Попробуйте поиграться со свойством Width (возможно, еще и AutoSize).
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
UPD2. Запомните уж, рисование на форме надо делать только в OnPaint. Сверни-разверни окно — линия исчезнет Код будет примерно такой.
TForm1 = class(TForm)
   ...
  private
    MyLabel,MyLabel2:TLabel;  // тут они занулятся автоматически, да и фэншуйнее
    ...
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
...
MyLabel2.Caption:='3';
Invalidate;   // Запросить перерисовку
end;

procedure TForm1.FormPaint(Sender: TObject);  // Событие OnPaint
begin
  if MyLabel <> nil then
    with Canvas do begin
      Pen.Color:=clRed;
      MoveTo(MyLabel.left,MyLabel.top+(MyLabel.Font.Size+MyLabel.Font.Size div 2) div 2);
      LineTo(MyLabel2.left,MyLabel2.top+(MyLabel2.Font.Size+MyLabel2.Font.Size div 2) div 2);
    end;
end;

А для расчёта ваших выносок вариантов несколько.
1. Нарисовать цифру во внеэкранный буфер и рассчитать размеры реально закрашенной части.
2. Получить метрику шрифта, по ней прикинуть размеры типичной «заглавной» цифры. Справа убрать пиксель межбуквенного пространства, плюс внести какую-то поправку на «узкую» единичку.

UPD3. В чём было дело? А в том, что TGraphicControl (к коим относится и TLabel) — это абстракция Delphi, не имеющая аналога в Windows. Он просто берёт тот TWinControl, на котором находится, в случае Transparent рисует фон под собой через WM_PAINT, а затем рисует себя. При этом чёрточка, нарисованная НЕ через OnPaint, стирается.

UPD4. Полный порядок, рисование через OnPaint — это всё, что надо было. TGraphicControl умный и обходится без лишних перерисовок.

Ну и наконец «хорошие качества» вашего кода.
MyLabel := TLabel.Create(Form1);
MyLabel.Parent := Form1;
Лучше использовать Self, а не Form1.

Form1: TForm1;
   p,c,z,j:integer;
Если бы эти переменные были нужны, лучше было бы их внести в Form1. Если бы…

function rez(p:integer): integer;
   begin
   c:=p+20;

   end;
Мы тут, очевидно, рассчитываем габариты наших надписей. А нельзя это сделать без побочных эффектов?

UPD. Это только макет и будет глючить на высоких DPI. Пожалуйста, если хотите такое широкой публике — усложните расчёты.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы