我试图在TPageControl上使用TLinkLabel,我找不到让它使用它的父级背景的方法。
// Image removed because the website doesn't exist any more
// and I can't find it anywhere... Sorry.
如您所见,父标签页的可爱渐变不会保留在链接文本后面。
我希望在流动的文本块中具有多个链接的功能(TLinkLabel提供的功能)和具有显示在文本后面的父级背景。
TLinkLabel没有ParentBackground属性。我尝试创建一个派生类,将csParentBackground添加到控件样式,但无济于事:
TMyLinkLabel = class (TLinkLabel)
public
constructor Create(AOwner: TComponent); override;
end;
...
constructor TMyLinkLabel.Create(AOwner: TComponent);
begin
inherited;
ControlStyle := ControlStyle - [csOpaque] + [csParentBackground]
end;
有人有什么想法吗?
答案 0 :(得分:7)
Nat,你差不多对ControlStyle
的{{1}}进行了更改。此外,您还需要确保标准Windows静态控件(即TLinkLabel
)的父级正确处理TLinkLabel
消息。
VCL有一个很好的重定向机制,让控件可以处理作为通知发送到父窗口的消息。可以创建一个完全独立的透明链接标签:
WM_CTLCOLORSTATIC
答案 1 :(得分:4)
通常我讨厌当人们提供第三方组件作为答案时,但我会提到TMS THTMLabel作为你想要做的事情的替代方案。它具有TLabel的Transparent属性,并允许您使用HTML作为标题,因此您可以根据您的示例执行多个链接。
答案 2 :(得分:3)
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 :(得分:1)
我能想到的一种方法是在实现
下创建辅助类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;
希望这有效。
答案 4 :(得分:0)
我的建议:使用简单的TLabel。 TLabel有一个名为Transparent的属性 - 这就是你需要的。将TLabels光标设置为crHandPoint(AFAIR这是链接光标),将字体设置为蓝色下划线,并编写OnClick事件处理程序,这将打开Web浏览器以导航到指向的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;
答案 5 :(得分:-1)
如果您的文字是静态的,那么您仍然可以使用标签来执行此操作。布置整个文本块包括您想要的单词作为链接。将标签设置为透明。接下来,删除将成为链接的单独标签组件(也设置为透明)。将颜色更改为clNavy,将字体样式更改为fsunderline,将光标更改为crHand。然后将标签放在现有文本上。然后为每个“链接”标签编写onClick处理程序以执行热链接。
虽然这不是最佳的,但只要您不想加粗文本并且愿意保持文本的字体大小相同,它就会起作用。当然,如果块是动态的,这不能很好地工作,因为你必须计算代码中链接标签的位置,如果你使用wordwrap,这相当复杂。如果没有,您可以使用canvas.textwidth和canvas.textheight方法来确定链接标签所需的偏移位置。