История TLinkLabel на TPageControl

Я имел эту ту же проблему прежде и нашел этот отрывок очень полезным:

class Tee(object):
    def __init__(self, name, mode):
        self.file = open(name, mode)
        self.stdout = sys.stdout
        sys.stdout = self
    def __del__(self):
        sys.stdout = self.stdout
        self.file.close()
    def write(self, data):
        self.file.write(data)
        self.stdout.write(data)
    def flush(self):
        self.file.flush()

от: http://mail.python.org/pipermail/python-list/2007-May/438106.html

12
задан Nat 6 December 2014 в 05:10
поделиться

6 ответов

Нат, вы почти готовы внести изменения в ControlStyle из TLinkLabel . Кроме того, вам необходимо убедиться, что родительский элемент стандартного статического элемента управления Windows (то есть TLinkLabel ) правильно обрабатывает сообщение WM_CTLCOLORSTATIC .

VCL имеет удобный механизм перенаправления, позволяющий элементам управления обрабатывать сообщения, которые отправляются как уведомления в их родительские окна. Используя это, можно создать полностью автономную прозрачную метку ссылки:

type
  TTransparentLinkLabel = class(TLinkLabel)
  private
    procedure CNCtlColorStatic(var AMsg: TWMCtlColorStatic);
      message CN_CTLCOLORSTATIC;
  public
    constructor Create(AOwner: TComponent); override;
  end;

constructor TTransparentLinkLabel.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle - [csOpaque] + [csParentBackground];
end;

procedure TTransparentLinkLabel.CNCtlColorStatic(var AMsg: TWMCtlColorStatic);
begin
  SetBkMode(AMsg.ChildDC, TRANSPARENT);
  AMsg.Result := GetStockObject(NULL_BRUSH);
end;
7
ответ дан 2 December 2019 в 21:03
поделиться

Оба стиля csParentBackground и csOpaque требуют взаимодействия других частей кода элемента управления. Простая установка их не принесет большого эффекта; если бы это было так, то элемент управления, вероятно, уже имел бы общедоступное свойство Transparent .

Вы можете посмотреть TCustomLabel.Paint , чтобы увидеть, как он учитывает csOpaque стиль. Он проверяет этот стиль, считывая его свойство Transparent , прежде чем рисовать фон:

if not Transparent then
begin
  Canvas.Brush.Color := Self.Color;
  Canvas.Brush.Style := bsSolid;
  FillRect(ClientRect);
end;

Стиль csParentBackground не влияет на TCustomLabel , потому что этот стиль влияет только на оконные элементы управления; TCustomLabel происходит от TGraphicControl , а не TWinControl .

У меня нет TLinkLabel , поэтому я не могу посмотреть его исходный код, чтобы выяснить, что ему нужно изменить. Если это потомок TGraphicControl , тогда он должен будет включить код, как я показал выше, из TCustomLabel . Если он происходит от TWinControl , я бы вместо этого адаптировал код из TCustomStaticText . Это немного сложнее; он вызывает DrawParentBackground в ответ на уведомление cn_CtlColorStatic . Он также не рисует себя в коде Delphi. Этот элемент управления является оболочкой для «статического» типа элемента управления Win32.

TLinkLabel , очевидно, безоговорочно рисует его фон. Чтобы исправить это, вам нужно переопределить метод Paint . Удаление функциональности (фоновое рисование, в этом случае) трудно сделать с традиционным способом переопределения виртуальных методов, потому что вы не сможете вызвать унаследованный метод, чтобы нарисовать весь текст. Вместо этого вам, вероятно, придется скопировать и вставить реализацию базового класса, а затем добавить условные части где-нибудь посередине.

3
ответ дан 2 December 2019 в 21:03
поделиться

Мой совет: используйте простой TLabel. TLabel имеет свойство Transparent - это то, что вам нужно. Установите курсор TLabels на crHandPoint (AFAIR это курсор ссылки), установите шрифт на синее подчеркивание и напишите обработчик события OnClick, который откроет веб-браузер для перехода к указанному URL-адресу. У вас даже может быть один обработчик событий по умолчанию.

procedure OnClickOnMyLinkTLabels(Sender : TObject);
var
  Address : string;
begin
  if NOT (Sender is TLabel) then Exit;
  Address := (Sender as TLabel).Caption;
  ShellExecute(self.WindowHandle,'open',PChar(Address),nil,nil, SW_SHOWNORMAL);
end;

Изменить :

Если вы не хотите, чтобы адрес был в заголовке, вы можете использовать свойство Tag, чтобы получить адрес и установить заголовок, который вам нужен:

procedure OnClickOnMyLinkTLabels(Sender : TObject);
var
  Address : string;
begin
  if NOT (Sender is TLabel) then Exit;
  Address :=  GetAddresByTag( (Sender as TLabel).Tag );
  ShellExecute(self.WindowHandle,'open',PChar(Address),nil,nil, SW_SHOWNORMAL);
end;

] Как вы будете реализовывать GetAddresByTag - это ваш выбор. Самый простой - использовать массив строк:

//in your form defintion
   private
     FAddresses : array of string;

function GetAddresByTag(id : integer): string;
begin
  if (i<Low(FAddresses)) OR (I> High(FAddresses)) then
    raise EXception.Create('wrong id sent!');
  Result:= FAddresses[id];
end;
0
ответ дан 2 December 2019 в 21:03
поделиться

Один из способов, который я могу придумать, - это создать вспомогательный класс в рамках реализации

type
  TLinkLabelHelper = class helper for TLinkLabel
  public
    procedure Add(const aBGColor: TColor; const S: string);
  end;

procedure TLinkLabelHelper.Add(const aBGColor: TColor; const S: string);
begin
  Color := aBGColor;
  Caption := S;
end;

Затем я создаю общедоступный

procedure AfterConstruction; override;

procedure Form_A.AfterConstruction;
begin
  inherited;
  LinkLabel1.Add(Self.Color, 'Hello World');
end;

Надеюсь, что это сработает.

1
ответ дан 2 December 2019 в 21:03
поделиться

Обычно я ненавижу, когда люди предлагают сторонний компонент в качестве ответа, но я упомяну TMS THTMLabel как альтернативу тому, что вы хотите сделать. Он имеет свойство Transparent TLabel и позволяет использовать HTML в качестве заголовка, поэтому вы можете создавать несколько ссылок в соответствии с вашим примером.

4
ответ дан 2 December 2019 в 21:03
поделиться

If your text is static, then you can still do this using labels. Lay out your entire text block INCLUDING the words you want as links. Set the label as transparent. Next, drop separate label components (also set to transparent) that will be the link. Change the color to clNavy, font style to fsunderline and the cursor to crHand. Then position the label OVER the existing text. Then write a onClick handler for each "link" label to perform your hot link.

While this is not optimal, it does work as long as you don't want to bold the text and are willing to keep the text the same font size. Of course this doesn't work so well if the block is dynamic, as you would have to calculate the position of the link labels in code, which is fairly complicated if you are using wordwrap. If not, you can use the canvas.textwidth and canvas.textheight methods to determine the necessary offset positions for your link labels.

-1
ответ дан 2 December 2019 в 21:03
поделиться
Другие вопросы по тегам:

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