溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SendMessage有哪些參數(shù)

發(fā)布時間:2021-03-04 14:11:55 來源:億速云 閱讀:690 作者:小新 欄目:編程語言

這篇文章主要介紹了SendMessage有哪些參數(shù),具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

SendMessage函數(shù)的常用消息及其應(yīng)用(有點長,希望能對大家有所幫助)
函數(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

  其中四個參數(shù)的含義和說明如下:

1.hWnd:
  對象的句柄。希望將消息傳送給哪個對象,就把該對象的句柄作為實參傳送,在 VB 中可以簡單地
用“對象.hWnd”獲得某個對象的句柄,如 Text1.hWnd和 Form1.hWnd分別可以得到 Text1和Form1的句
柄。它是一個長整型數(shù)。Windows給每個控件一個編號,這個編號就稱為窗口句柄。有了這個句柄,我們
就可告訴 Windows 我們要控制哪個控件,所以這個句柄在 API 調(diào)用中至關(guān)重要。VB 的大多數(shù)控件都包
括hwnd屬性,如下拉框、TreeView等,窗體也有這個屬性。但也有一些控件沒有這個屬性,如標(biāo)簽控件。
沒有這個屬性就無法利用Windows API函數(shù),但可以節(jié)省系統(tǒng)資源。

2.wMsg:
  被發(fā)送的消息。根據(jù)具體需求和不同的對象,將不同的消息作為實參傳送,以產(chǎn)生預(yù)期的動作。使
SendMessage 傳遞消息,大多是為了完成以下幾個工作: 
 ?、僭O(shè)置控件的一些選項,象我們要使用的CB_SETDROPPEDWIDTH的就屬于這種情況。盡管VB的每個控
件都提供了許多屬性,但仍然有許多控件的選項沒有包括在其中。而這些選項中的大多數(shù)都可以利用該
函數(shù)進(jìn)行設(shè)置。
 ?、讷@得控件的一些設(shè)置。同上一種情況相反,有時我們需要獲得控件的一些設(shè)置,相當(dāng)于讀取屬性。
例如,如果想知道一個下拉框的下拉部分的寬度是多少,就可以向控件發(fā)送CB_GETDROPPEDWIDTH消息。
對于這種情況,SendMessage函數(shù)的返回值就是結(jié)果。 
  ③執(zhí)行一定的操作。例如,我們要在下拉框中尋找是否有“ABC”這個字符串,當(dāng)然,我們可以編寫
一個循環(huán),逐條比較看是否存在這樣的字符串。如果使用API,我們只需要向下拉框發(fā)送CB_FINDSTRING
消息,這條消息就會自動進(jìn)行查找工作并返回結(jié)果。 
 ?、苣M用戶操作。我們有時希望模擬用戶的操作,比如關(guān)閉其他應(yīng)用程序的窗口。其實只要我們能知
道那個窗口的句柄,我們就可以發(fā)送WM_CLOSE消息給那個窗口,窗口接受到這條消息就會關(guān)閉,如同用戶
關(guān)閉窗口一樣。 

3.wParam、4.lParam:
  附加的消息信息。這兩個是可選的參數(shù),用來提供關(guān)于wMsg消息更多的信息,不同的wMsg可能使用這
兩個參數(shù)中的0、1或2個,如果不需要哪個附加參數(shù),則將實參賦為NULL(在VB中賦為0)。
  lParam定義為Any類型。指定 Any類型可禁止VB進(jìn)行類型檢查,從而允許將任意數(shù)據(jù)類型傳遞給該過
程。由于每條消息對參數(shù)的類型和傳遞方式的要求都不同:有的可能要求為Long型,有的可能要求為自定
義類型;大多數(shù)要求按傳值方式傳遞,但也有一些要求按傳地址方式。為了滿足各種要求,我們將這個參
數(shù)定義為Any類型。比如,我們要傳遞一個Long型變量lData。如果消息要求傳地址方式傳遞,可以使用: 
  SendMessage ……, lData 
  而如果要求傳值方式傳遞,則使用 
  SendMessage ……, ByVal lData 
  如果傳遞常數(shù),我們則需要使用類型后綴來指定常數(shù)的類型,比如"0&",表示Long型的常數(shù)0,如 
  SendMessage ……, ByVal 0& 
  我們也可以使用類型轉(zhuǎn)換函數(shù)CLng將常數(shù)指定為Long型,如CLng(0)。

  程序中,有時定義 lParam As Any,有時定義 ByVal lParam As String。這是為什么呢?對于
SendMessage函數(shù),lParam的使用是很靈活的,在一般情況下,lParam是一個指針,它指向的數(shù)據(jù)類型
有三種:長整形、自定義數(shù)據(jù)結(jié)構(gòu)類型、字符串類型。對于前兩種類型,需要將 lParam定義為 lParam
As Any,從而將 lParam 數(shù)據(jù)的指針傳遞到 SendMessage 函數(shù)。對于字符串類型,則需要定義 Byval
lParam As String,因為字符串類型數(shù)據(jù)不同,只有定義 ByVal,得到的才是字符串的指針,如果沒有
ByVal,得到的將是指向字符串指針的指針。另外對于少數(shù)的消息來說,SendMessage 函數(shù)需要的只是
lParam 本身的值,這時就需要將 lParam定義為 Byval lParam As Long,或者在程序調(diào)用時在 lParam
之前加 ByVal。

  當(dāng)用戶在編輯控件上進(jìn)行各種操作時,其父窗口將收到 WM_COMMAND 通知消息,lParam帶控件句柄
(hWnd),同時 wParam 的低16位帶控件的 ID,高16位帶有如下表的消息代碼:

常用編輯控件消息:
EC_LEFTMARGIN(&H1)                    EC_USEFONTINF 設(shè)置左邊距時使用
EC_RIGHTMARGIN                        EC_USEFONTINF 設(shè)置右邊距時使用
EC_USEFONTINF,O,邊距                  設(shè)置編輯控件的左、右邊距,當(dāng)wParam含EC_LEFTMARGIN時在lParam的低16位指定左邊距點數(shù),當(dāng)wParam含EC_RIGHTMARGIN時在lParam的高16位指定右邊距點數(shù)。當(dāng)指定wParam為EC_USEFONTINFO時,則用當(dāng)前字體的字符"A"的寬度指定右邊距和字符"C"的寬度指定左邊距l(xiāng)Param被忽略。

EM_CHARFROMPOS(&HD7=215),0,           取得編輯控件中指定位置的字符相對于文本頭部的偏移量。使用本操作應(yīng)先在第4個參數(shù)的高16位指定行號,低16位指定列號(或一個POINTAPI結(jié)構(gòu)),行列是按編輯控件的客戶區(qū)左上角為原點(0,0)計算的。如果指定的位置超出控件客戶區(qū)則返回-1
EM_CANUNDO(&HC6=198),0,0             決定前一次編輯操作是否能夠撤消:檢測控件撤消緩沖區(qū)是否為空,通??丶炎詈笠淮卧诳丶木庉嫴僮鞅4嬖谝粋€撤消緩沖區(qū),如果緩沖區(qū)非空則返回TRUE表示上次操作可以撤消,否則返回FALSE,應(yīng)用程序可以利用該返回值來禁止或允許菜單或工具條的"撤消"項。
EM_EMPTYUNDOBUFFER(&HCD=205 ),0,0     清除控件的撤消緩沖區(qū),使其不能撤消前一次編輯操作 
EM_FMTLINES(&HC8=200)                決定是否在取回的文本宇串中包含軟回車字符
EM_GETFIRSTVISIBLEINE(&HCE=206),0,0   獲得文本控件中處于可見位置的最頂部的文本所在的行號

EM_GETLINE(&HC4=196 ),行號,ByVal 變量 獲取編輯控件某一行的內(nèi)容,變量須預(yù)先賦空格
EM_GETLINECOUNT(&HBA=186,0,0          獲取編輯控件的總行數(shù)
EM_GETMODIFY(&HB8=184),0,0           判斷編輯控件的內(nèi)容是否已發(fā)生變化,返回TRUE則控件文本已被修改,返回FALSE則未變。 
EM_GETPASSWORDCHAR( ),0,0            獲取編輯控件的密碼字符,返回NULL表示沒有字符
EM_GETRECT(&HB2=178),0,結(jié)構(gòu)          獲取編輯控件的格式化矩形
EM_GETTHUMB(&HBE=190),0,0             取得多行文本編輯控件的滾動框的當(dāng)前位置(注意:是象素值)
EM_GETSEL(&HB0=176),0,變量            獲取光標(biāo)位置(以字節(jié)數(shù)表示),或:(緩沖區(qū)起點,緩沖區(qū)終點)取得編輯控件中選定內(nèi)容的范圍,返回值中低16位為起點,高16位為終點
EM_GETHANDLE(&HBD=189),0,0            取得文本緩沖區(qū)
EM_GETWORDBREAKPROC(&HD1=209),0,0     取得整字換行回調(diào)函數(shù)EditWordBreakProc指針
EM_GETLIMITTEXT(WM_USER+37=1061),0,0  獲取一個編輯控件中文本的最大長度 
EM_GETMARGINS( ),0,0                  獲取編輯控件的左、右邊距,返回值低16位為左邊距,高16位為右邊距(不得用于NT3.51) 
EM_LIMITTEXT(&HC5=197),最大值,0       設(shè)置編輯控件中的文本長度
EM_SCROLLCARET(&HB7=183),0,0          把可見范圍移至光標(biāo)處
EM_LINEFROMCHAR(&HC9=201),偏移值,0    獲取指定位置(或:-1,0 表示光標(biāo)位置)所在的行號
EM_LINEINDEX(&HBB=187),行號,0         獲取指定行(或:-1,0 表示光標(biāo)所在行)首字符在文本中的位置(以字節(jié)數(shù)表示)
EM_LINELENGTH(&hC1=193),偏移值,0      獲取指定位置所在行(或:-1,0 表示光標(biāo)所在行)的文本長度(以字節(jié)數(shù)表示)
EM_POSFROMCHARPOINT,結(jié)構(gòu)地址,偏移值   取得指定字符位置的行列號,偏移值是字符相對于文本頭部的偏移。
EM_LINESCROLL(&HB6=182),列數(shù),行數(shù)     指定行數(shù)的文本水平滾動,每次滾動N列
EM_EXGETSEL(&H434=1076)   

EM_EXSETSEL(&H437=1079),0,結(jié)構(gòu)        RichEdit控件設(shè)置文本選定范圍,參閱 EM_SETSEL 消息,結(jié)構(gòu)是指 CHARRANGE 結(jié)構(gòu)
EM_PASTESPECIAL(&H440=1088),2(1),1    RichEdit控件粘貼剪貼板中的位圖(或文本)
EM_FINDTEXT(&H738=1080)               RichEdit控件正文搜索操作
EM_FINDTEXTEX(&H44F=1103)             同上
EM_SETTEXTEX(&H461=1121)              RichEdit控件正文替換/插入操作
EM_SETTARGETDEVICE, GetDC(RichText.hWnd), RichText.Width / 15)設(shè)置 RichTextBox 自動換行,后續(xù)代碼是:RichText.RightMargin = iif(RichText.RightMargin = 0,1,0)
EM_SETTARGETDEVICE, 0, 1              設(shè)置 RichTextBox 不自動換行

EM_POSFROMCHAR(&HD6或&H426)           判斷指定字符在編輯控件的位置(用于NT3.51) 
EM_SCROLL(&HB5=181),*,0               文本垂直滾動。第三個參數(shù)*控制滾動方向:SB_LINEDOWN(1)向下滾動一行,SB_LINEUP(0)向上滾動一行,SB_PAGEDOWN(3)向下滾動一頁,SB_PAGEUP(2)向上滾動一頁。
EM_REPLACESEL(&HC2=194),1(0),字符串   用指定字符串替換編輯控件中的當(dāng)前選定內(nèi)容,如果第三個參數(shù)wParam為1,則本次操作允許撤消,0禁止撤消。字符串可用傳值方式,也可用傳址方式(例:SendMessage Text1.hwnd, EM_REPLACESEL, 0, Text2.Text '這是傳值方式)
EM_SETSEL(&HB1=177),起點,終點        設(shè)置編輯控件中文本選定內(nèi)容范圍(或設(shè)置光標(biāo)位置),該范圍被反相顯示,用于為復(fù)制、替換、粘貼、剪切、刪除等編輯功能指定范圍,光標(biāo)將被移至指定的終點后面。還可使用指定相同起點和終點來移動光標(biāo)而不是選定范圍。當(dāng)指定的起點等于0和終點等于-1時,文本全部被選中,此法常用在清空編輯控件。當(dāng)指定的起點等于-2和終點等于-1時,全文均不選,光標(biāo)移至文本未端,此法常用在文本未端追加內(nèi)容。注意:當(dāng)控件沒有輸入焦點時,本操作將會失敗,一般在執(zhí)行本操作前都應(yīng)調(diào)用SetFocus先取得輸入焦點。
EM_UNDO(&HC7=199),0,0                 撤消前一次編輯操作,當(dāng)重復(fù)發(fā)送本消息,控件將在撤消和恢復(fù)中來回切換
EM_SETCHARFORMAT(&H444)               改變選定文本的顏色
EM_SETHANDLE(&HBC=188),緩沖區(qū)指針,0  為編輯控件指定新的文本緩沖區(qū)。此操作僅適用對話框創(chuàng)建帶DS_LOCALEDIT風(fēng)格的控件。
EM_SETLIMITTEXT,長度(字節(jié)),0          設(shè)置編輯控件中的文本最大長度(不得用于NT3.51)
EM_SETMARGINS(&HD3=211)               設(shè)置編輯控件的左、右邊距(不得用于NT3.51)
EM_SETMODIFY(&HB9=185),1(0),0         設(shè)置或清除一個編輯控件的修改標(biāo)志
EM_SETPASSWORDCHAR(&HCC=204),字符,0   指定控件用來顯示密碼的字符,缺省為"*"。當(dāng)?shù)谌齻€參數(shù)wParam為0時,本操作將清除控件的ES_PASSWORD風(fēng)格,并按實際字符顯示。
EM_SETREADONLY(&HCF=207),1(0),0       決定是否將編輯控件設(shè)為只讀,同時決定控件的ES_READONLY風(fēng)格
EM_SETRECT(&HB3=179),0(或RECT),結(jié)構(gòu)地址      為一個編輯控件設(shè)置格式化矩形
EM_SETRECTNP(&HB4=180),0(或RECT),結(jié)構(gòu)地址    為一個編輯控件設(shè)置格式化矩形,只是控件此時不會重畫

EN_CHANGE(&H300=768)                  編輯控件的內(nèi)容發(fā)生改變。與EN_UPDATE不同,該消息是在編輯框顯示的正文被刷新后才發(fā)出的。 
EN_ERRSPACE(&H500=1280)               任何時候只要由于內(nèi)存不足以完成一項編輯操作 
EN_HSCROLL(&H601=1537)                用戶單擊了編輯控件的水平滾動條。注意:這條消息是在控件更新顯示之前發(fā)送出去的。
EN_VSCROLL(&H602=1538)                用戶單擊了編輯控件的垂直滾動條。注意:這條消息是在控件更新顯示之前發(fā)送出去的。
EN_KILLFOCUS(&H200=512)               編輯控件失去了輸入焦點
EN_SETFOCUS(&H100=256)                編輯控件獲得了輸入焦點
EN_UPDATE(&H400=1024)                 控件準(zhǔn)備顯示改變了的正文時發(fā)送該消息。它與EN_CHANGE通知消息相似,只是它發(fā)生于更新文本顯示出來之前。 
EN_MAXTEXT(&H501=1281)                用戶輸人的文字?jǐn)?shù)超出由EM_LIMITTEXT消息規(guī)定的界限,或超出由VB Maxlength屬性規(guī)定的界限,就會發(fā)送這條消息 。此外,倘若不允許自動進(jìn)行水平滾動,同時插入點要超出控件的寬度;或者不允許自動垂直滾動,同時插入點要超出控件的高度,那么也會觸發(fā)這條消息。在沒有ES_AUTOHSCROLL或ES_AUTOVSCROLL的編輯框中,當(dāng)正文超出了編輯框的邊框時也會發(fā)出該消息。 

編輯風(fēng)格消息:
ES_MULTILINE                         指定編輯控件能否進(jìn)行多行文本編輯,若多行編輯器不指定ES_AUTOHSCROLL風(fēng)格,則會自動換行,用戶每按一次Enter,在當(dāng)前光標(biāo)處輸入一個回車換行符(0Dh,0Ah),文本增加一行。若不指定ES_AUTOVSCROLL,則多行編輯器會在窗口中正文裝滿時發(fā)出警告聲響。
ES_LEFT                               文本顯示居左。
ES_CENTER                            文本顯示居中。
ES_RIGHT                             文本顯示居右。
ES_LOWERCASE                         把用戶輸入的字母統(tǒng)統(tǒng)轉(zhuǎn)換成小寫字母。
ES_UPPERCASE                         把用戶輸入的字母統(tǒng)統(tǒng)轉(zhuǎn)換成大寫字母。
ES_OEMCONVERT                        把輸入的文本從ANSI碼轉(zhuǎn)換成OEM碼,然后又轉(zhuǎn)換成ANSI碼,目的是保證函數(shù)AnsiToOem的正確調(diào)用。這在編輯框中包含文件名時是很有用的。
ES_AUTOHSCROLL(自動增加水平滾動條?) 當(dāng)用戶在行尾鍵入一個字符時,正文將自動向右滾動10個字符,當(dāng)用戶按回車鍵時,正文總是滾向左邊。
ES_AUTOVSCROLL                       當(dāng)用戶在最后一個可見行按回車鍵時,正文向上滾動一頁。
ES_NUMBER                            只接收數(shù)碼輸入,其它字符輸入一律無效。
ES_NOHIDESEL(&H100=256)               當(dāng)編輯框失去輸入焦點時,選中的文本將隱藏,正文中的選擇保持不變。缺省時正文中的選擇將失效,當(dāng)獲得輸入焦點后才又顯示出來。
ES_READONLY                          將編輯框設(shè)置成只讀的。
ES_PASSWORD(&H20=32)                  使所有鍵入的字符都用"*"來顯示。
ES_WANTRETURN                        使多行編輯器接收回車鍵輸入并換行。如果不指定該風(fēng)格,按回車鍵會選擇缺省的命令按鈕,這往往會導(dǎo)致對話框的關(guān)閉。

列表框操作:
LB_FINDSTRING(&H18F=399),-1,ByVal 字串   查找列表項的字符串,返回值=字符串所在的列表項的索引。-1表示從第0行開始查找,如果改為一個有效的列表項索引值,將從該行開始查找。
LB_ITEMFROMPOINT(&H1A9=425)              獲取光標(biāo)所在的列表項的索引
LB_SETHORIZONTALEXTENT(&H194=404),長度,0 設(shè)置列表框的橫向滾動條以及滾動長度,長度為象素值

組合框操作:
CB_SHOWDROPDOWN(&H14F),1(0),0         打開(關(guān)閉)組合框的列表

TVM_SETBKCOLOR(&H1100+29=4381)        設(shè)置擴(kuò)展樹型列表控件的背景色(TVM開頭的常數(shù))

常用窗口消息:
WM_GETFONT(&H31=49)                   得到當(dāng)前控件繪制文本的字體(的句柄)
WM_GETTEXT(&HD=13),變量長度,變量       取得窗體的標(biāo)題,變量須預(yù)先賦空字串(chr(0)),變量長度=Len(變量)
WM_SETTEXT(&HC=12),0,ByVal "字串"     設(shè)置窗體的標(biāo)題
WM_NCLBUTTONDOWN(&HA1=161),2,0        在非客戶區(qū),即邊框及標(biāo)題欄上(假如定義的是一個組件,則非客戶區(qū)包括Form等)按下鼠標(biāo)左鍵;
WM_LBUTTONDOWN(&H201=513),2,0         在客戶區(qū),也就是除邊框及標(biāo)題欄以外按下鼠標(biāo)左鍵
WM_VSCROLL(&H115=277),&H10000*p+SB_THUMBPOSITION(&H4),0 同步滾動文本,p是位置改變量
WM_PAINT
WM_USER(&H400=1024)

WM_CUT(&H300=768),0,0                 剪切
WM_COPY(&H301=769)),0,0               復(fù)制
WM_PASTE(&H302=770)),0,0              粘貼
WM_CLEAR(&H303=771)),0,0              刪除
WM_UNDO(&H304=772)),0,0               撤消

按紐消息:
BM_SETSTYLE(&HF4)                   設(shè)置按紐樣式
BS_RADIOBUTTON(&H4)                 收音機(jī)旋紐式的按紐,是 BM_SETSTYLE 使用的參數(shù) 

SendMessage函數(shù)應(yīng)用(一)
    在Windows系統(tǒng)的很多消息中,有一些不僅僅是提供一個窗口消息那么簡單。它們可以控制窗口的
動作和屬性。下面向大家介紹SendMessage函數(shù)在擴(kuò)充列表(ListBox)控件功能方面的應(yīng)用。 
  在 Windows 中,有一系列的以 LB_ 開頭的列表消息,這里介紹的就是利用LB消息控制的ListBox
的應(yīng)用。

1、使列表中光標(biāo)移動到不同的列表項上有不同的提示(ToolTip)
  在列表框控件中有一個 ToolTipText 屬性,該屬性決定了當(dāng)光標(biāo)在列表框上移動時出現(xiàn)的提示文
字。但是如何使得當(dāng)光標(biāo)在不同的列表項上移動時的提示文字也不同呢?問題的關(guān)鍵是要知道在光標(biāo)移
動時光標(biāo)所在的列表項的索引,使用SendMessage函數(shù)發(fā)送 LB_ITEMFROMPOINT 消息就可以獲得。
  在 Form1 中加入一個 ListBox 控件,運行程序,當(dāng)光標(biāo)在列表中移動時,可以看到根據(jù)光標(biāo)所在
的不同的列表項,提示文字也不相同。代碼如下(我已試驗成功):

Const LB_ITEMFROMPOINT = &H1A9

Private Sub Form_Load()
Dim ZXS As Long
Drive1.Drive = "G:": Dir1.Path = "G:\一江秋水的文檔"
Combo1.Text = Combo1.List(0)
ZXS = SendMessage(Text1.hwnd, 186, 0, 0)
Label1.Caption = "共 " & ZXS & " 行," & Len(Text1.Text) & " 字"
For i = 1 To 200: List1.AddItem Str(i) + " 列表框試驗項目": Next
End Sub

Private Sub List1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lXPoint As Long, lYPoint As Long, lIndex As Long
If Button = 0 Then '確定在移動鼠標(biāo)的同時沒有按下功能鍵或者鼠標(biāo)鍵
  lXPoint = CLng(X / Screen.TwipsPerPixelX) '獲得光標(biāo)的位置,以像素為單位
  lYPoint = CLng(Y / Screen.TwipsPerPixelY)
  With List1
    lIndex = SendMessage(.hwnd, LB_ITEMFROMPOINT, 0, ByVal ((lYPoint * 65536) + lXPoint)) '獲得光標(biāo)所在的標(biāo)題行的索引
    If lIndex < .ListCount Then .ToolTipText = .List(lIndex) Else .ToolTipText = ""
  End With
End If
End Sub

2、向列表中加入橫向滾動條使得可以瀏覽長列表項
  當(dāng)向列表中加入的列表項超出了列表的顯示范圍后,列表并不會出現(xiàn)橫向滾動條讓你可以通過滾動來瀏覽
項目的全部內(nèi)容。利用 LB_SETHORIZONTALEXTENT 消息可以設(shè)置列表框的橫向滾動條以及滾動長度。
  在 Form1 中加入一個 ListBox 控件,運行程序,可以看到列表中出現(xiàn)了橫向滾動條,而且滾動范圍正好
是列表項的長度。代碼如下(我已試驗成功):

Option Explicit

Private Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type

Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, _
  ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
Private 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 LB_SETHORIZONTALEXTENT = &H194
Const DT_CALCRECT = &H400

Public Function ListTextWidth(ByRef lstThis As ListBox) As Long '獲取最長項目的象素長度值
Dim i As Long
Dim tR As RECT
Dim lW As Long
Dim lWidth As Long
Dim lHDC As Long
With lstThis.Parent.Font
  .Name = lstThis.Font.Name
  .Size = lstThis.Font.Size
  .Bold = lstThis.Font.Bold
  .Italic = lstThis.Font.Italic
End With
lHDC = lstThis.Parent.hdc
For i = 0 To lstThis.ListCount - 1 '遍歷所有的列表項以找到最長的項
  DrawText lHDC, lstThis.List(i), -1, tR, DT_CALCRECT
  lW = tR.Right - tR.Left + 8
  If lW > lWidth Then lWidth = lW
Next 
ListTextWidth = lWidth '返回最長列表項的長度(像素)
End Function

Private Sub Form_Load()
Dim astr As String
Dim i
Dim l As Long
For i = 1 To 10: astr = Str(i) + "這是真正的長項目" + astr: List1.AddItem astr: Next '加入一個很大的列表項
L = ListTextWidth(List1)
SendMessage List1.hwnd, LB_SETHORIZONTALEXTENT, L, 0
End Sub

3、使列表框可以響應(yīng)用戶擊鍵
  有時我們需要列表根據(jù)用戶的敲入字符串自動調(diào)整列表的ListIndex到最接近的列表項,就象VB中動態(tài)
響應(yīng)用戶輸入控件屬性的編輯器一樣。問題的關(guān)鍵是如何在列表中查找含有指定字符串的列表項,使用
LB_FINDSTRING消息可以在列表中查找指定字符串。
  在 Form1 中加入一個 TextBox 控件和一個 ListBox 控件,并將 List1的 Sorted 屬性設(shè)置為True。
運行程序,在文本框中敲入字符,例如"av" "gm",列表就會高亮顯示相近的列表項。代碼如下(已成功):

Const LB_FINDSTRING = &H18F
Dim st As String

Private Sub Form_Load()
For i = 65 To 90: For j = 65 To 90: List1.AddItem Chr(i) + Chr(j): Next: Next '向List中加入列表項
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
If Len(st) > 1 Then st = ""
If ((KeyAscii > 64 And KeyAscii < 91) Or (KeyAscii > 96 Or KeyAscii < 123)) Then
  Dim L As Long
  st = st + Chr(KeyAscii)
  L = SendMessage(List1.hwnd, LB_FINDSTRING, -1, ByVal st)'注意!當(dāng)參數(shù)4傳入的是字符串時,必須用ByVal傳遞
  If L Then List1.ListIndex = L
End If
End Sub

4.在列表框中查找匹配的項目
   在Win95風(fēng)格的幫助系統(tǒng)中一般都有一個“索引”頁,索引頁含有一個文本框和一個列表框,當(dāng)用戶
在文本框中輸入文字時,下拉列表會動態(tài)地顯示與文本框中文字最匹配的項目,為用戶提供了最大的方
便。這種效果在應(yīng)用程序的幫助系統(tǒng)中很容易實現(xiàn)(只要按照 Win95幫助系統(tǒng)的正常制作過程制作就可
以實現(xiàn)),如果想在應(yīng)用程序的其它地方實現(xiàn)這種特性就需費一番心思了。
   而使用SendMessage函數(shù)實現(xiàn)上述特性則非常簡單,甚至只需一條語句就足夠了,那就是在文本框的
Change事件中給列表框發(fā)一條LB_FINDSTRING(&H18F)消息,該消息告訴列表框在列表中查找匹配的項
目。
   在發(fā)LB_FINDSTRING消息時,wParam參數(shù)代表從列表框的哪一個項目后面開始查找,一般情況下該參
數(shù)可定為-1,表示從List1(0)即第一項開始向后循環(huán)查找,lParam則傳進(jìn)欲搜索的字符串(必須采用值
傳遞)。
   具體的代碼和運行畫面與下面的 5. 合并在一起演示。
5.為ListBox添加水平滾動條
   在VB中,列表框控件僅提供垂直滾動條,沒有設(shè)置水平滾動條的能力,當(dāng)某些項目的文本寬度較長
時,超出列表框?qū)挾炔糠值奈谋揪蜔o法顯示出來,因此,很有必要為ListBox添加一個水平滾動條來方
便操作。
   為添加水平滾動條,只需發(fā)一條 LB_SETHORIZONTALEXTENT(&H194) 消息給列表框即可。發(fā)送消息
時,wParam為滾動條的長度(以像素為單位,可通過計算得出準(zhǔn)確的長度,上面例2 就是如此的,也可
隨便給一個數(shù)字,如本例的 250),lParam無用。代碼如下(已試驗成功):

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 "電視機(jī)"
List1.AddItem "電視臺"
List1.AddItem "電腦"
List1.AddItem "電腦游戲軟件"
SendMessage List1.hwnd,&H194,250,0 '為列表框添加水平滾動條
End Sub

Private Sub Text1_Change()
'注意!當(dāng)lParam傳入的是字符串時,必須用ByVal傳遞
List1.ListIndex = SendMessage(List1.hwnd,LB_FINDSTRING,-1,ByVal Text1.Text)
End Sub

6.在API文本瀏覽器里,當(dāng)我們在搜索欄輸入任意字母,“可用項”里以該字母開頭的項目以高亮顯
示以引起我們注意該項是不是我們所需的。象這樣的功能一切提供搜索選項的程序都應(yīng)該具備。以下例
子采用SendMessage函數(shù)實現(xiàn)這一技術(shù)。

Const LB_FINDSTRING = &H18F 

Private Sub Form_Load()
Dim i As Integer
For i = Asc("A") To Asc("Z") '給列表框添加26個字母(大寫)
List1.AddItem Chr$(i)
Next
Text1 = "" '令文本框為空
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
Text1 = "" '按下任意鍵則令原內(nèi)容消失
Text1.SelLength = 1 '限制長度
Text1.SelText = Chr(KeyAscii) '顯示鍵盤符號
KeyAscii = 0 '禁止響應(yīng)
'ListBox中的項目文本若與文本框的一致則選中(高亮)
List1.ListIndex = SendMessage(List1.hwnd, LB_FINDSTRING, -1, ByVal CStr(Text1.Text))'經(jīng)試,不需CStr函數(shù) 
End Sub

  以上程序適用于單項目為多個字母的查詢,但必須注意,在TextBox的KeyPress事件中要作相應(yīng)的
改動

SendMessage函數(shù)應(yīng)用(二) 
  介紹如何利用消息函數(shù)來擴(kuò)展樹型列表 TreeView 控件的功能。相信對于樹型列表控件大家十分的
熟悉,典型的應(yīng)用就是 Windows 資源管理器中的目錄列表。而在VB中,樹型列表控件包含在Microsoft
Windows Common Control 6.0(也可能是5.0,視你的VB或者系統(tǒng)版本而定)中。在Windows API 中,
有一系列的以 TVM_ 開頭的消息值,這些消息就是擴(kuò)展樹型列表控件所特定的消息值,下面向大家介紹
其中的一些應(yīng)用

1、設(shè)置樹型列表控件的背景顏色
 首先做如下的定義:

Const TV_FIRST = &H1100
Const TVM_SETBKCOLOR = TV_FIRST + 29(4381)
  
  調(diào)用:
Call SendMessage(TreeView1.hwnd, 4381, 0,ByVal RGB(255, 0, 0))

  上面的SendMessage調(diào)用將TreeView1的背景顏色設(shè)置為紅色。
  大家可能注意到了。在上面的 Sendmessage 函數(shù)定義中,我們將 lParam 定義為 ByVal lParam
As Long,而不是象前面的那些范例那樣定義為 Any 或者 String 類型,關(guān)于這個問題,我會在最后的
一章中做介紹。

2、設(shè)置樹型列表控件標(biāo)題行高度
  TVM_SETITEMHEIGHT 消息設(shè)定控件的標(biāo)題行的高度,該消息的定義及調(diào)用方法如下:

Const TV_FIRST = &H1100
Const TVM_SETITEMHEIGHT = TV_FIRST + 27

Call SendMessage(TreeView1.hwnd, TVM_SETITEMHEIGHT, 60, 0) '將TreeView1標(biāo)題行高度設(shè)置到60像素高
3、為樹型列表控件中不同的標(biāo)題行設(shè)置不同的提示
  介紹如何為樹型列表控件中的每一個標(biāo)題設(shè)置不同的提示。同 ListBox控件不通,樹型列表控件中
并沒有根據(jù)光標(biāo)位置獲得標(biāo)題行索引的消息,我們需要另外想辦法。在TVM類消息中有一個TVM_HITTEST
消息,發(fā)送該消息可以檢測控件表面上的某一點,如果該點位于一個標(biāo)題上,則返回該標(biāo)題的句柄。而
利用 TVM_GETITEM消息,則可以根據(jù)標(biāo)題句柄返回該標(biāo)題行的文本。所以結(jié)合利用這兩個消息可以獲取
光標(biāo)所在標(biāo)題行的標(biāo)題文本。具體的范例代碼如下:

Option Explicit
Private Type TPoint
 x As Long
 y As Long
End Type

Private Type TVHITTESTINFO
 pt As TPoint
 flags As Long

 hItem As Long
End Type

Private Type TVITEM
 mask As Long
 HTreeItem As Long
 state As Long
 stateMask As Long
 pszText As Long
 cchTextMax As Long
 iImage As Long
 iSelectedImage As Long
 cChildren As Long
 lParam As Long
End Type

Const TV_FIRST = &H1100
Const TVM_HITTEST = TV_FIRST + 17
Const TVM_GETITEM = TV_FIRST + 12
Const TVHT_ONITEMLABEL = &H4
Const TVIF_TEXT = &H1
Const GMEM_FIXED = &H0

Private Declare Function SendMessageRef Lib "user32" Alias "SendMessageA" (ByVal hwnd As _
  Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As _
  String, ByVal Source As Long, ByVal Length As Long)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes _
  As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long

Dim hItemPrv As Long

Private Sub Form_Load()
Dim ndX As Node
   '加入若干Item
   Set ndX = TreeView1.Nodes.Add(, , "R", "Root")
   Set ndX = TreeView1.Nodes.Add("R", tvwChild, "Key1", "Node1")
   Set ndX = TreeView1.Nodes.Add("Key1", tvwChild, "SubKey1", "SubNode1")
   Set ndX = TreeView1.Nodes.Add("SubKey1", tvwChild, "SubKeys1", "SubNode1")
   Set ndX = TreeView1.Nodes.Add("Key1", tvwChild, "SubKey2", "SubNode2")
   Set ndX = TreeView1.Nodes.Add("Key1", tvwChild, "SubKey3", "SubNode3")
   Set ndX = TreeView1.Nodes.Add("Key1", tvwChild, "SubKey4", "SubNode4")
End Sub

Private Sub TreeView1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
   Dim ptA As TPoint
   Dim tf As TVHITTESTINFO
   Dim tv As TVITEM
   Dim hStr As Long
   Dim hItem As Long
   Dim astr As String * 1024
   Dim bstr
   On Error GoTo errLab

   '獲得當(dāng)前光標(biāo)所在的位置坐標(biāo)
   ptA.x = Int(x / Screen.TwipsPerPixelX)
   ptA.y = Int(y / Screen.TwipsPerPixelY)
   tf.pt = ptA
   tf.flags = TVHT_ONITEMLABEL

   '獲得光標(biāo)所在的Item的句柄
   hItem = SendMessageRef(TreeView1.hwnd, TVM_HITTEST, 0, tf)
   '如果未獲得句柄或者同上一次是同一個Item的句柄則退出
   If ((hItem <= 0) Or (hItem = hItemPrv)) Then Exit Sub

   hItemPrv = hItem
   '分配一定的內(nèi)存空間用以存儲Item的標(biāo)題
   hStr = GlobalAlloc(GMEM_FIXED, 1024)

   If hStr > 0 Then
    tv.mask = TVIF_TEXT '獲取標(biāo)題文本
    tv.HTreeItem = hItem 'Item句柄
    tv.pszText = hStr
    tv.cchTextMax = 1023
    '發(fā)送TVM_GETITEM獲得標(biāo)題文本
    Call SendMessageRef(TreeView1.hwnd, TVM_GETITEM, 0, tv)
    '將標(biāo)題文本拷貝到字符串a(chǎn)str中
    CopyMemory astr, hStr, 1024
    bstr = Left$(astr, (InStr(astr, Chr(0)) - 1))
    TreeView1.ToolTipText = bstr
    '釋放分配的內(nèi)存空間
    GlobalFree hStr
   End If
   Exit Sub
  errLab:
   Resume Next
  End Sub

  運行上面的程序,當(dāng)光標(biāo)在 TreeView1上面移動時,TreeView1的 ToolTips就會根據(jù)光標(biāo)所在的不
同標(biāo)題行而變動。

SendMessage函數(shù)應(yīng)用(三) 
  介紹關(guān)于RichTextBox(簡稱RTF)控件的消息和ListView控件的消息控制。

1.在Windows消息中,以EM_開頭的消息是專門控制TextBox類控件和RTF類控件的。下面介紹的是如何利
用 EM_ 消息實現(xiàn)向 RichTextBox 中粘貼文本和位圖。在 EM_消息中,有一個 EM_PASTESPECIAL 消息
可以從剪貼板中獲取文本或者位圖類數(shù)據(jù)并拷貝到 RTF 上。
  運行程序,點擊Command1,可以將剪貼板中的數(shù)據(jù)(位圖或者文本)拷貝到RichTextBox1上。
  在 EM_PASTESPECIAL 消息中,wParam 定義剪貼板數(shù)據(jù)類型,lParam 定義一個 repastespecial
類型的數(shù)據(jù),其中的 dwAspect 說明數(shù)據(jù)以何種方式顯示到 RTF 對象上,如果是 DVASPECT_CONTENT,
則將整個數(shù)據(jù)顯示在 RTF 上,如果是 DVASPECT_ICON ,則只在 RTF 上顯示一個圖標(biāo)。
  經(jīng)試,repastespecial 格式?jīng)]有作用,因此參數(shù)4設(shè)為0即可。

Private Type repastespecial
  dwAspect As Long '顯示方式
  dwParam As Long
End Type

Const WM_USER = &H400
Const EM_PASTESPECIAL = 1088
Const CF_BITMAP = 2
Const CF_TEXT = 1
Const DVASPECT_CONTENT = 1
Const DVASPECT_ICON = 4

Private Sub Command1_Click()
Dim re As repastespecial
re.dwAspect = DVASPECT_CONTENT
If Clipboard.GetFormat(vbCFText) Then ''剪貼板中為文本信息
 Call SendMessage(RichTextBox1.hwnd, EM_PASTESPECIAL, CF_TEXT, re)
ElseIf Clipboard.GetFormat(vbCFBitmap) Then ''剪貼板中為位圖信息
 Call SendMessage(RichTextBox1.hwnd, EM_PASTESPECIAL, CF_BITMAP, re)
End If
End Sub 
2.ListView控件也是Windows界面開發(fā)中重要的控件,典型的應(yīng)用就是Windows資源管理器中的文件列
表。而在VB中,ListView控件包含在Microsoft Windows Common Control 6.0(也可能是5.0,視你的
VB或者系統(tǒng)版本而定)中。在 Windows API 中,有一系列的以 LVM_開頭的消息值,這些消息就是擴(kuò)展
ListView控件所特定的消息值,下面的范例介紹如何通過LVM_消息設(shè)置ListView控件中圖標(biāo)的間距。范
例如下:

Private Type RECT
 Left As Long
 Top As Long
 Right As Long
 Bottom As Long
End Type

Const LVM_FIRST = &H1000
Const LVM_SETWORKAREA = LVM_FIRST + 65
Const LVM_SETICONSPACING = LVM_FIRST + 53

Private Sub Form_Load()
Dim xn As ListItem
Me.Show
ListView1.Width = 4500
ListView1.Height = 3000
ListView1.Refresh
Set xn = ListView1.ListItems.Add
xn.Text = "List1"
Set xn = ListView1.ListItems.Add
xn.Text = "List2"
Set xn = ListView1.ListItems.Add
xn.Text = "List3"
Set xn = ListView1.ListItems.Add
xn.Text = "List4"
Set xn = ListView1.ListItems.Add
xn.Text = "List5"
Set xn = ListView1.ListItems.Add
xn.Text = "List6"
ListView1.Refresh
Call SendMessage(ListView1.hwnd, LVM_SETICONSPACING, 0, ByVal (60 * 65536 + 190&))
End Sub

  要運行上面的程序,首先要確保ListView1的Arrange屬性為1,View屬性為0。在上面的程序中,我
們利用了 VM_SETICONSPACING 消息來控制圖標(biāo)間距。其中SendMessage中的參數(shù)lParam定義圖標(biāo)間距,
高位為縱向間距,低位為橫向間距,在上面的范例中,我們將圖標(biāo)的縱向間距定義為60像素,橫向間距
定義為190像素。
    

SendMessage函數(shù)的應(yīng)用(四) 
   
1,獲得光標(biāo)位置和字符個數(shù).
Cpos=SendMessage(text1.hwnd,187,-1,0)   '光標(biāo)所在行的首字符在文本中的位置
Lpos=SendMessage(text1.hwnd,201,Cpos,0) '光標(biāo)所在的行號
Line=SendMessage(text1.hwnd,193,Cpos,0) '這行的字符數(shù).

2.獲取第N行的文本
Dim ST As String
ST = Space(110)'必須要事先賦空格
Line=SendMessage(text1.hwnd,196, N-1, ByVal ST 'ST返回獲取到的文本,Line返回文本的長度字節(jié)數(shù)

'下面的未成功
Dim str(256) As Byte, K As Integer
str(1)=1 '最大允許存放256個字符
K = SendMessage (Text1.hwnd,196,2,str(0)) '獲取第3行的數(shù)據(jù)放在str中
text1.text = StrConv(str,vbUnicode) '轉(zhuǎn)換為字符串后顯示
   
  說明:在調(diào)用SendMessage獲取第N行字符串時,lParam需要說明為字節(jié)數(shù)組,在調(diào)用完成后,再將
字節(jié)數(shù)組轉(zhuǎn)換為字符串;另外,調(diào)用前必須在lParam的前兩個字節(jié)指明允許存放的最大長度,其中第一
個字節(jié)為低位,第二個字節(jié)為高位,本例將高位(即str(1))置1.說明最大允許存放256個字符。
 
3.開關(guān)顯示器.

SendMessage Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0 '關(guān)閉顯示器.
SendMessage Handle, WM_SYSCOMMAND, SC_MONITORPOWER, -1 '打開顯示器

4.程序控制拉下或收起組合框的下拉列表
   一般情況下,為了拉下或收起組合框的下拉列表,需要用鍵盤或鼠標(biāo)進(jìn)行操作,而有時我們希望程
序運行的某個時刻自動拉出下拉列表(比如在一些演示程序中),為了實現(xiàn)這個目的,我們也只有借助
于SendMessage函數(shù),方法是發(fā)一個CB_SHOWDROPDOWN(&H14F)消息給組合框。
   在發(fā)CB_SHOWDROPDOWN消息時,wParam參數(shù)決定了是拉下列表(=True)還是收起表(=False),
lParam無用(設(shè)為0)。
   為說明具體的使用方法,下面提供簡單的程序片段:

Const CB_SHOWDROPDOWN=&H14F

   當(dāng)程序中某處需要拉下組合框Combol的列表時,調(diào)用如下語句:

SendMessage Combol.hwnd,CB_SHOWDROPDOWN,True,0

   當(dāng)需要收起組合框Combol的列表時,調(diào)用如下語句:

SendMessage Combol.hwnd,CB_SHOWDROPDOWNN,False,0

5. 返回控件中顯示的第一行的行號。

LineNo = SendMessageBynum(CTextBox.hwnd, EM_GETFIRSTVISIBLELINE, 0, 0) 
  
6.下面的函數(shù)能夠滾動控件,不過在滾動之前最好判斷控件的文本行數(shù)和能夠顯示的行數(shù),以免滾動時
發(fā)生混亂。函數(shù)SendMessageBynum是SendMessage函數(shù)的安全聲明函數(shù),其定義與SendMessage函數(shù)完全
相同,只是函數(shù)名不同。 

Function ScrollTextBox(CTextBox As TextBox, nVal As Long, Optional nVertical As _
  Boolean = True) As Long 
If nVertical Then 
 ScrollTextBox = SendMessageBynum(CTextBox.hwnd, EM_LINESCROLL, 0, nVal) 
Else 
 ScrollTextBox = SendMessageBynum(CTextBox.hwnd, EM_LINESCROLL, nVal, 0) 
End If 
End Function 

7.下面的函數(shù)將返回控件能顯示的行數(shù):(經(jīng)試,總是引起程序崩潰)

'獲取當(dāng)前字體的矩形區(qū)域(即字體的高度與平均寬度等信息)
Private Declare Function GetTextMetrics Lib "gdi32" Alias "GetTextMetricsA" (ByVal hdc As Long, lpMetrics As TEXTMETRIC) As Long
Private Type TEXTMETRIC
  tmHeight As Long           '字符高度
  tmAscent As Long           '字符上部高度(基線以上)
  tmDescent As Long          '字符下部高度(基線以下)
  tmInternalLeading As Long  '由tmHeight定義的字符高度的頂部空間數(shù)目
  tmExternalLeading As Long  '加在兩行之間的空間數(shù)目
  tmAveCharWidth As Long     '平均字符寬度
  tmMaxCharWidth As Long     '最寬字符的寬度
  tmWeight As Long           '字體的粗細(xì)輕重程度
  tmOverhang As Long         '加入某些拼接字體上的附加高度
  tmDigitizedAspectX As Long '字體設(shè)計所針對的設(shè)備水平方向
  tmDigitizedAspectY As Long '字體設(shè)計所針對的設(shè)備垂直方向
  tmFirstChar As String      '為字體定義的第一個字符
  tmLastChar As String       '為字體定義的最后一個字符
  tmDefaultChar As String    '字體中所沒有字符的替代字符
  tmBreakChar As String      '用于拆字的字符
  tmItalic As Byte           '字體為斜體時非零
  tmUnderlined As Byte       '字體為下劃線時非零
  tmStruckOut As Byte        '字體被刪去時非零
  tmPitchAndFamily As Byte   '字體間距(低4位)和族(高4位)
  tmCharSet As Byte          '字體的字符集
End Type
Type RECT
  Left As Long
  Top As Long
  Right As Long
  bottom As Long
End Type
Public ST As String

Function GetVisibleLines(CTextBox As TextBox) As Long 
Dim rc As RECT  '以象素為單位
Dim tm As TEXTMETRIC
Dim hDC&, lfont&, oldfont& 
Dim di&, lc& 
lc = SendMessage(CTextBox.hwnd, EM_GETRECT, 0, rc) 
lfont = SendMessage(CTextBox.hwnd, WM_GETFONT, 0, 0) 
hDC = GetDC(CTextBox.hwnd) 
If lfont <> 0 Then oldfont = SelectObject(hDC, lfont) 
di = GetTextMetrics(hDC, tm) 
If lfont <> 0 Then lfont = SelectObject(hDC, oldfont) 
GetVisibleLines = (rc.bottom - rc.top) / tm.tmHeight 
di = ReleaseDC(CTextBox.hwnd, hDC) 
End Function

8.設(shè)置控件的左邊距。 

Public Const EM_SETMARGINS& = &HD3 
Public Const EC_LEFTMARGIN& = &H1 

Function SetMargins(CTextBox As TextBox, nVal As Long) As Long 
SetMargins = SendMessageBynum(CTextBox.hwnd, EM_SETMARGINS, EC_LEFTMARGIN, nVal) 
End Function

9.利用SendMessage函數(shù)還可以實現(xiàn)一些有趣的效果:
  例如在按鈕的Click事件中加入如下語句:

SendMessage(Command1.hWnd,BM_SETSTYLE,BS_RADIOBUTTON,1)'BM_SETSTYLE = &HF4,BS_RADIOBUTTON = &H4

  運行后點擊按鈕,就可以把按鈕變成一個收音機(jī)按鈕(經(jīng)試,變成一個圓孔,有點象單選按紐)。
  如要得到圓形或橢圓形按紐可使用另外2個API函數(shù):

hdc=CreateEllipticRgn(3, 3, 25, 25) '試驗成功,這兩個函數(shù)也用于創(chuàng)建圓形窗體
SetWindowRgn Command1.hWnd, hdc, True
DeleteObject hdc

10.窗體操作
  
Public Const WM_SYSCOMMAND = &H112
Public Const SC_CLOSE = &HF060 '關(guān)閉窗體
Public Const SC_MINIMIZE = &HF020 '最小化窗體
Public Const SC_MAXIMIZE = &HF030 '最大化窗體
Public Const SC_RESTORE = &HF120 '恢復(fù)窗體大小
Public Const WM_SETTEXT = &HC '設(shè)置窗體的Caption
Public Const WM_GETTEXT = &HD '取得窗體的caption

Private Sub Command_Click(Index As Integer)
Dim S As String
S = String(80, Chr(0)) 
Select Case Index
 Case 0: SendMessage Me.hwnd, WM_GETTEXT, Len(S), ByVal S: Text1 = Left(S, InStr(S, Chr(0)) - 1) '讀出窗體的Caption
 Case 1: SendMessage Me.hwnd, WM_SETTEXT, 0, ByVal CStr(Text1.Text)'設(shè)置窗體的Caption,由于Text1.text屬于Variant類型,所以一定先要用CStr把它轉(zhuǎn)換成字符串
 Case 2: SendMessage Me.hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, ByVal 0&'窗體最大化
 Case 3: SendMessage Me.hwnd, WM_SYSCOMMAND, SC_MINIMIZE, ByVal 0&'窗體最小化
 Case 4: SendMessage Me.hwnd, WM_SYSCOMMAND, SC_RESTORE, ByVal 0&'窗體恢復(fù)原來的大小
 Case 5: SendMessage Me.hwnd, WM_SYSCOMMAND, SC_CLOSE, ByVal 0&'關(guān)閉窗體
End Select
End Sub

11.文本垂直居中:
  實現(xiàn)這個效果首先TextBox的MultiLine屬性必須為True(多行文本,其實這個屬性關(guān)系創(chuàng)建TextBox內(nèi)部

使用哪個類,因此一旦創(chuàng)建就不能修改這個屬性,所以不能在代碼中修改這個屬性)

Public Sub VerMiddleText(mText As TextBox)
Dim rc As RECT '以象素為單位
Dim tmpTop As Long
Dim tmpBot As Long
If mText.MultiLine = False Then Exit Sub
Call SendMessage(mText.hwnd, EM_GETRECT, 0, rc)'獲得窗口區(qū)域的邊界
   '進(jìn)行位置數(shù)據(jù)計算
With Me.Font
  .Name = mText.Font.Name
  .Size = mText.Font.Size
  .Bold = mText.Font.Bold
End With
tmpTop = ((rc.Bottom - rc.Top) - (mText.Parent.TextHeight("H") \ Screen.TwipsPerPixelY)) \ 2
tmpBot = ((rc.Bottom - rc.Top) + (mText.Parent.TextHeight("H") \ Screen.TwipsPerPixelY)) \ 2
rc.Top = tmpTop
rc.Bottom = tmpBot
mText.Alignment = vbCenter
   '數(shù)據(jù)計算完畢,再發(fā)送EM_SETRECTNP消息(為一個編輯控件設(shè)置格式化矩形,與EM_SETRECT類似,只是控件此時不會重畫)
Call SendMessage(mText.hwnd, EM_SETRECTNP, 0&, rc)
mText.Refresh
End Sub

12.調(diào)整邊距:
  如果你查看TextBox中常用的消息,你會發(fā)現(xiàn)有這樣一對消息:EM_GETMARGINS 和 EM_SETMARGINS,MSDN的解
釋是:獲取和設(shè)置編輯控件的左、右邊距(不得用于NT3.51)。具體是左還是右由該消息的參數(shù)決定。
  這樣做有什么意義呢?有的時候如果你想在texebox中放入其他對象,而又不希望文本被覆蓋掉,你就需要用
到這個方法。

Private Sub SetMargin(nLeft As Integer, nRight As Integer, lhWnd As Long)
Dim lLongValue As Long
lLongValue = nRight * &H10000 + nLeft '高四位表示右邊距,低四位為左邊距
SendMessage lhWnd, EM_SETMARGINS, EC_LEFTMARGIN Or EC_RIGHTMARGIN, lLongValue
End Sub

SendMessage函數(shù)應(yīng)用(五)
  RichEdit控件的正文操作

一、正文搜索
     RichEdit 控件具有幾種正文操作,搜索指定正文就是其中的一種。搜索正文是通過發(fā)送
EM_FINDTEXT 或者 EM_FINDTEXTEX 消息來完成的。這兩個消息有一點很小的不同點。

1.EM_FINDTEXT
 wParam=搜索選項,可以是下面3個參數(shù)的任意組合值(這些選項對 EM_FINDTEXT 和 EM_FINDTEXTEX
都是一樣的):
①FR_DOWN(&H1):搜索方向。如果指定了這個標(biāo)志值,搜索操作從當(dāng)前選定的 end 位置開始,直到控件
  中正文的 end 位置結(jié)束(向下搜索)。這個標(biāo)志影響 RichEdit 2.0 和以后版本,是 RichEdit 1.0
  的缺省行為。RichEdit 2.0或以后版本的缺省行為是:在當(dāng)前選定正文內(nèi)的從結(jié)尾搜索到開始位置
  (向前搜索)。概括來說就是,如果你使用 RichEdit 1.0, 無論你做什么都沒法影響搜索的方向,它
  總使用向后搜索。但是如果你使用 RichEdit 2.0 而且你想使用向后搜索的話,你必須指定這個標(biāo)
  志值,否則使用的是向前搜索了。
②FR_MATCHCASE(&H4):區(qū)分大小寫。
③FR_WHOLEWORD(&H2):匹配指定搜索串的整個詞。

 lParam = FINDTEXT 結(jié)構(gòu)的指針。
Type FINDTEXT        'STRUCT
  chrg As CHARRANGE  '
  lpstrText As Long
End Type

  chrg 是一個 CHARRANGE 結(jié)構(gòu),其定義如下:
Type CHARRANGE       'STRUCT
  cpMin As Long      '包含字符數(shù)組中第一個字符的字符索引
  cpMax As Long      '包含緊跟在字符數(shù)組中最后一個字符的字符的字符索引
End Type 

  基本上,要搜索一個正文串,你必須指定要搜索的字符范圍。cpMin 和 cpMax 的具體意義根據(jù)搜索是向
后還是向前是不同的。
  如果是向后搜索,cpMin 指定搜索的開始字符索引,而 cpMax 則是結(jié)束字符索引。
  如果是向前搜索,則反過來才對,也就是說 cpMin 包含結(jié)束字符索引而cpMax 包含開始字符索引。

  lpstrText 是要搜索的正文串的指針。

2.EM_FINDTEXTEX
  返回控件中跟搜索串匹配的的正文串的一個字符的索引。如果沒找到匹配的則返回 -1。

  wParam = 搜索選項,跟 EM_FINDTEXT 的一樣。
  lParam = FINDTEXTEX 結(jié)構(gòu)的指針。

Type FINDTEXTEX      'STRUCT
  chrg As CHARRANGE  '
  lpstrText As Long 
  chrgText CHARRANGE 'CHARRANGE
End Type

  FINDTEXTEX 中開始的兩個成員是跟 FINDTEXT 結(jié)構(gòu)中的一樣的。
  chrgText 是一個 CHARRANGE 結(jié)構(gòu),如果搜索到匹配串的話,其開始/結(jié)束字符索引會被填入這個結(jié)構(gòu)中。

  EM_FINDTEXTEX 的返回值跟 EM_FINDTEXT的是一樣的。

  EM_FINDTEXT 跟 EM_FINDTEXTEX 的不同處:
FINDTEXTEX 結(jié)構(gòu)有一個另外的chrgText成員, 如果搜索到匹配串的話,其開始/結(jié)束字符索引會被填入這個成
員中。如果我們想對這個正文串進(jìn)行更多的正文操作的話,有這個就方便多了。

二、替換/插入正文

  RichEdit 控件提供了 EM_SETTEXTEX 來進(jìn)行正文替換/插入操作。這個消息混合了 WM_SETTEXT 和
EM_REPLACESEL 的功能. 它具有以下語法:

  wParam = SETTEXTEX 結(jié)構(gòu)的指針。
Type SETTEXTEX      'STRUCT
  flags As Long 
  codepage As Long
End Type

  flags 可以是以下值的組合:
  ST_DEFAULT   刪除Undo堆棧,丟棄RTF格式,替換所有的正文。
  ST_KEEPUNDO  保留Undo堆棧。
  ST_SELECTION 替換選定正文并且保留RTF格式

  codepage 是一個常量,指定你的正文想要的代碼頁。我們通常簡單的使用 CP_ACP。

三、正文選擇

  我們可以使用消息 EM_SETSEL 或者 EM_EXSETSEL 來編程選擇正文.其中任意的一個都可以工作的很好。
要使用哪一個消息要根據(jù)可用的字符索引格式來選擇。如果它們保存在一個 CHARRANGE 結(jié)構(gòu)中,則使用
EM_EXSETSEL更容易實現(xiàn)。

  EM_EXSETSEL
  wParam = 沒有使用,必須為 0 。
  lParam = CHARRANGE 結(jié)構(gòu)的指針,包含想要選定的正文字符范圍。

四、事件通知

  在使用多行Edit控件時,你必須子類化它以便得到輸入信息象鼠標(biāo)/鍵盤事件等。RichEdit 控件提供了一
個更好的方案,它可以把這些消息通知父窗口。為了注冊得到通知消息,父窗口發(fā)送 EM_SETEVENTMASK 消息
給 RichEdit 控件,指定它對哪些消息感興趣。 
  EM_SETEVENTMASK 具有以下的語法:
wParam  沒有使用,必須為 0 。

lParam = 事件掩碼值,可以是以下標(biāo)志值的任意組合:

  ENM_CHANGE 發(fā)送 EN_CHANGE 通知
  ENM_CORRECTTEXT 發(fā)送 EN_CORRECTTEXT 通知
  ENM_DRAGDROPDONE 發(fā)送 EN_DRAGDROPDONE 通知
  ENM_DROPFILES 發(fā)送 EN_DROPFILES 通知
  ENM_KEYEVENTS 為鍵盤消息發(fā)送 EN_MSGFILTER 通知
  ENM_LINK Rich Edit 2.0 或以后版本: 當(dāng)鼠標(biāo)在具有 CFE_LINK 風(fēng)格的正文上面移過,而且執(zhí)行了一個
或幾個鼠標(biāo)動作時,就發(fā)送 EN_LINK 通知。
  ENM_MOUSEEVENTS 為鼠標(biāo)消息發(fā)送 EN_MSGFILTER 通知。
  ENM_OBJECTPOSITIONS 發(fā)送 EN_OBJECTPOSITIONS 通知
  ENM_PROTECTED 發(fā)送 EN_PROTECTED 通知
  ENM_REQUESTRESIZE 發(fā)送 EN_REQUESTRESIZE 通知
  ENM_SCROLL 發(fā)送 EN_HSCROLL 和 EN_VSCROLL 通知
  ENM_SCROLLEVENTS 為鼠標(biāo)滑輪發(fā)送 EN_MSGFILTER 通知。
  ENM_SELCHANGE 發(fā)送 EN_SELCHANGE 通知
  ENM_UPDATE 發(fā)送 EN_UPDATE 通知

  Rich Edit 2.0 和以后版本: 這個標(biāo)志值會被忽略,而經(jīng)常發(fā)送 EN_UPDATE 通知。然而如果 RichEdit 
3.0 模擬 RichEdit 1.0的話,你必須使用這個標(biāo)志值來發(fā)送 EN_UPDATE 通知

  上面的所有通知都被做為 WM_NOTIFY 消息來發(fā)送:你必須檢查 NMHDR 結(jié)構(gòu)的 code 成員來得到通知消

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“SendMessage有哪些參數(shù)”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI