牧者

大风起兮云飞扬

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

Delphi中SendMessage使用说明(2)--控件接收SendMessage消息

控件接收SendMessage消息 
上面讨论了用SendMessage向控件发送消息的过程。但凡事有利就有弊,用SendMessage发送的消息在处理上存在着一定困难。因为该消息不经过消息队列,所以无法用OnMessage方式来指定对消息的响应,甚至用HookMainWindow也不行,因为消息直接发送到控件,绕过了主窗体。要对这种类型的消息作出响应,需要重载控件的WndProc方法。


例如,对于一个列表框,滚动条的滚动消息就是用SendMessage方式发送的,因此该消息不在TlistBox的事件列表中。下面是处理控件响应该滚动消息的具体步骤。

1.首先从TlistBox继承一个TmyListBox类,并重载WndProc方法。在程序中加入下列定义: 
type 
TMyListBox=class(TListBox) 
private 
procedure WndProc(var Msg: TMessage); 
override; 
//重载WndProc,处理发送到控件的消息 
public 
end; 
其中WndProc方法指定控件对消息的响应,输入参数是TMessage类型,该数据类型是一个记录,包含了消息代码和消息的参数,消息参数可以用Longint或Word方式获得。

2.对滚动事件做出响应,在WndProc方法中加入如下处理代码: 
  if (Msg.Msg=WM_VSCROLL) and 
(Msg.WParamLo=SB_ENDSCROLL) then 
   begin 
//获得鼠标位置对应的列 
    ItemIndex:=ItemAtPos(Point,true); 
  Form1.Edit1.Text:=inttostr(ItemIndex); 
  inherited; 
   end 
  else 
   inherited; 
当程序接收到WM_VSCROLL消息,且WParamLo参数为SB_ENDSCROLL时,表示竖直滚动条停止滚动,就可以用 
ItemAtPos方法确定与鼠标位置对应的ItemIndex。ItemAtPos方法的Point参数是一个TPoint类型的变量,用来保存鼠标的位置。

3.定义方法ListBoxMouseMove,在鼠标移动时,将当前位置保存在Point中: 
procedure TForm1.ListBoxMouseMove(Sender: 
TObject; Shift: TShiftState; X,Y: Integer); 
   begin 
    Point.X:=X; 
    Point.Y:=Y; 
   end;

4.在运行期创建和初始化列表框,并指定列表框的MouseMove事件对应上一步定义的ListBoxMouseMove方法。

在主窗体的Create事件中输入下面的代码:

begin 
Point.X:=0; 
Point.Y:=0;

//创建自定义列表框 
List:=TMyListBox.Create(Form1); 
List.Parent:=Form1; 
List.Left:=5; 
List.Top:=30; 
List.Width:=150; 
List.Height:=200; 
for i:=0 to 300 do 
begin 
List.Items.Add(inttostr(i)); //初始化 
end;

5.指定处理MouseMove事件的方法 
List.OnMouseMove := ListBoxMouseMove; end; 

posted on 2016-10-20 10:00  牧者.D  阅读(339)  评论(0)    收藏  举报