delphi的消息处理机制TWinControl.WndProc

原创 2012年03月21日 18:27:38

delphi在处理消息的时候是逐级调用的,最基础的算是 TWinControl.WndProc函数了,下面给出了这个函数的源代码。

procedure TWinControl.WndProc(var Message: TMessage);
var
  Form: TCustomForm;
  LMouseEvent: TTrackMouseEvent;
  P: TPoint;
  Target: TControl;
begin
  case Message.Msg of
    CM_UNTHEMECONTROL:
      if (csDesigning in ComponentState) and ThemeServices.ThemesAvailable then
      begin
        SetWindowTheme(Handle, ' ', ' ');
        SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_SHOWWINDOW or SWP_FRAMECHANGED);
      end;
    CM_SETACTIVECONTROL:
      begin
        Form := GetParentForm(Self);
        if (Form <> nil) and (Form <> Self) then
          Form.Perform(CM_SETACTIVECONTROL, Message.WParam, Message.LParam);
      end;
    WM_SETFOCUS:
      begin
        Form := GetParentForm(Self);
        if (Form <> nil) and (not (csDesigning in Form.ComponentState) or (Form.Parent = nil)) then
          if not Form.SetFocusedControl(Self) then Exit;
      end;
    WM_KILLFOCUS:
      if csFocusing in ControlState then Exit;
    WM_NCHITTEST:
      begin
        inherited WndProc(Message);
        if (Message.Result = HTTRANSPARENT) and (ControlAtPos(ScreenToClient(
          SmallPointToPoint(TWMNCHitTest(Message).Pos)), False) <> nil) then
          Message.Result := HTCLIENT;
        Exit;
      end;
    WM_MOUSELEAVE:
      begin
        FMouseInClient := False;
        if FMouseControl <> nil then
          FMouseControl.Perform(CM_MOUSELEAVE, 0, 0)
        else
          Perform(CM_MOUSELEAVE, 0, 0);
        FMouseControl := nil;
      end;
    WM_MOUSEFIRST..WM_MOUSELAST:
      begin
        if Message.Msg = WM_MOUSEMOVE then
        begin
          P := ClientToScreen(Point(TWMMouse(Message).XPos, TWMMouse(Message).YPos));
          CaptureControl := GetCaptureControl;
          if CaptureControl = nil then
            Target := FindDragTarget(P, True)
          else
            Target := CaptureControl;
          if (FMouseControl <> Target) then
          begin
            if ((FMouseControl <> nil) and (CaptureControl = nil)) or
               ((CaptureControl <> nil) and (FMouseControl = CaptureControl)) or
               ((CaptureControl is TControl) and (CaptureControl.Parent = FMouseControl)) then
              FMouseControl.Perform(CM_MOUSELEAVE, 0, 0);
            if FMouseControl <> nil then
              FMouseControl.RemoveFreeNotification(Self);
            FMouseControl := Target;
            if FMouseControl <> nil then
              FMouseControl.FreeNotification(Self);
            if ((FMouseControl <> nil) and (CaptureControl = nil)) or
               ((CaptureControl <> nil) and (FMouseControl = CaptureControl)) then
              FMouseControl.Perform(CM_MOUSEENTER, 0, 0);
          end;
          if not FMouseInClient then
          begin
            FMouseInClient := True;
            // Register for a WM_MOUSELEAVE message which ensures CM_MOUSELEAVE
            // is called when the mouse leaves the TWinControl
            LMouseEvent.cbSize := SizeOf(LMouseEvent);
            LMouseEvent.dwFlags := TME_LEAVE;
            LMouseEvent.hwndTrack := Handle;
            LMouseEvent.dwHoverTime := HOVER_DEFAULT;
            _TrackMouseEvent(@LMouseEvent);
          end;
        end;
        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;
      end;
    WM_MOUSEACTIVATE:
      if IsControlActivateMsg(TWMMouseActivate(Message)) then
      begin
        if (Message.Result = 0) and HandleAllocated then
          inherited WndProc(Message);
        Exit;
      end;
    WM_KEYFIRST..WM_KEYLAST:
      if Dragging then Exit;
    WM_CANCELMODE:
      if (GetCapture = Handle) and (CaptureControl <> nil) and
        (CaptureControl.Parent = Self) then
        CaptureControl.Perform(WM_CANCELMODE, 0, 0);
    CM_DESTROYHANDLE:
      begin
        if Boolean(Message.WParam) then // Sender has csRecreating set
          UpdateRecreatingFlag(True);
        try
          DestroyHandle;
        finally
          if Boolean(Message.WParam) then
            UpdateRecreatingFlag(False);
        end;
        Exit;
      end;
  end;
  inherited WndProc(Message);

  if Message.Msg = WM_UPDATEUISTATE then
    Invalidate; // Ensure control is repainted
end;

这里面有很多消息。欢迎大家讨论分享。



版权声明:本文为博主原创文章,未经博主允许不得转载。

delphi中Message消息的使用方法

实例1 unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For...
  • delphi1234
  • delphi1234
  • 2008年02月20日 18:28
  • 10691

DELPHI 消息处理

在程序员大本营上看到的文章,觉得不错,贴上来 VCL   HardCore   ——   VCL窗口函数注册机制研究手记,兼与MFC比较                 中国软件开发网络   --> ...
  • RegeditNo1
  • RegeditNo1
  • 2010年11月04日 15:47
  • 1833

delphi中Message消息的使用方法

原文:http://blog.csdn.net/delphi1234/article/details/2110083 实例1 unit Unit1;interfaceuses Win...
  • fhfanxin
  • fhfanxin
  • 2016年03月06日 16:35
  • 1213

Delphi TWinControl 类(1)

转自@得闲的博客 Delphi 组件开发教程指南(4)组件生成过程(针对TWinControl继承而来的组件)      还记得在第二章的时候,我用到了procedure CreatePa...
  • lailai186
  • lailai186
  • 2013年04月15日 09:04
  • 2638

Delphi中如何拦截键盘消息

var   st,et,ct: int64; procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char); begin   Q...
  • chinajobs
  • chinajobs
  • 2016年02月17日 19:55
  • 1633

Delphi 的消息机制

=============================================================================== ⊙ 一个 GUI Applicatio...
  • zang141588761
  • zang141588761
  • 2016年09月05日 15:36
  • 1276

delphi中Message消息的使用方法

原文:http://blog.csdn.net/delphi1234/article/details/2110083 实例1 unit Unit1;interfaceuses Win...
  • fhfanxin
  • fhfanxin
  • 2016年03月06日 16:35
  • 1213

理解windows消息机制-delphi消息机制学习笔记。

一、什么是消息? 消息是windows对应用程序发送的有关‘发生了某种事件’的通知。例如点击鼠标,调整窗口大小或键盘上按下一个键,都会引起windows发送一条消息到应用程序中去,去通知应用程序...
  • chinajobs
  • chinajobs
  • 2016年06月23日 16:39
  • 453

delphi VCL研究之消息分发机制-delphi高手突破读书笔记

1.VCL 概貌 先看一下VCL类图的主要分支,如图4.1所示。 在图中可以看到,TObject是VCL的祖先类,这也是Object Pascal语言所规定的。但实际上,TObject以及TObj...
  • sushengmiyan
  • sushengmiyan
  • 2013年03月04日 21:36
  • 3257

Delphi中的消息处理

1、windows的消息驱动体系    在windows系统中,消息传递是实现对乡间通信和控制的主要手段。可以额系统都以消息驱动的方式工作。系统中发生的用户输入操作、显示信息的改变、系统环境参数变化...
  • zang141588761
  • zang141588761
  • 2016年05月19日 08:44
  • 1339
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:delphi的消息处理机制TWinControl.WndProc
举报原因:
原因补充:

(最多只允许输入30个字)