在从TPanel
派生的复合组件中,我试图发布一个属性,该唯一的pourpose是设置并获取子组件的链接属性。每次我将复合组件添加到表单时,都会引发访问冲突:
模块“MyRuntimePackage.bpl”中地址12612D86处的访问冲突。读取地址00000080。
我准备了一个使用TLabel
及其PopupMenu
属性的简化示例,但在将复合组件放置在表单/框架上时仍然存在同样的问题。
运行时包:
uses
StdCtrls, Menus, ExtCtrls, Classes;
type
TTestCompoundComponent = class(TPanel)
private
FSubCmp : TLabel;
function GetLabelPopupMenu() : TPopupMenu;
procedure SetLabelPopupMenu(AValue : TPopupMenu);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy(); override;
published
property LabelPopupMenu : TPopupMenu read GetLabelPopupMenu write SetLabelPopupMenu;
end;
...
function TTestCompoundComponent.GetLabelPopupMenu() : TPopupMenu;
begin
Result := FSubCmp.PopupMenu;
end;
procedure TTestCompoundComponent.SetLabelPopupMenu(AValue : TPopupMenu);
begin
if(GetLabelPopupMenu() <> AValue) then
begin
if(GetLabelPopupMenu() <> nil)
then GetLabelPopupMenu().RemoveFreeNotification(Self);
FSubCmp.PopupMenu := AValue;
if(GetLabelPopupMenu() <> nil)
then GetLabelPopupMenu().FreeNotification(Self);
end;
end;
procedure TTestCompoundComponent.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if((AComponent = GetLabelPopupMenu()) AND (Operation = opRemove))
then SetLabelPopupMenu(nil);
end;
constructor TTestCompoundComponent.Create(AOwner : TComponent);
begin
inherited;
FSubCmp := TLabel.Create(nil);
FSubCmp.Parent := Self;
end;
destructor TTestCompoundComponent.Destroy();
begin
FSubCmp.Free;
inherited;
end;
Designtime包:
procedure Register;
begin
RegisterComponents('MyTestCompoundComponent', [TTestCompoundComponent]);
end;
答案 0 :(得分:5)
GetLabelPopupMenu()
FSubCmp
nil
Notification()
opInsert
FSubCmp
FSubCmp
{}}}如果nil
为PopupMenu
,则引用其GetLabelPopupMenu()
属性将导致AV。因此,您需要在if FSubCmp = nil then
Result := nil
else
Result := FSubCmp.PopupMenu;
中检查,例如:
and
否则,请将Notification()
中if (Operation = opRemove) and (AComponent = GetLabelPopupMenu())
逻辑的顺序改为:
(Operation = opRemove)
如果条件<p>(.*?);(.*?)<p>
为假,则不会评估右侧条件(短路)。