CM_MOUSEENTER 和 CM_MOUSELEAVE 消息分析

来源:互联网 发布:淘宝网汽车坐垫 编辑:程序博客网 时间:2024/04/29 10:00

在TControl 类中有自定义的消息
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
在我们写控件的时候,可以显示鼠标进入或移除控件的特效
但是CM_MOUSEENTER 和CM_MOUSELEAVE消息是什么时候产生的呢
在Tapplication类中
function TApplication.DoMouseIdle: TControl;
var
  CaptureControl: TControl;
  P: TPoint;
begin
  GetCursorPos(P);
  Result := FindDragTarget(P, True);
  CaptureControl := GetCaptureControl;
  if FMouseControl <> Result then
  begin
    if ((FMouseControl <> nil) and (CaptureControl = nil)) or
      ((CaptureControl <> nil) and (FMouseControl = CaptureControl)) then
      FMouseControl.Perform(CM_MOUSELEAVE, 0, 0);
    FMouseControl := Result;
    if ((FMouseControl <> nil) and (CaptureControl = nil)) or
      ((CaptureControl <> nil) and (FMouseControl = CaptureControl)) then
      FMouseControl.Perform(CM_MOUSEENTER, 0, 0);
  end;
end;

获取鼠标的位置,判断鼠标所在那个控件的范围呢,如果控件改变了,就对这个控件发送

CM_MOUSEENTER,对旧的控件发送CM_MOUSELEAVE。

procedure TApplication.Idle(const Msg: TMsg);
var
  Control: TControl;
  Done: Boolean;
begin
  Control := DoMouseIdle;

DoMouseIdle 是在 Idle函数中调用

继续追踪
procedure TApplication.HandleMessage;
var
  Msg: TMsg;
begin
  if not ProcessMessage(Msg) then Idle(Msg);
end;

这下真相大白了

在没有消息处理的时候,就调用Idle函数,