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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM