Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Delphi中,当控件的父控件接收并失去焦点时,如何通知控件?_Delphi_Components_Vcl - Fatal编程技术网

在Delphi中,当控件的父控件接收并失去焦点时,如何通知控件?

在Delphi中,当控件的父控件接收并失去焦点时,如何通知控件?,delphi,components,vcl,Delphi,Components,Vcl,正如标题所说,我希望组件(例如,标签)在其父组件(例如,面板)接收并失去焦点时得到通知。我在Delphi源代码中漫游了一下,希望使用TControl.Notify,但它只用于通知子控件一些属性更改,如字体和颜色。有什么建议吗?每当应用程序中的活动控件发生更改时,会向所有控件广播一条CM\u FOCUSCHANGED消息。简单地拦截它,并相应地采取行动 另外,我假设当其父控件(比如面板)接收并失去焦点时,您的意思是当其父控件/面板上的(嵌套)子控件接收或失去焦点时 type TLabel =

正如标题所说,我希望组件(例如,
标签
)在其父组件(例如,
面板
)接收并失去焦点时得到通知。我在Delphi源代码中漫游了一下,希望使用
TControl.Notify
,但它只用于通知子控件一些属性更改,如字体和颜色。有什么建议吗?

每当应用程序中的活动控件发生更改时,会向所有控件广播一条
CM\u FOCUSCHANGED
消息。简单地拦截它,并相应地采取行动

另外,我假设当其父控件(比如面板)接收并失去焦点时,您的意思是当其父控件/面板上的(嵌套)子控件接收或失去焦点时

type
  TLabel = class(StdCtrls.TLabel)
  private
    function HasCommonParent(AControl: TWinControl): Boolean;
    procedure CMFocusChanged(var Message: TCMFocusChanged);
      message CM_FOCUSCHANGED;
  end;

procedure TLabel.CMFocusChanged(var Message: TCMFocusChanged);
const
  FontStyles: array[Boolean] of TFontStyles = ([], [fsBold]);
begin
  inherited;
  Font.Style := FontStyles[HasCommonParent(Message.Sender)];
end;

function TLabel.HasCommonParent(AControl: TWinControl): Boolean;
begin
  Result := False;
  while AControl <> nil do
  begin
    if AControl = Parent then
    begin
      Result := True;
      Break;
    end;
    AControl := AControl.Parent;
  end;
end;

请注意,我选择了
TLabel
来演示此功能也适用于
TControl
衍生产品。

这是用于您自己的控件(标签)吗?在表单上,您可以简单地为父级(面板)编写OneNet和OnExit事件处理程序。面板是否实际接收焦点?为所有面板分配一组OneNet和OnExit事件处理程序。在处理程序内部,您可以通过发送方的子控件循环查找JvGradientHeader对象,然后根据需要进行更新。另一个选项是对每个面板进行子类化,以捕获CM_FOCUSCHANGED消息,然后向发送方的子控件广播自定义定义的CM_PARENTFOCUSCHANGED消息。然后,您可以对JvGradientHeader控件进行子类化以捕获该消息。这听起来是创建从TPanel继承并拥有JvGradientHeader的复合控件的好时机。然后可以覆盖Tpanel控件的exit和enter虚拟方法。面向对象编程是你的朋友。我学到了一些好东西。我一直认为只有表单才能有消息处理程序。非常感谢:-)
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FHeaders: TList;
    procedure ActiveControlChanged(Sender: TObject);
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FHeaders := TList.Create;
  FHeaders.Add(Label1);
  FHeaders.Add(Label2);
  Screen.OnActiveControlChange := ActiveControlChanged;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FHeaders.Free;
end;

function HasCommonParent(AControl: TWinControl; AMatch: TControl): Boolean;
begin
  Result := False;
  while AControl <> nil do
  begin
    if AControl = AMatch.Parent then
    begin
      Result := True;
      Break;
    end;
    AControl := AControl.Parent;
  end;
end;

procedure TForm1.ActiveControlChanged(Sender: TObject);
const
  FontStyles: array[Boolean] of TFontStyles = ([], [fsBold]);
var
  I: Integer;
begin
  for I := 0 to FHeaders.Count - 1 do
    TLabel(FHeaders[I]).Font.Style :=
      FontStyles[HasCommonParent(Screen.ActiveControl, TLabel(FHeaders[I]))];
end;