【发布时间】:2012-12-13 20:26:46
【问题描述】:
我有一个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,从这个问题的第一个视图中看不到它,但 OP 真的想重定向消息。所以,这就是要走的路。
-
@TLama 我不想在这里写答案。请不要为自己这样做而感到压抑!
-
@DavidHeffernan,“我不想在这里写答案”。这是为什么呢?
-
RE (update1):最初的问题并不清楚,即使鼠标不在图像区域内,您也需要鼠标消息,因此您得到了答案。另外,在图像区域之外,不应该单击图像,不是吗?如果它们适合您的需求,答案会更好。如果您不需要启用的面板,则禁用面板肯定没问题。我没有测试你的代码,所以我不能评论主要功能,但它看起来不太正确——你甚至没有将点转换为图像的坐标。而且你已经在 (X, Y) 中有一个点,不需要 GetCursorPos。