windows api(應用程序接口)是windows系列軟件為程序開發(fā)人員提供的火力強大的“武器庫”,在這個武器庫中,有很多極具威力的武器,sendmessage就是其中之一,它的功能非常豐富,靈活使用這個函數(shù),會給編程工作帶來很多便利。本文以visual basic為例,結合幾個具體的例子介紹該函數(shù)的功能。 一、sendmeaasge函數(shù)簡介 顧名思義,sendmessage函數(shù)的功能是“發(fā)送消息”,即將一條消息發(fā)送到指定對象(操作系統(tǒng)、窗口或控件等)上,以產(chǎn)生特定的動作(如滾屏、修改對象外觀等)。 sendmessage函數(shù)在vb中的函數(shù)說明如下: declare function sendmessage lib "user32" alias "sendmessagea" (byval hwnd as long, byval wmsg as long,byval wparam as long,lparam as any) as long 其中四個自變量的含義和說明如下: hwnd:對象的句柄。希望將消息傳送給哪個對象,就把該對象的句柄作為實參傳送,在vb中可以簡單地用“對象.hwnd”獲得某個對象的句柄,如text1.hwnd和form1.hwnd分別可以得到text1和form1的句柄。 wmsg:被發(fā)送的消息。根據(jù)具體需求和不同的對象,將不同的消息作為實參傳送,以產(chǎn)生預期的動作。 wparam、lparam:附加的消息信息。這兩個是可選的參數(shù),用來提供關于wmsg消息更多的信息,不同的wmsg可能使用這兩個參數(shù)中的0、1或2個,如果不需要哪個附加參數(shù),則將實參賦為null(在vb中賦為0)。 在簡單了解了sendmessage函數(shù)的格式和功能后,讓我們以幾個例子來看看它的威力。 二、sendmessage函數(shù)使用實例 例1 多行textbox中的快速處理功能在處理多行textbox時我們經(jīng)常會碰到以下幾種情況: 希望了解多行textbox中目前共有多少行文字。 想快速返回第n行的文字。 對于上面的情況,如果用vb自身的語句或函數(shù)來實現(xiàn)的話,要寫不短的代碼,而且由于要采用順序查找的辦法來完成,因此代碼的執(zhí)行效率也很低。如果使用sendmessage函數(shù)則可以大大減少代碼量,并大幅度的提高執(zhí)行效率。 用sendmessage函數(shù)完成上面兩個任務的方法非常簡單,每個任務只需簡單地發(fā)送一條消息給多行textbox即可,兩個消息分別為:em_getlinecount、em_getline,其它參數(shù)和返回值見附表。 下面用一個簡單的實例演示這兩個功能: 新建工程,在form1上添加三個textbox(名稱分別為text1、txtlinecount、txtstring,將text1的multi line屬性置為true)、三個標簽和一個命令按鈕。為工程添加一個模塊moudle1,在其中寫如下聲明(其中 sendmessage函數(shù)的聲明可以從vb的“api瀏覽器”中復制): 消息常量名 | 消息值 | wparam | lparam | 返回值 | em_getlinecount | &hba | 未用 | 未用 | 行數(shù) | em_getline | &hc4 | 要找的行號 | 存結果的字節(jié)串 | 結果字節(jié)串的字節(jié)數(shù) | declare function sendmessage lib "user32" alias "sendmessagea" (byval hwnd as long, byval wmsg as long, byval wparam as long,lparam as any) as long public const em_getlinecount=&hba public const em_getline=&hc4 在form1的代碼模塊中寫如下代碼: private sub command1_click() dim str(256) as byte str(1)=1 ´最大允許存放256個字符 ´獲取總行數(shù),結果顯示在文本框txtlinecount中 txtlinecount=sendmessage(text1.hwnd,em_getlinecount,0,0) ´獲取第3行的數(shù)據(jù)放在str中,轉(zhuǎn)換為字符串后顯示在文本框txtstring中 sendmessage text1.hwnd,em_getline,2,str(0) txtstring= strconv(str,vbunicode) end sub 之后,按f5運行程序,在多行文本框中隨便鍵入幾行文字,然后按下[確定]按鈕,出現(xiàn)如圖畫面,說明程序正確統(tǒng)計出了總行數(shù)和第3行的文字。
兩點補充說明:在調(diào)用sendmessage獲取第n行字符串時,lparam需要說明為字節(jié)數(shù)組,在調(diào)用完成后,再將字節(jié)數(shù)組轉(zhuǎn)換為字符串;另外,調(diào)用前必須在lparam的前兩個字節(jié)指明允許存放的最大長度,其中第一個字節(jié)為低位,第二個字節(jié)為高位,本例將高位(即str(1))置1.說明最大允許存放256個字符。 例2 程序控制拉下或收起組合框的下拉列來 一般情況下,為了拉下或收起組合框的下拉列表,需要用鍵盤或鼠標進行操作,而有時我們希望程序運行的某個時刻自動拉出下拉列表(比如在一些演示程序中),為了實現(xiàn)這個目的,我們也只有借助于sendmessage函數(shù),方法是發(fā)一個cb_showdropdown(&h14f)消息給組合框。 在發(fā)cb_showdropdown消息時,wparam參數(shù)決定了是拉下列表(=true時)還是收起列表(=false時),lparam無用(設為0)。 為說明具體的使用方法,下面提供簡單的程序片段。首先在代碼模塊中做如下聲明: declare function sendmessage lib "user32" alias "sendmessagea" (byval hwnd as long,byval wmsg as long,byval wparam as long,lparam as any) as long const cb_showdropdown=&h14f 當程序中某處需要拉下組合框combol的列表時,寫如下調(diào)用語句: sendmessage combol.hwnd,cb_showdropdown,true,0 當需要收起組合框combol的列表時,寫如下語句: sendmessage combol.hwnd,cb_showdropdownn,false,0 例3 在列表框中查找匹配的項目 在win95風格的幫助系統(tǒng)中一般都有一個“索引”頁,索引頁含有一個文本框和一個列表框,當用戶在文本框中輸入文字時,下拉列表會動態(tài)地顯示與文本框中文字最匹配的項目,為用戶提供了最大的方便。這種效果在應用程序的幫助系統(tǒng)中很容易實現(xiàn)(只要按照win95幫助系統(tǒng)的正常制作過程制作就可以實現(xiàn)),如果想在應用程序的其它地方實現(xiàn)這種特性就需費一番心思了。 而使用sendmessage函數(shù)實現(xiàn)上述特性則非常簡單,甚至只需一條語句就足夠了,那就是在文本框的change事件中給列表框發(fā)一條lb_findstring(&h18f)消息,該消息告訴列表框在列表中查找匹配的項目。 在發(fā)lb_findstring消息時,wparam參數(shù)代表從列表框的哪一個項目后面開始查找,一般情況下該參數(shù)可定為-1,表示從list1(0)即第一項開始向后循環(huán)查找,lparam則傳進欲搜索的字符串(必須采用值傳遞)。 具體的代碼和運行畫面與后面的例4合并在一起演示。 例4 為listbox添加水平滾動條 在vb中,列表框控件僅提供垂直滾動條,沒有設置水平滾動條的能力,當某些項目的文本寬度較長時,超出列表框?qū)挾炔糠值奈谋揪蜔o法顯示出來,因此,很有必要為listbox添加一個水平滾動條來方便操作。 為添加水平滾動條,只需發(fā)一條lb_sethorizontalextent(&h194)消息給列表框即可。發(fā)送消息時,wparam為滾動條的長度(以像素為單位,可通過計算得出準確的長度,也可隨便給一個大于最大文本寬度的數(shù)字,如本例的250),lparam無用。下面是例3和例4合并在一起的代碼和運行畫面
declare function sendmessage lib "user32" alias "sendmessagea"(byval hwnd as long,byval wmsg as long,byval wparam as long,lparam as any) as long public const lb_findstring=&h18f public const lb_sethorizontalextent=&h194 private sub form_load() list1.additem "軟件" list1.additem "電腦游戲" list1.additem "電視機" list1.additem "電視臺" list1.additem "電腦" list1.additem "電腦游戲軟件" ´下一句為列表框添加水平滾動條 sendmessage list1.hwnd,lb_sethorizontalextent,250,0 end sub private sub text1_change() ´注意!當lparam傳入的是字符串時,必須用byval傳遞 list1.listindex = sendmessage(list1.hwnd,lb_findstring,-1,byval text1.text) end sub 通過上面幾個例子,想必您已經(jīng)對sendmessage函數(shù)的強大功能有了初步的了解。事實上利用該函數(shù)我們還可以完成更多更好的任務,如控制文本框的自動滾屏、實現(xiàn)文字編輯過程中的undo功能、操縱應用程序的窗體控制菜單等等,感興趣的讀者請參閱有關windows api的資料。 本文程序均用visual basic 5.0企業(yè)版編寫,在pwin95環(huán)境下運行正常 |