4

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

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

在这个特定的控件中(我没有看到这个问题的模式),我正在捕获消息,包括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;
4

2 回答 2

6

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

要么inherited在某个时候调用,要么实现您的逻辑并返回(设置 Message.Result)HTCLIENT您认为是控件内部的点。

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

if csDesigning in ComponentState then
  Msg.Result := HTCLIENT;
于 2012-05-13T00:52:30.000 回答
5

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

于 2012-05-13T01:59:12.337 回答