1

我有12个形状

Shape1
Shape2
.....
Shape12

我有 12 个标签

Label13
Label14
......
Label24

我想知道是否有办法编写这样的函数,在鼠标输入形状时会将相应的标签分配给不同的标签,例如 Label25:

Label25 :=  
OnMouseEnter
shape1 -> label13
shape2 -> label14
...
shape12 -> label24

所以如果鼠标进入Shape1,Label25将等于Label13,如果鼠标进入Shape2,Label25将等于Label14,一直持续到如果鼠标进入Shape12,Label25将等于Label24。

我知道我会写

label25 := labelxx 

在每个鼠标输入事件。但是认为可能有一种更简单的方法,因为标签的名称和形状对应,其中标签 # 每次都比形状 # 多 12。

添加建议后,我添加了这个

procedure TFZone1Mod7.ChangeText(sender: TObject);
var
  ShapeOrderNo: integer;
  FoundComponent: TComponent;
begin
  if TryStrToInt(copy(TShape(Sender).Name,6,MaxInt),ShapeOrderNo) then
    begin
      FoundComponent := FindComponent('label'+inttostr(ShapeOrderNo+12));
      if (FoundComponent is TLabel) then
            Label25.Caption := TLabel(FoundComponent).Caption
      else
          showmessage('not found');
    end;
  showmessage('failed try');

end;

procedure TFZone1Mod7.Shape1MouseEnter(Sender: TObject);
begin
    changetext(self);
end;

end.

但每次它运行我都会失败尝试。我发送的信息有误吗?

4

4 回答 4

6

我不喜欢这种设计,但是,您可以对所有形状使用通用事件处理程序,并使用该FindComponent函数在那里按名称查找组件。然后你可能会写出这样的东西(请注意,它未经测试,仅在浏览器中编写):

var
  ShapeOrderNo: Integer;
  FoundComponent: TComponent;
begin
  // first try to convert a text behind "Shape", what should be a shape's order 
  // and if it's convertable to integer, then...
  if TryStrToInt(Copy(TShape(Sender).Name, 6, MaxInt), ShapeOrderNo) then
  begin
    // try to find a component with the name "label" + found shape order number
    // incremented by 12
    FoundComponent := FindComponent('label' + IntToStr(ShapeOrderNo + 12));
    // if the component is found, or to be more specific, if it's TLabel, then...
    if (FoundComponent is TLabel) then
      TLabel(FoundComponent).Caption := 'Hello from ' + TShape(Sender).Name;
  end;
end;
于 2012-10-19T07:18:08.280 回答
2

在您的 TShape 上添加一个属性。

 TMyShape= class(TShape)
 private
   FLinkLabel: TLabel;
 procedure SetLinkLabel(const Value: TLabel);
 published
   property LinkLabel: TLabel read FLinkLabel write SetLinkLabel;
 end;

 procedure TMyShape.SetLinkLabel(const Value: TLabel);
 begin
   FLinkLabel := Value;
 end;

 procedure TForm1.FormCreate(Sender: TObject);
 var
   oMyShape: TMyShape;
 begin
   oMyShape:= TMyShape.Create(self);
   oMyShape.Parent:= Self;
   oMyShape.LinkLabel:= self.Label1;
   oMyShape.OnMouseEnter:= OnShapeMouseEnter;
 end;

 procedure TForm1.OnShapeMouseEnter(Sender: TObject);
 begin
   if (sender is TMyShape) and
      ( TMyShape(Sender).LinkLabel <>Nil) then
   begin
     TMyShape(Sender).LinkLabel.Caption:= 'Hello';
   end;
 end;

我只是在表单上设置了一个标签并将标签与 TMyShape 链接。

于 2012-10-19T08:04:07.013 回答
2

如果您不在 Forms Designer 中进行控件管理并在运行时创建它们,我会这样做:

声明标签数组和形状数组:

const
  ShapesCount = 20;

type
  TForm1 = class(TForm)
    fLabels: array [0..ShapesCount-1] of TLabel;
    fShapes: array [0..ShapesCount-1] of TShape;

在运行时分配给每个形状 aTag及其索引。

procedure TForm1.OnFormCreate;
begin
  for I := 0 to ShapesCount - 1 do  
  begin
    fShapes[I] := TShape.Create(..);
    fLabels[I] := TLabel.Create(..);
    fShapes[I].Tag := I;
    fShapes[I].OnMouseEnter := OnShapeMouseEnter;
  end;
end;

然后你可以像这样使用它:

procedure TForm1.OnShapeMouseEnter(Sender: TObject);
begin
  Assert(Sender is TShape);
  Label25.Caption := fLabels[TShape(Sender).Tag].Caption;
end;

编辑:再看一点,您可能已经有一个带有 Lable.Captions 的数组,因此您可以从那里直接获取 Label25.Caption。

于 2012-10-19T08:16:29.993 回答
2

如果您不想重新编写标签的创建,请使用 findcomponent:

所有形状的相同处理程序

procedure TForm1.Shape1MouseEnter(Sender: TObject);
var
  ActiveShape: TShape;
  StrName: string;
  ActiveLabel: TComponent;
begin
  if Sender is TShape then
  begin
    ActiveShape := TShape(Sender);
// Only works if Shapes are named Shape1..12 and the labels Label1..12 !!
    StrName := 'Label' + copy(ActiveShape.name, 6, length(ActiveShape.name)); 
    ActiveLabel := FindComponent(StrName);
    if ActiveLabel is TLabel then
      Label25.Caption := TLabel(ActiveLabel).Caption;
  end;
end;

如果有点混乱,这将满足您的需求:)

[编辑]我想到有一种简单的方法可以改进这一点并满足您对具有不同“name_number”的标签的需求:

在设计器中,将每个 TShape 的 Tag 属性设置为您希望与之关联的标签编号。因此,将 shape one 的 Tag 设置为 13(以保留问题)然后

procedure TForm1.Shape1MouseEnter(Sender: TObject);
var
  ActiveShape: TShape;
  StrName: string;
  ActiveLabel: TComponent;
begin
  if Sender is TShape then
  begin
    ActiveShape := TShape(Sender);
    StrName := 'Label' + IntToStr(ActiveShape.Tag); // find tag numbered label
    ActiveLabel := FindComponent(StrName);
    if ActiveLabel is TLabel then
      Label25.Caption := TLabel(ActiveLabel).Caption;
  end;
end;
于 2012-10-19T11:21:29.847 回答