【问题标题】:Unable to click custom control in design time无法在设计时单击自定义控件
【发布时间】:2012-05-21 01:22:09
【问题描述】:

我正在 Delphi XE2 中构建一个自定义控件(继承自 TCustomControl)(并且在我的其他控件中遇到过这个问题),在设计时,我无法单击它们。我知道它与鼠标捕获有关,捕获鼠标事件并在设计时以不同于运行时的方式处理它们,但我不知道如何正确适应这一点。换句话说,在我能想到的许多变通方法中,我无法确定哪一个是正确(或最有效)的方法。

我确信这必须有一些非常简单的标准,很可能使用ControlStyleCreateParams 但不知道是什么。

在这个特定的控件中(我没有看到这个问题的模式),我正在捕获包括WM_NCHITTESTWM_LBUTTONDOWN 在内的消息。在设计时,控件就像在运行时一样 100% 处于活动状态,当单击时,它改为执行运行时代码。

我感觉它在我的命中测试消息处理程序中,所以这里的代码(一些东西重命名):

procedure TMyCustomControl.WMNCHitTest(var Message: TWMNCHitTest);
var
  P: TPoint;
  Poly: TPoints;
  X: Integer;
  I: TMyCollectionItem;
  Ch: Bool; //Need to improve invalidation
begin
  Ch:= False;
  P:= ScreenToClient(Point(Message.Pos.X, Message.Pos.Y));
  for X := 0 to Items.Count - 1 do begin
    I:= Items[X];
    Poly:= I.Points;
    FMouseIndex:= -1;
    FMouseState:= bmNone;
    if PointInPolygon(P, Poly) then begin //checks if point is within polygon
      FMouseIndex:= X;
      FMouseState:= bmHover;
      Ch:= True;
      Break;
    end;
  end;
  if Ch then Invalidate;
end;

还有我的控件的构造函数(剥离):

constructor TMyCustomControl.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle:= ControlStyle - [csDesignInteractive];
end;

【问题讨论】:

  • 更具体地说,这个控件是一个水平(或垂直)的项目列表,实际上是箭头。每个项目一个接一个地被绘制为一个多边形,每个项目周围的空间被认为是空的(背景)。将鼠标悬停在某个项目上时,我会突出显示该项目(并对该项目执行其他内部引用)。我还计划将重点放在单个列表项上。

标签: delphi custom-controls mouse delphi-xe2 design-time


【解决方案1】:

但你当然是对的。您没有在 WM_NCHITTEST 处理程序中返回任何内容。当您的处理程序被调用并且您没有为其分配任何其他内容时,您的 Mmessage.Result 为“0”(HTNOWHERE)。

在某个时间点调用 inherited,或者实现您的逻辑并返回(设置 Message.Result)HTCLIENT 以获得您认为是控件内部的点。

这已经是运行时所需的行为,您可以包括设计时检查(但我想您应该出于某种原因进行所有计算):

if csDesigning in ComponentState then
  Msg.Result := HTCLIENT;

【讨论】:

  • +1 csDesigning 成功了——我知道是这样的,但我在寻找 ControlState 而不是 ComponentState 这就是为什么我一开始就找不到答案的原因。谢谢!
【解决方案2】:

在设计时支持鼠标交互的官方方法是用非零结果响应CM_DESIGNHITTEST 消息。然后该组件将接收正常的鼠标消息。

【讨论】:

  • AFAICS CM_DESIGNHITTEST 仅在控件返回 WM_NCHITTEST 的 HTCLIENT 时发送。顺便说一句,通过查看 VCL 源,我不太明白这应该如何工作,它也没有记录。我为测试控制返回 0,但没有观察到任何不同的行为。
  • 您不需要处理WM_NCHITTEST,让默认处理程序为您管理。大多数控件不需要支持设计时交互,因此它们不响应CM_DESIGNHITTEST,但一些本机控件可以,例如那些允许可视化列大小而不是使用对象检查器的控件。
猜你喜欢
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-15
相关资源
最近更新 更多