TControl的消息覆盖函数大全(15个WM_函数和17个CM_函数,它的WndProc就处理鼠标与键盘消息)

注意,这些函数只有Private一种形式(也就是不允许覆盖,但仍在动态表格中):

  TControl = class(TComponent)
  private
    // 15个私有消息处理,大多是鼠标消息。注意,消息函数大多只是一个中介,且TWinControl并不重写。
    procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;
    procedure WMMButtonDown(var Message: TWMMButtonDown); message WM_MBUTTONDOWN;
    procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
    procedure WMRButtonDblClk(var Message: TWMRButtonDblClk); message WM_RBUTTONDBLCLK;
    procedure WMMButtonDblClk(var Message: TWMMButtonDblClk); message WM_MBUTTONDBLCLK;
    procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
    procedure WMRButtonUp(var Message: TWMRButtonUp); message WM_RBUTTONUP;
    procedure WMMButtonUp(var Message: TWMMButtonUp); message WM_MBUTTONUP;
    //
    procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
    procedure WMMouseWheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL;
    procedure WMCancelMode(var Message: TWMCancelMode); message WM_CANCELMODE;
    procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED; // 重新计算最大化最小化的限制和坞里的尺寸
    procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU; // 真正展开右键菜单,其子类虽然覆盖这个函数,但反而只是帮助发送而已(发送给图形控件,为其增加右键菜单功能)。
    // 17个组件事件(大多是简单函数,通知某件事情,一般没有实际内容)
    // CM_显示函数
    procedure CMVisibleChanged(var Message: TMessage); message CM_VISIBLECHANGED; // 显示属性被改变了,那么要调用InvalidateControl重画自己。fixme 不明白这句为什么一定要这样调用,而不是执行Invalidate函数
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED; // 3个函数都简单调用Invalidate; 但是注意,它有可能调用子类TWinControl的Invalidate函数
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
    procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED;
    procedure CMParentBiDiModeChanged(var Message: TMessage); message CM_PARENTBIDIMODECHANGED;
    // 颜色字体
    procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;
    procedure CMSysFontChanged(var Message: TMessage); message CM_SYSFONTCHANGED;  // 调用SetFont
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CMParentShowHintChanged(var Message: TMessage); message CM_PARENTSHOWHINTCHANGED; // 调用 SetShowHint
    procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW;
    procedure CMHitTest(var Message: TCMHitTest); message CM_HITTEST; // 测试鼠标消息对子控件是否起作用
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; // important 有趣,给父控件发送CM_MOUSEENTER,为什么要依赖它来处理?
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMDesignHitTest(var Message: TCMDesignHitTest); message CM_DESIGNHITTEST; // important5 什么都不做,消息结果为未处理
    procedure CMFloat(var Message: TCMFloat); message CM_FLOAT;
    procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL; // 给父控件发送CM_MOUSEWHEEL
end;

同时把它的WndProc列出来,这样它能处理的消息就齐了:

procedure TControl.WndProc(var Message: TMessage);
var
  Form: TCustomForm;
  KeyState: TKeyboardState;
  WheelMsg: TCMMouseWheel;
begin
  if (csDesigning in ComponentState) then
  begin
    Form := GetParentForm(Self);
    if (Form <> nil) and (Form.Designer <> nil) and
      Form.Designer.IsDesignMsg(Self, Message) then Exit //消息由窗体来处理
  end;
  //窗体可以为其拥有的组件来处理键盘消息
  if (Message.Msg >= WM_KEYFIRST) and (Message.Msg <= WM_KEYLAST) then
  begin
    Form := GetParentForm(Self);
    if (Form <> nil) and Form.WantChildKey(Self, Message) then Exit;
  end
  // important 图形控件的鼠标处理都在这里
  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); // 如果是鼠标移动的消息,则出现hint窗口
      WM_LBUTTONDOWN, WM_LBUTTONDBLCLK: // 如果是左键被按下,或者双击,如果是自动拖动模式,则开始拖动,并将左键按下的状态加入组件的状态。
        begin
          if FDragMode = dmAutomatic then
          begin
            BeginAutoDrag;
            Exit;
          end;
          Include(FControlState, csLButtonDown); // important 为图形控件(也可为Win控件)增加鼠标点击状态。点击Button就会执行到这里来。
        end;
      WM_LBUTTONUP:
        Exclude(FControlState, csLButtonDown); //如果是左键放开,则将左键按下的状态剔除。
    else
      with Mouse do
        if WheelPresent and (RegWheelMessage <> 0) and //如果鼠标有滚轮,并且滚轮滑动时发出了消息
          (Message.Msg = RegWheelMessage) then
        begin
          GetKeyboardState(KeyState); // API,将256虚拟键的状态拷贝到缓存中去
          with WheelMsg do //填充记录
          begin
            Msg := Message.Msg;
            ShiftState := KeyboardStateToShiftState(KeyState);
            WheelDelta := Message.WParam;
            Pos := TSmallPoint(Message.LParam);
          end;
          MouseWheelHandler(TMessage(WheelMsg)); // 类函数,派发鼠标滚轮的消息
          Exit;
        end;
    end;
  end
  else if Message.Msg = CM_VISIBLECHANGED then
    with Message do
      SendDockNotification(Msg, WParam, LParam);
  Dispatch(Message); // 到了这里,已经无法再使用WndProc方法向父类传递消息了,所以使用Dispatch。而且必定向上传递(一般情况下TControl的父类不会不响应这些消息)
end;
时间: 2024-10-13 13:34:02

TControl的消息覆盖函数大全(15个WM_函数和17个CM_函数,它的WndProc就处理鼠标与键盘消息)的相关文章

Hook 简单的实例--拦截鼠标和键盘消息(一)

Hook(钩子)就是对Windows系统的一些消息或是API函数进行拦截和监控的处理平台,让可以根据程序员的设置获取其感兴趣的信息. 这里主要是介绍一下Hook拦截鼠标消息和键盘消息. 下面是CALLBACK Proc 回调函数 和 CallNextHookEx函数 LRESULT CALLBACK HookProc ( int nCode, //指定是否需要处理该消息 WPARAM wParam, LPARAM lParam //包含该消息的附加消息 , ); 这个回调函数的名字可以随你取,但

钩子函数大全(2)

[转载]钩子函数大全(2) (2010-07-21 11:12:26) 转载▼ 标签: 转载   还是很好的,木马函数挂钩 原文地址:钩子函数大全(2)作者:老代码 CallNextHookEx 函数功能:该函数发送挂钩信息给当前挂钩链中的下一个挂钩处理过程,一个挂钩处理过程可在对该挂钩信息进行处理之前或之后调用本函数. 函数原形:LRESULT CallNextHookEx(HHOOK hhk,int nCode,WPARAM wParam,LPARAM lParam); 参数: hhk:当前

TWinControl的消息覆盖函数大全(41个WM_函数和31个CM_函数,它的WndProc就处理鼠标(转发)、键盘(取消拖动)、焦点、和WM_NCHITTEST一共4类消息)

注意,这些函数只有Private一种形式(也就是不允许覆盖,但仍在动态表格中): TWinControl = class(TControl) private // 41个windows消息,几乎全部消息都是私有函数(因为不需要别人来调用).很多都是覆盖消息,也有少部分是首次出现. // 总结规律:直接接受消息的函数都起一个中转站的作用,其函数内容都十分简单. // WM_PAINT第一次出现,由某些直接继承Win控件的类使用.而图形控件和自绘控件会自己响应这个消息. // TControl 类控

【转】NI语法 JNI参考 JNI函数大全

原文网址:http://blog.sina.com.cn/s/blog_5de73d0b0101chk1.html 一.对照表 Java类型    本地类型         描述boolean    jboolean       C/C++8位整型byte       jbyte          C/C++带符号的8位整型char       jchar          C/C++无符号的16位整型short      jshort         C/C++带符号的16位整型int    

delphi常用函数大全(转)

Abort函数引起放弃的意外处理Abs函数绝对值函数AddExitProc函数将一过程添加到运行时库的结束过程表中Addr函数返回指定对象的地址AdjustLineBreaks函数将给定字符串的行分隔符调整为CR/LF序列Align属性使控件位于窗口某部分Alignment属性控件标签的文字位置AllocMem函数在堆栈上分配给定大小的块AllowGrayed属性允许一个灰度选择AnsiCompareStr函数比较字符串(区分大小写)AnsiCompareText函数比较字符串(不区分大小写)A

JNI语法 JNI参考 JNI函数大全

原文地址:JNI语法 JNI参考 JNI函数大全 内容太多,请按Ctrl+F查找你需要的信息. 一.对照表 Java类型    本地类型         描述 boolean    jboolean       C/C++8位整型 byte       jbyte          C/C++带符号的8位整型 char       jchar          C/C++无符号的16位整型 short      jshort         C/C++带符号的16位整型 int        j

PHP内置函数大全

1 php内置函数大全 2 第2章 Apache函数 15 3 2.1 Apache信息获取类函数 15 4 2.1.1 apache_child_terminate函数:在本次请求结束后终止Apache进程 15 5 2.1.2 apache_get_modules函数:获取Apache的模块列表 16 6 2.1.3 apache_get_version函数:获取Apache的版本 16 7 2.1.4 apache_getenv函数:获取Apache的环境变量 17 8 2.1.5 apa

文华财经函数大全

文华财经函数大全 1.引用数据 AVPRICE 引用均价(在盘后对于国内三个期货交易所指结算价)SETTLE 引用结算价(如果用在周期小于'日'的K线上如5分钟K线,一小时k线,每根k线返回的值表示这根k线当日开盘时到这根k线的为止的结算价(均价)如果用在周期大于等于'日'的K线上,返回当根K线结束时间所在日的结算价.)CLOSE 引用收盘价(在盘中指最新价),也可简写为C.HIGH 引用最高价,也可简写为H.LOW 引用最低价,也可简写为L.OPEN 引用开盘价,也可简写为O.OPI 引用持仓

PLSQL_Oracle PLSQL内置函数大全(概念)

2014-06-20 BaoXinjian PLSQL常用方法大全 1.ASCII 返回与指定的字符对应的十进制数; SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') space from dual; A         a      ZERO     SPACE --------- --------- --------- --------- 65        97        48        32 2.CH