我在窗体Form1放了个TImage控件Image1
TGraphicControl控件的一些事件是依靠它的父控件TWinControl来产生的
在这里Image1的Parent为TForm1;
当点击Image1时,我跟踪了下,是这样的,我只说主要的
TWinControl的WndProc中的(Controls单元的6226行)
WM_MOUSEFIRST..WM_MOUSELAST:
if IsControlMouseMsg(TWMMouse(Message)) then
begin
{ Check HandleAllocated because IsControlMouseMsg might have freed the
window if user code executed something like Parent := nil. }
if (Message.Result = 0) and HandleAllocated then
DefWindowProc(Handle, Message.Msg, Message.wParam, Message.lParam);
Exit;
end;
当我把鼠标移到Image1并单击了一下,产生了WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_LBUTTONUP
在WM_MOUSEFIRST和WM_MOUSELAST范围内,
调用IsControlMouseMsg(TWMMouse(Message));
源码如下
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;
WM_MOUSEMOE被通过ControlAtPos所确定的Image1控件Perform出去了,先不说了。
WM_LBUTTONDOWN过来了
然后调用Perform,Perform调用TControl的WindowProc
TControl的WndProc又对这个消息做了些处理
else if (Message.Msg >= WM_MOUSEFIRST) and (Message.Msg <= WM_MOUSELAST) then
begin
if not (csDoubleClicks in ControlStyle) then
case Message.Msg of
WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDBLCLK:
Dec(Message.Msg, WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
end;
case Message.Msg of
WM_MOUSEMOVE: Application.HintMouseMessage(Self, Message);
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
begin
if FDragMode = dmAutomatic then
begin
BeginAutoDrag;
Exit;
end;
Include(FControlState, csLButtonDown);
end;
然后TControl的WndProc把WM_LBUTTONDOWN消息Dispatch出去
调用TControl.WMLBUTTONDOWN
procedure TControl.WMLButtonDown(var Message: TWMLButtonDown);
begin
SendCancelMode(Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := True;
if csClickEvents in ControlStyle then Include(FControlState, csClicked);
DoMouseDown(Message, mbLeft, []);
end;
同样WM_LBUTTONUP也是这样当调用到TControl.WMLButtonUp时
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
end;
DoMouseUp(Message, mbLeft);
end;
这个Click事件就产生了
代码贴了一大堆,不好意思。
说的也乱七八糟,唉,跟我做人的风格也一样
呵呵