我正在Delphi XE2中构建一个自定义控件(继承自TCustomControl
)(并在我的其他控件中遇到此问题),在设计时,我无法单击它们。我知道它与鼠标捕获有关,捕获鼠标事件并在设计时间内处理它们的方式与运行时间不同,但我不知道如何正确适应这一点。换句话说,在我能想到的许多工作中,我无法确定哪一种是正确的(或最有效的)方式。
我确信必须有一些非常简单的标准,很可能使用ControlStyle
或CreateParams
,但不知道是什么。
在这个特定的控件中(我在这个问题上没有看到模式),我正在捕获包括WM_NCHITTEST
和WM_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;
答案 0 :(得分:6)
但当然你是对的。您没有在WM_NCHITTEST
处理程序中返回任何内容。调用处理程序时,Mmessage.Result
为'0'(HTNOWHERE),并且您没有为其分配任何其他内容。
要么在某个时刻调用inherited
,要么实现你的逻辑并返回(设置Message.Result)HTCLIENT
以获得你认为是控制内部的点。
这已经是运行时所需的行为,你可以包括一个设计时间检查(但我猜你应该因为一个原因而进行所有计算):
if csDesigning in ComponentState then
Msg.Result := HTCLIENT;
答案 1 :(得分:5)
在设计时支持鼠标交互的官方方法是对CM_DESIGNHITTEST
消息进行非零结果响应。然后该组件将接收正常的鼠标消息。