简单深刻:为控件创建MouseEnter和MouseLeave事件(覆盖WndProc,增加对消息的处理,真简单!)——连对CM_MOUSEENTER的消息处理都是颇有深意啊!

其实很简单:

unit Unit1; 

interface 

uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  StdCtrls; 

type 

  TURLLabel = class(TLabel) 
    procedure WndProc(var Message : TMessage); override; 
  end; 

type 
  TForm1 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
  private 
    { Private declarations } 
  public 
    { Public declarations } 
  end; 

var 
  Form1: TForm1; 

implementation 

{$R *.DFM} 

{ TURLLabel } 

procedure TURLLabel.WndProc(var Message: TMessage); 
begin 
  if (Message.Msg = CM_MOUSEENTER) then 
  begin 
    Font.Color := clBlue; 
    Font.Style := Font.Style + [fsUnderline]; 
  end; 
  if (Message.Msg = CM_MOUSELEAVE) then 
  begin 
    Font.Color := clWindowText; 
    Font.Style := Font.Style - [fsUnderline]; 
  end; 
  inherited WndProc(Message); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  with TURLLabel.Create(Self) do 
  begin 
    Parent := Self; 
    Left := 10; 
    Top := 10; 
    caption := 'www.delphi3000.com'; 
    Cursor := crHandPoint; 
  end; 
end; 

end. 

转自http://www.delphi3000.com/articles/article_1050.asp?SK=

--------------------------------------------------------------------------------------

稍微分析一下,inherited WndProc(Message)会导致执行:

procedure TControl.CMMouseEnter(var Message: TMessage);
begin
  if FParent <> nil then
    FParent.Perform(CM_MOUSEENTER, 0, Longint(Self)); // 把控件自己的指针当参数传过去,即表明当前消息来自于哪个控件
end;

procedure TControl.CMMouseLeave(var Message: TMessage);
begin
  if FParent <> nil then
    FParent.Perform(CM_MOUSELEAVE, 0, Longint(Self));
end;

即告诉父控件,有鼠标移入了。但是TWinControl没有CM_MOUSEENTER消息函数,所以就不了了之了。

这个例子说明,TControl的许多行为都不仅仅属于自己,即使自己处理了,还必须通知一下TWinControl父控件(而且是向上回溯通知所有祖先控件),看它们有什么意见(就好象小孩做了事情,要报告父母一样)。

posted @ 2016-03-23 05:42  findumars  Views(1090)  Comments(0Edit  收藏  举报