我有这样一种情况,我有一个TImage
,在它的上方部分覆盖着一个TPanel
,它们共享同一个父容器:
------------------
| Image1 |
| ------------ |
| | Panel1 | |
| ------------ |
| |
------------------
Panel1正在接收鼠标的按下/移动/释放事件并进行处理(Image1也是如此),但在某些情况下,我希望将鼠标按下消息“重定向”到Image1,仿佛是单击了Image1而不是Panel1。
这是我所做的:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (ssLeft in Shift) then
Beep;
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
//...
end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('boo!');
end;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
P: TPoint;
begin
if FRedirectToImage then begin
ReleaseCapture; // do I need to send a WM_LBUTTONUP as well to the panel?
GetCursorPos(P);
P := ScreenToClient(P);
Image1.Perform(WM_LBUTTONDOWN, MK_LBUTTON, Longint(PointToSmallPoint(P)));
Exit;
end;
// Normal handling
if (ssLeft in Shift) then begin
// ...
end;
end;
它按预期工作,但我不确定是否是正确的方法。我的问题是,我是否做得对?是否有更好或推荐的方法?
更新(1): 如建议的那样处理WM_NCHITTEST是一个有效的答案,我也考虑过它。即使将Panel1.Enabled设置为False也会将鼠标消息路由到底层的Image1控件。
但是(!)请考虑这种情况:当我单击面板上的x位置时,仍然需要将消息路由到Image1:
------------------
| Image1 |
| --------------
| | Panel1 x |
| --------------
| |
------------------
我的方法是可行的,但在描述的情况下不适用
WM_NCHITTEST
。我仍然没有得到答案,关于我的方法是否有效。(或者也许我应该用上述情况提出另一个问题?)
TApplication
实现一个OnMessage
处理程序,或者使用TApplicationEvents
对象完成相同的操作。在那里,你可以更改感兴趣的消息的目标窗口句柄。 - David Heffernan