gpt4 book ai didi

delphi - 如何使我的自定义控件在其表单或应用程序接收和失去焦点时收到通知?

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

我希望我的控件仅在其父窗体(不是面板或其他内容,只是此控件的主窗体)接收和失去焦点时接收不同的通知。无论焦点是从另一种形式的应用程序还是在我的应用程序和其他应用程序之间切换,这两种情况都必须收到。是否可以?我想在表单未激活时暂停控件的某些更新,并在激活表单时恢复更新。

编辑:换句话说,控件必须捕获 (TForm.OnActivate + TApplication.OnActivate) 和 (TForm.OnDeactivate + TApplication.OnDeactivate)

Edit2:如果两者都不可能,至少我可以使控件捕获来自 TApplication 的事件。它比 TForm 中的更重要。

最佳答案

I want to suspend some updates of the control when his form is not active and resume the updates when the form is activated.

如果这些更新是连续完成的,或者是由计时器或操作触发的,那么您可以这样做:

type
TMyControl = class(TControl)
private
procedure PerformUpdate;
end;

procedure TMyControl.PerformUpdate;
begin
if Application.Active and HasParent and GetParentForm(Self).Active then
//...
else
//...
end;

...at least if I can make the control catch the events from the application

捕捉TApplication.OnActivateTApplication.OnDeactivate使用 TApplicationEvents 非常容易组件:

uses
Vcl.AppEvnts;

type
TMyControl = class(TControl)
private
FActive: Boolean;
FAppEvents: TApplicationEvents;
procedure ApplicationActiveChanged(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
end;

procedure TMyControl.ApplicationActiveChanged(Sender: TObject);
begin
FActive := Application.Active;
end;

constructor TMyControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAppEvents := TApplicationEvents.Create(Self);
FAppEvents.OnActivate := ApplicationActiveChanged;
FAppEvents.OnDeactivate := ApplicationActiveChanged;
end;

...it's more important than those from the form

可以在 Application.OnIdle 中捕获育儿表单的(取消)激活。 。所有这些结合起来可能会导致如下结果:

type
TMyControl = class(TControl)
private
FActive: Boolean;
FAppEvents: TApplicationEvents;
FParentForm: TCustomForm;
procedure ApplicationActiveChanged(Sender: TObject);
procedure ApplicationIdle(Sender: TObject; var Done: Boolean);
procedure UpdateActive;
protected
procedure SetParent(AParent: TWinControl); override;
public
constructor Create(AOwner: TComponent); override;
end;

procedure TMyControl.ApplicationActiveChanged(Sender: TObject);
begin
UpdateActive;
end;

procedure TMyControl.ApplicationIdle(Sender: TObject; var Done: Boolean);
begin
UpdateActive;
Done := True;
end;

constructor TMyControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAppEvents := TApplicationEvents.Create(Self);
FAppEvents.OnActivate := ApplicationActiveChanged;
FAppEvents.OnDeactivate := ApplicationActiveChanged;
end;

procedure TMyControl.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
FParentForm := GetParentForm(Self);
end;

procedure TMyControl.UpdateActive;
var
SaveActive: Boolean;
begin
SaveActive := FActive;
FActive := Application.Active and (FParentForm <> nil) and FParentForm.Active;
if Application.Active then
FAppEvents.OnIdle := ApplicationIdle
else
FAppEvents.OnIdle := nil;
if FActive <> SaveActive then
Invalidate;
end;

因为使用Application.OnIdle是一个相当严格的方法,像我上面那样通过仅在必要时分配它来避免使用它,并通过缓存像GetParentForm这样的函数结果来加速其实现。 .

关于delphi - 如何使我的自定义控件在其表单或应用程序接收和失去焦点时收到通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30895079/

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