请教: 事件和消息的联系?

本文深入探讨了VCL框架中TEdit组件的OnKeyPress事件与Win32 API中的WM_CHAR消息之间的映射机制。通过分析TWinControl类的WMChar方法和DoKeyPress函数,揭示了VCL如何处理键盘输入并触发相应的事件。

位大虾,
     这个问题在VCL中是怎样处理的呀?
  例如:Tedit中有一个事件是onkeypress,应用如下:

   procedure tform1.edit1keypress(sender:tobject;var key:char); 
   begin 
   end; 

   那么这个事件是怎么样和WIN32中的WM-CHAR联系上的呢?
   VCL是怎么做的?


TWinControl 
   procedure WMChar(var Message: TWMChar); message WM_CHAR; 
... 

procedure TWinControl.WMChar(var Message: TWMChar); 
begin 
 if not DoKeyPress(Message) then inherited; //这里开始消息响应 
end; 

function TWinControl.DoKeyPress(var Message: TWMKey): Boolean; 
var 
 Form: TCustomForm; 
 Ch: Char; 
begin 
  Result := True;
  Form := GetParentForm(Self);
  if (Form <> nil) and (Form <> Self) and Form.KeyPreview and
    TWinControl(Form).DoKeyPress(Message) then Exit;
  if not (csNoStdEvents in ControlStyle) then
    with Message do
    begin
      Ch := Char(CharCode);
      KeyPress(Ch); //再看这里
      CharCode := Word(Ch);
      if Char(CharCode) = #0 then Exit;
    end;
  Result := False;
end; 

procedure TWinControl.KeyPress(var Key: Char); 
begin 
 if Assigned(FOnKeyPress) then FOnKeyPress(Self, Key); 
end; 

你可以在程序的开头(在Uses后面)先将你的消息赋值为一个常量,如:

const MyMessage = WM_User+1;

然后你要自己定义这个消息的结构,如:

TMyMSG=packed record
  MSG:Cardinal;
  param1:integer;
  param2:integer;
  .. //这里既然是自定义的消息结构,要多少个参数你自己定
  end;

调用的时候Var MSG1:TMyMSG;说明这个消息是MyMSG消息的结构形式的。
这样你只要将常量中定义的MyMessage作为MSG1的域MSG的值就可以发送了。
再说说发送吧,你如果是向窗口过程发送的话(处理后返回),用SendMessge,向消息队列
中发送消息(立即返回)用PostMessege();如果是在程序内部发送消息给程序特定的消息过
程处理,你可以用Tobject的Dispatch()这种方式最简单。
如何确定消息处理过程?
将你的特定过程定义在类的Private部分,并且标明Message MyMessage说明这是一个消息过
程。然后在实现部分将这个过程实现过程写好(注意这里不要Message MyMessage)。这样
你就可以处理自定义的消息了。
这里简单写一下代码,你自己再看看

const MyMessage = WM_User+1;
 
  TMyMSG  record
    MSG:Cardinal;
    param1:integer;
    param2:integer;
  end;
  TForm1=(TForm)
  ..
  
     Mychuli(var msg: TMyMSG);Message MyMessage;
  ..
  
   TForm1.Mychuli(var msg:TMyMSG);
  begin
    MessageBeep(0);
  end;
   TForm1.Button1Click(Sender:Tobject);//单击Button1发送消息
   MSG1: TMyMSG;
  begin
    MSG1.MSG:=MyMessage;
    Dispatch(MSG1);//这是由TForm1负责发送的
 
  ..
 
还有几个方法可以在不同的层次上截获消息。这个就要你自己看看了。

转载于:https://www.cnblogs.com/railgunman/archive/2010/12/10/1902537.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值