gpt4 book ai didi

delphi - 如何知道我是否引用了正确的组件?

转载 作者:行者123 更新时间:2023-12-03 15:45:11 24 4
gpt4 key购买 nike

概述

我重写了一些从 TXPStyleMenuItem 继承的过程,这样我就可以更改使用 TActionMainMenuBar 时菜单的外观。

示例:

  TMyXPStyleMenuItem = class(TXPStyleMenuItem)
protected
procedure DrawBackground(var PaintRect: TRect); override;
end;

我创建了自己的组件,该组件派生自 TActionMainMenuBar,并在 GetControlClass 方法中将 var ControlClass: TCustomActionControlClass 设置为 TMyXPStyleMenuItem。

到目前为止,我所做的一切都运行良好,尽管显然比上面的示例更完整 - 为了解决问题,我使其尽可能简短。

样式器组件

我创建了一个非视觉样式器组件,它基本上只不过是一堆已发布的属性,这个样式器组件可以分配给我的一些控件,在本例中是我的后代 TActionMainMenuBar。

当我的控件分配了样式器组件时,它会读取属性的值,然后根据这些值进行绘制。如果未分配样式器组件,那么我只需使用默认值来决定如何绘制控件。

一个简单的示例来 self 的一个自定义 TEdit,我可以根据指定的样式器值更改颜色:

TMyEdit = class(TCustomEdit)
private
FStyler: TMyStyler;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;

if Assigned(FStyler) then
begin
Color := FStyler.Color;
end;

问题

我面临的问题是 TMyXPStyleMenuItem = class(TXPStyleMenuItem) 中的重写过程。

我需要读取样式器组件的值,但因为 TMyXPStyleMenuItem 实际上并不是我的菜单组件的一部分,所以我无法知道 FStyler 来自哪里,例如它是我的 TActionMainMenuBar 的哪个实例被分配到?

通常 FStyler 在我的菜单类中设置如下:

private
FStyler: TMyStyler;
procedure SetStyler(const Value: TMyStyler);
published
property Styler: TMyStyler read FStyler write SetStyler;

..

procedure TMyMenu.SetStyler(const Value: TMyStyler);
begin
if Value <> FStyler then
begin
FStyler := Value;
end;
end;

但是 TMyXPStyleMenuItem 中的那些过程不知道上述内容。

我无法在覆盖的过程中包含新参数,因为它无法工作,因为声明与基类不同,例如:

procedure DrawBackground(var PaintRect: TRect; AStyler: TMyStyler); override;

差点就拥有了

我得到的最接近的是在我的菜单组件的单元中,我在实现部分上方创建了一个全局变量:

var
FStyler: TMyStyler;

implementation

然后在重写的 DrawBackground 过程中我这样做了:

procedure TMyXPStyleMenuItem.DrawBackground(var PaintRect: TRect);

procedure _DrawBackground(AStyler: TMyStyler);
begin
// handle all the painting from here
// using the values from AStyler.
end;

begin
if Assigned(FStyler) then
_DrawBackground(FStyler);
end;

正当我以为我可以正常工作时,我很快发现事实并非如此。一旦我有了二级菜单或另一种形式的菜单,它就会混淆应该使用哪些样式器值绘制哪个菜单。这是因为理论上我的菜单组件的任何实例都将使用全局 FStyler 变量。

我认为我可以做的另一件事是使用重载指令标记过程,这将让我添加额外的参数,但我仍然不知道我是否引用了正确的菜单组件。

由于我基本上仍在熟悉组件编写等,如果我忽略了一些完全明显的东西,请原谅我。如果它很简单,那么我就完全错过了它 - 如果我说实话,这让我现在有点困惑!

最佳答案

使用 Menu 属性(在 TCustomMenuItem 中声明,它是您的类的祖父)来访问菜单样式器,如下所示:

procedure TMyXPStyleMenuItem.DrawBackground(var PaintRect: TRect);
var
Styler: TMyStyler;
begin
if Menu is TMyActionMainMenuBar then
Styler := TMyActionMainMenuBar(Menu).Styler
else
Styler := nil;
if Assigned(Styler) then
DrawStyledBackground
else
DrawDefaultBackground;
end;

您可以重构代码以添加 GetMenuStyler 方法:

function TMyXPStyleMenuItem.GetMenuStyler: TMyStyler;
begin
if Menu is TMyActionMainMenuBar then
Result := TMyActionMainMenuBar(Menu).Styler
else
Result := nil;
end;

procedure TMyXPStyleMenuItem.DrawBackground(var PaintRect: TRect);
var
Styler: TMyStyler;
begin
Styler := GetMenuStyler;
if Assigned(Styler) then
DrawStyledBackground
else
DrawDefaultBackground;
end;

procedure TMyXPStyleMenuItem.OtherDrawMethod(var PaintRect: TRect);
var
Styler: TMyStyler;
begin
Styler := GetMenuStyler;
if Assigned(Styler) then
...;
end;

关于delphi - 如何知道我是否引用了正确的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15011897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com