gpt4 book ai didi

delphi - 如何正确响应自定义控件中的焦点消息?

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

我需要创建自己的面板,该面板将从 TCustomPanel 派生 - 在这里我将在面板上进行自己的自定义绘制,例如在顶部绘制标题。

我需要的要求之一是我需要能够根据我的面板是否具有焦点来绘制两种不同的颜色,我还需要一种方法来了解面板内的子控件是否也具有焦点- 当然,尽管不知道子内容可能是什么。

例如,如果面板(或面板内的任何子控件)具有焦点,则颜色可以是 clSkyBlue。如果面板(或面板内的所有子控件)没有焦点,则颜色可能是 clWhite

这是自定义面板的快速布局:(为了保持示例简单,没有标题绘制,只有基本的颜色更改)

type
TMyPanel = class(TCustomPanel)
private
//
protected
// procedure Paint; override;

procedure WMMouseDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;

constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

Self.ParentBackground := False;
Self.ParentColor := False;
end;

destructor TMyPanel.Destroy;
begin
inherited Destroy;
end;

procedure TMyPanel.WMMouseDown(var Message: TWMLButtonDown);
begin
Self.SetFocus;
end;

procedure TMyPanel.WMKillFocus(var Message: TWMKillFocus);
begin
Self.Color := clWhite;
Invalidate;
end;

procedure TMyPanel.WMSetFocus(var Message: TWMSetFocus);
begin
Self.Color := clSkyBlue;
Invalidate;
end;

我遇到的第一个问题是使面板可聚焦,我确信会有一个我忽略的正确解决方案,但在这种情况下,我通过拦截 WM_LBUTTONDOWN 消息使用了一个肮脏的技巧并使小组集中注意力。这当然也否定了我之前提到的其他要求,即子控件还根据面板或其子控件是否获得焦点来决定面板应该是什么颜色。

这就是我点击面板时发生的情况:

enter image description here

这是单击子控件时发生的情况:

enter image description here

正如您所看到的,面板变成了白色,但我需要它变成 clSkyBlue 来指示面板或其子内容具有焦点,应该如下所示:

enter image description here

那么,正确识别我的自定义控件或其子控件是否具有焦点的解决方案是什么?

我曾考虑过迭代面板内的每个子控件以确定它是否具有焦点,但我不确定如何首先触发这样的事件,因为直接单击子控件肯定会忽略任何自定义面板正在等待拦截的消息。

最佳答案

所有 TWinControl 后代都已可聚焦,您的 TCustomPanel 后代也是如此。无需在这方面做任何额外的工作。

不会自动为您完成的(我认为您想要做的)是直观地显示组件的焦点状态。一种可能的方法是处理 CM_ENTERCM_EXIT 消息:

  TMyPanel = class(TCustomPanel)
private
procedure FocusChanged(Value: Boolean);
protected
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMExit(var Message: TCMExit); message CM_EXIT;
end;

procedure TMyPanel.CMEnter(var Message: TCMEnter);
begin
FocusChanged(True);
end;

procedure TMyPanel.CMExit(var Message: TCMExit);
begin
FocusChanged(False);
end;

procedure TMyPanel.FocusChanged(Value: Boolean);
const
Colors: array[Boolean] of TColor = (clWhite, clSkyBlue);
begin
Color := Colors[Value];
end;

关于delphi - 如何正确响应自定义控件中的焦点消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31479073/

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