一些没有句柄的控件他们的消息事件是由他们的父窗体负责的。如tspeedButton的点击,
首先由父窗体的WndProc收到,如果消息号处于WM_MOUSEFIRST和WM_MOUSELAST之间则
进一步判断点击区域是否在子控件上,如是则调用子控件的消息函数。
下面是TWinControl中WndProc的代码:
...............
WM_MOUSEFIRST..WM_MOUSELAST:
if IsControlMouseMsg(TWMMouse(Message)) then //关键
begin
if Message.Result = 0 then
DefWindowProc(Handle, Message.Msg, Message.wParam, Message.lParam);
Exit;
end;
.......................
function TWinControl.IsControlMouseMsg(var Message: TWMMouse): Boolean;
var
Control: TControl;
P: TPoint;
begin
if GetCapture = Handle then
begin
Control := nil;
if (CaptureControl <> nil) and (CaptureControl.Parent = Self) then
Control := CaptureControl;
end else
Control := ControlAtPos(SmallPointToPoint(Message.Pos), False);
Result := False;
if Control <> nil then
begin
P.X := Message.XPos - Control.Left;
P.Y := Message.YPos - Control.Top;
Message.Result := Control.Perform(Message.Msg, Message.Keys, Longint(PointToSmallPoint(P)));//关键
Result := True;
end;
end;