SendMessage基本认识

SendMessage基本认识SendMessage基本认识函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。函数原型:LRESULTSendMessage(HWNDhWnd,UI

大家好,欢迎来到IT知识分享网。

SendMessage基本认识

函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。   
  函数原型:LRESULT   SendMessage(HWND   hWnd,UINT   Msg,WPARAM   wParam,LPARAM   IParam);   
  参数:   
  hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。   
  Msg:指定被发送的消息。   
  wParam:指定附加的消息指定信息。   
  IParam:指定附加的消息指定信息。   
  返回值:返回值指定消息处理的结果,依赖于所发送的消息。   
  备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消息。   
          如果指定的窗口是由调用线程创建的,则窗口程序立即作为子程序调用。如果指定的窗口是由不同线程创建的,则系统切换到该线程并调用恰当的窗口程序。线程间的消息只有在线程执行消息检索代码时才被处理。发送线程被阻塞直到接收线程处理完消息为止。   
          Windows   CE:Windows   CE不支持Windows桌面平台支持的所有消息。使用SendMesssge之前,要检查发送的消息是否被支持。

 

附:Delphi中SendMessage使用技巧

 

Windows系统是由消息机制驱动的,每个线程如果建立了一个窗口,则由系统分配一个消息队列用于窗口消息的处理。另外,消息也可以不经过消息队列而利用SendMessage函数直接发送给窗口,窗口过程将处理这个消息,但只有当消息被处理之后,SendMessage才能返回到调用程序。下面结合两个Delphi程序,讨论如何利用SendMessage向控件发送消息和控件对这种消息的响应。

用SendMessage向控件发送消息

在编程中,有时需要控件以特殊的风格显示,而这种要求又无法通过设置控件属性实现。例如,读取客户列表并显示在下拉框供用户选择,如果下拉框宽度太窄,则不能全部显示;如果将宽度定得太宽,界面又有不紧凑之感。因此希望能在运行期动态地确定下拉框显示区域的宽度,这种要求如果不用SendMessage函数就很难实现。

解决办法是,在读数据库时计算字符串的显示宽度,用显示宽度的最大值确定下拉框显示区域的宽度。再用SendMessage函数向下拉框发送CB_SETDROPPEDWIDTH消息和宽度值,下拉框根据消息中传来的信息,就可以进行正确显示。

  部分源程序代码如下:

  i:=0; //计数

  MaxWidth:=0;

  Query1.SQL.Clear;

  Query1.SQL.Add(‘select Company from Customer’);

  Query1.Open;

//读客户列表到下拉框

  while not Query1.Eof do begin

  ComboBox1.Items.add(Query1.FieldByName

(‘Company’).AsString);

   Width:=ComboBox1.Font.Size * Length

(ComboBox1.Items[i]);

   if Width>MaxWidth then

   MaxWidth:=Width; //找出最大值

   Query1.Next;

   i:=i+1;

  end;

  Query1.Close;

  ComboBox1.Text:=ComboBox1.Items[0];

  //发送消息以确定显示区域的宽度

  SendMessage(ComboBox1.Handle,

CB_SETDROPPEDWIDTH,MaxWidth,0);

利用SendMessage函数还可以实现一些有趣的效果,例如在按钮的Click事件中加入如下语句:

SendMessage(Button.Handle,BM_SETSTYLE,

BS_RADIOBUTTON,1);

运行后点击按钮,就可以把按钮变成一个收音机按钮。

控件接收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;

//指定处理MouseMove事件的方法

List.OnMouseMove := ListBoxMouseMove; end;

   
 
SendMessage参数

TTreeView:
(引用CommCtrl)
SendMessage(TreeView.Handle,TVM_SETBKCOLOR,0,RGB(255,0,0)); 设置TV背景颜色

SendMessage(Button.Handle,WM_LBUTTONDOWN,0,0);  鼠标左键按下
SendMessage(Button.Handle,WM_LBUTTONUP,0,0);   鼠标左键抬起
SendMessage(Edit.Handle,WM_SETTEXT,255,Integer(PChar(‘abc’))); 传递文本
SendMessage(Edit.Handle,WM_Char,Wparam(‘Q’),2);  传递字符
SendMessage(Button.Handle,BM_SETSTYLE,BS_RADIOBUTTON,1);  改变Button风格
SendMessage(ComboBox.Handle,CB_SETDROPPEDWIDTH,300,0);  改变CBDownWidth
WM_CUT、WM_COPY和WM_PASTE  剪切,复制,粘帖

实现任意组合键
keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), 0, 0);
keybd_event(ord(‘V’), MapVirtualKey(ord(‘V’), 0), 0, 0);
keybd_event(ord(‘V’), MapVirtualKey(ord(‘V’), 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);

 
http://www.cnblogs.com/dashan9zj/archive/2008/12/22/1359982.html

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30147.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信