程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB綜合教程 >> 功能強大的SendMessage函數

功能強大的SendMessage函數

編輯:VB綜合教程
WindowsAPI(應用程序接口)是Windows系列軟件為程序開發人員提供的火力強大的“武器庫”,在這個武器庫中,有很多極具威力的武器,SendMessage就是其中之一,它的功能非常豐富,靈活使用這個函數,會給編程工作帶來很多便利。本文以VisualBasic為例,結合幾個具體的例子介紹該函數的功能。
  一、SendMeaasge函數簡介
  顧名思義,SendMessage函數的功能是“發送消息”,即將一條消息發送到指定對象(操作系統、窗口或控件等)上,以產生特定的動作(如滾屏、修改對象外觀等)。
  SendMessage函數在VB中的函數說明如下:
  DeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByvalhwndAsLong,ByvalwMsgAsLong,ByvalwParamAsLong,lParamAsAny)AsLong
  其中四個自變量的含義和說明如下:
  hWnd:對象的句柄。希望將消息傳送給哪個對象,就把該對象的句柄作為實參傳送,在VB中可以簡單地用“對象.hWnd”獲得某個對象的句柄,如Text1.hWnd和Form1.hWnd分別可以得到Text1和Form1的句柄。
  wMsg:被發送的消息。根據具體需求和不同的對象,將不同的消息作為實參傳送,以產生預期的動作。
  wParam、lParam:附加的消息信息。這兩個是可選的參數,用來提供關於wMsg消息更多的信息,不同的wMsg可能使用這兩個參數中的0、1或2個,如果不需要哪個附加參數,則將實參賦為NULL(在VB中賦為0)。
  在簡單了解了SendMessage函數的格式和功能後,讓我們以幾個例子來看看它的威力。
  二、SendMessage函數使用實例
  例1多行TextBox中的快速處理功能在處理多行TextBox時我們經常會碰到以下幾種情況:
  希望了解多行TextBox中目前共有多少行文字。
  想快速返回第N行的文字。
  對於上面的情況,如果用VB自身的語句或函數來實現的話,要寫不短的代碼,而且由於要采用順序查找的辦法來完成,因此代碼的執行效率也很低。如果使用SendMessage函數則可以大大減少代碼量,並大幅度的提高執行效率。
  用SendMessage函數完成上面兩個任務的方法非常簡單,每個任務只需簡單地發送一條消息給多行TextBox即可,兩個消息分別為:EM_GETLINECOUNT、EM_GETLINE,其它參數和返回值見附表。
  下面用一個簡單的實例演示這兩個功能:
  新建工程,在Form1上添加三個TextBox(名稱分別為Text1、txtLineCount、TxtString,將Text1的Multi
  Line屬性置為True)、三個標簽和一個命令按鈕。為工程添加一個模塊Moudle1,在其中寫如下聲明(其中
  SendMessage函數的聲明可以從VB的“API浏覽器”中復制):-align="middle"width="20">消息常量名->-align="middle"width="20">消息值->-align="middle"width="20">wParam->-align="middle"width="20">lParam->-align="middle"width="20">返回值->-align="middle"width="20">EM_GETLINECOUNT->-align="middle"width="20">&HBA->-align="middle"width="20">未用->-align="middle"width="20">未用->-align="middle"width="20">行數->-align="middle"width="20">EM_GETLINE->-align="middle"width="20">&HC4->-align="middle"width="20">要找的行號->-align="middle"width="20">存結果的字節串->-align="middle"width="20">結果字節串的字節數->

DeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,lParamAsAny)AsLong
  PublicConstEM_GETLINECOUNT=&HBA
  PublicConstEM_GETLINE=&HC4
  在Form1的代碼模塊中寫如下代碼:
  PrivateSubCommand1_Click()
  Dimstr(256)AsByte
  str(1)=1'最大允許存放256個字符
  '獲取總行數,結果顯示在文本框txtLineCount中
  txtlineCount=SendMessage(Text1.hwnd,EM_GETLINECOUNT,0,0)
  '獲取第3行的數據放在str中,轉換為字符串後顯示在文本框txtString中
  SendMessageText1.hwnd,EM_GETLINE,2,str(0)
  txtString=StrConv(str,vbUnicode)
  EndSub
  之後,按F5運行程序,在多行文本框中隨便鍵入幾行文字,然後按下[確定]按鈕,出現如圖畫面,說明程序正確統計出了總行數和第3行的文字。
  兩點補充說明:在調用SendMessage獲取第N行字符串時,lParam需要說明為字節數組,在調用完成後,再將字節數組轉換為字符串;另外,調用前必須在lParam的前兩個字節指明允許存放的最大長度,其中第一個字節為低位,第二個字節為高位,本例將高位(即str(1))置1.說明最大允許存放256個字符。
  例2程序控制拉下或收起組合框的下拉列來
  一般情況下,為了拉下或收起組合框的下拉列表,需要用鍵盤或鼠標進行操作,而有時我們希望程序運行的某個時刻自動拉出下拉列表(比如在一些演示程序中),為了實現這個目的,我們也只有借助於SendMessage函數,方法是發一個CB_SHOWDROPDOWN(&H14F)消息給組合框。
  在發CB_SHOWDROPDOWN消息時,wParam參數決定了是拉下列表(=True時)還是收起列表(=False時),lParam無用(設為0)。
  為說明具體的使用方法,下面提供簡單的程序片段。首先在代碼模塊中做如下聲明:
  DeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,lParamAsAny)AsLong
  ConstCB_SHOWDROPDOWN=&H14F
  當程序中某處需要拉下組合框Combol的列表時,寫如下調用語句:
  SendMessageCombol.hwnd,CB_SHOWDROPDOWN,True,0
  當需要收起組合框Combol的列表時,寫如下語句:
  SendMessageCombol.hwnd,CB_SHOWDROPDOWNN,False,0
  例3在列表框中查找匹配的項目
  在Win95風格的幫助系統中一般都有一個“索引”頁,索引頁含有一個文本框和一個列表框,當用戶在文本框中輸入文字時,下拉列表會動態地顯示與文本框中文字最匹配的項目,為用戶提供了最大的方便。這種效果在應用程序的幫助系統中很容易實現(只要按照Win95幫助系統的正常制作過程制作就可以實現),如果想在應用程序的其它地方實現這種特性就需費一番心思了。
  而使用SendMessage函數實現上述特性則非常簡單,甚至只需一條語句就足夠了,那就是在文本框的Change事件中給列表框發一條LB_FINDSTRING(&H18F)消息,該消息告訴列表框在列表中查找匹配的項目。
  在發LB_FINDSTRING消息時,wParam參數代表從列表框的哪一個項目後面開始查找,一般情況下該參數可定為-1,表示從List1(0)即第一項開始向後循環查找,lParam則傳進欲搜索的字符串(必須采用值傳遞)。
  具體的代碼和運行畫面與後面的例4合並在一起演示。
  例4為ListBox添加水平滾動條
  在VB中,列表框控件僅提供垂直滾動條,沒有設置水平滾動條的能力,當某些項目的文本寬度較長時,超出列表框寬度部分的文本就無法顯示出來,因此,很有必要為ListBox添加一個水平滾動條來方便操作。
  為添加水平滾動條,只需發一條LB_SETHORIZONTALEXTENT(&H194)消息給列表框即可。發送消息時,wParam為滾動條的長度(以像素為單位,可通過計算得出准確的長度,也可隨便給一個大於最大文本寬度的數字,如本例的250),lParam無用。下面是例3和例4合並在一起的代碼和運行畫面
  DeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,lParamAsAny)AsLong
  PublicConstLB_FINDSTRING=&H18F
  PublicConstLB_SETHORIZONTALEXTENT=&H194
  PrivateSubForm_Load()
  List1.AddItem"軟件"
  List1.AddItem"電腦游戲"
  List1.AddItem"電視機"
  List1.AddItem"電視台"
  List1.AddItem"電腦"
  List1.AddItem"電腦游戲軟件"
  '下一句為列表框添加水平滾動條
  SendMessageList1.hwnd,LB_SETHORIZONTALEXTENT,250,0
  EndSub
  PrivateSubText1_Change()
  '注意!當lParam傳入的是字符串時,必須用ByVal傳遞
  List1.ListIndex=SendMessage(List1.hwnd,LB_FINDSTRING,-1,ByValText1.Text)
  EndSub
  通過上面幾個例子,想必您已經對SendMessage函數的強大功能有了初步的了解。事實上利用該函數我們還可以完成更多更好的任務,如控制文本框的自動滾屏、實現文字編輯過程中的Undo功能、操縱應用程序的窗體控制菜單等等,感興趣的讀者請參閱有關WindowsAPI的資料。
  本文程序均用VisualBasic5.0企業版編寫,在Pwin95環境下運行正常。

->

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved