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. Пожалуйста, если хотите такое широкой публике — усложните расчёты.