我正在将 32 位代码转换为 64 位代码,并且
.Tag
属性有很多用途。MyInteger := Component.Tag
这样的赋值,虽然形式上是错误的(可能导致范围检查错误),但仍将继续工作。由于这些分配没有编译器提示/警告,我决定离开它们。是我们自己的代码首先将整数放入标签中......
但在其他地方,指向对象的指针被放置在
.Tag
属性中,例如像这样:
procedure IntervalWeergaveSubMenuToevoegen( AParentMenu : TMenuItem; ACaption : String; AInterval : TcxPivotGridGroupInterval; AField : TcxDBPivotGridField );
var lSubMenuItem : TMenuItem;
begin
lSubMenuItem := TMenuItem.Create(Self);
lSubMenuItem.Caption := ACaption;
lSubMenuItem.ImageIndex := Integer(AInterval); // (Mis-)use ImageIndex property to store interval
lSubMenuItem.Tag := Integer(AField); // (Mis-)use Tag property to store reference to field THIS ONE!
lSubMenuItem.GroupIndex := 99;
lSubMenuItem.RadioItem := True;
lSubMenuItem.Checked := (AField.GroupInterval=AInterval);
lSubMenuItem.OnClick := PopupSubMenuWeergaveClick;
AParentMenu.Add(lSubMenuItem);
end;
然后
PopupSubMenuWeergaveClick
,接收一个 TMenuItem
作为它的 Sender
,将 .Tag
转换回 TcxDBPivotGridField
:
procedure TDialoogDynRapport.PopupSubMenuWeergaveClick(Sender: TObject);
begin
inherited;
ExcelPivotGrid.BeginUpdate;
try // TcxDBPivotGridField reference was put in MenuItem.Tag
TcxDBPivotGridField(TMenuItem(Sender).Tag).GroupInterval := TcxPivotGridGroupInterval( TMenuItem(Sender).ImageIndex );
finally
ExcelPivotGrid.EndUpdate;
end;
end;
不是很好,我知道。
我看到两条出路:
IntervalWeergaveSubMenuToevoegen
包含在 TDialoogDynRapport
方法中,所以我可以给 TDialoogDynRapport
一个额外的私有结构来存储 TMenuItem
和 TcxDBPivotGridField
之间的关联。像这个Integer(AField)
分配给另一个演员。毕竟.Tag
现在是8个字节,TcxDBPivotGridField
推荐什么?
Delphi 11.3,没有多线程,也应该在 Win32 中继续工作。
你真的根本不需要“标签”属性。
有一种更好的方法可以将 tMenuitem 映射到一个或多个对象。您可以简单地使用使用 tMenuitem 作为键的 tDictionary(= 快速查找引擎)。
这是一个快速而肮脏的例子:
Uses system.generics.collections, ..... ;
var fieldlookup: tDictionary <tMenuitem, TcxDBPivotGridField>;
intervalLookup: tDictionary <tMenuitem, TcxPivotGridGroupInterval>;
Procedure initialization;
begin
fieldlookup:=tDictionary <tMenuitem, TcxDBPivotGridField>.Create;
intervallookup:=tDictionary <tMenuitem, TcxPivotGridGroupInterval>.Create;
end;
Procedure IntervalWeergaveSubMenuToevoegen(
AParentMenu : TMenuItem;
ACaption : String;
AInterval : TcxPivotGridGroupInterval;
AField : TcxDBPivotGridField);
var lSubMenuItem : TMenuItem;
begin
lSubMenuItem := TMenuItem.Create(Self);
fieldlookup.add(lSubMenuItem, AField);
intervallookup.add(lSubMenuItem, AInterval);
lSubMenuItem.Caption := ACaption;
lSubMenuItem.GroupIndex := 99;
lSubMenuItem.RadioItem := True;
lSubMenuItem.Checked := (AField.GroupInterval=AInterval);
lSubMenuItem.OnClick := PopupSubMenuWeergaveClick;
AParentMenu.Add(lSubMenuItem);
end;
procedure TDialoogDynRapport.PopupSubMenuWeergaveClick(
Sender: TObject);
Var Field:TcxDBPivotGridField; Interval:TcxPivotGridGroupInterval;
begin
if (fieldlookup.TryGetValue(sender as tmenuitem, Field) and
intervallookup.Trygetvalue(sender as tmenuitem, Interval)) then
begin
{Field and interval are now known. Insert rest of event handler code here}
end;
end;