SendMessage函数的常用消息及其应用大全
來源:http://www.360doc.com/content/09/0814/10/19147_4907488.shtml,非常全面的解釋。
文本框控件通常用于輸入和編輯文字。它屬于標準?Windows?編輯控件的一個子類,所以它支持所有
編輯控件消息。這兒講述的技術也適用于由其他廠商設計的,以Windows編輯控件類為基礎的其他控件。
函數(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?調用中至關重要。VB?的大多數(shù)控件都包
括hwnd屬性,如下拉框、TreeView等,窗體也有這個屬性。但也有一些控件沒有這個屬性,如標簽控件。
沒有這個屬性就無法利用Windows?API函數(shù),但可以節(jié)省系統(tǒng)資源。
?
2.wMsg:
被發(fā)送的消息。根據具體需求和不同的對象,將不同的消息作為實參傳送,以產生預期的動作。使
SendMessage?傳遞消息,大多是為了完成以下幾個工作:?
?、僭O置控件的一些選項,象我們要使用的CB_SETDROPPEDWIDTH的就屬于這種情況。盡管VB的每個控
件都提供了許多屬性,但仍然有許多控件的選項沒有包括在其中。而這些選項中的大多數(shù)都可以利用該
函數(shù)進行設置。
?、讷@得控件的一些設置。同上一種情況相反,有時我們需要獲得控件的一些設置,相當于讀取屬性。
例如,如果想知道一個下拉框的下拉部分的寬度是多少,就可以向控件發(fā)送CB_GETDROPPEDWIDTH消息。
對于這種情況,SendMessage函數(shù)的返回值就是結果。?
③執(zhí)行一定的操作。例如,我們要在下拉框中尋找是否有“ABC”這個字符串,當然,我們可以編寫
一個循環(huán),逐條比較看是否存在這樣的字符串。如果使用API,我們只需要向下拉框發(fā)送CB_FINDSTRING
消息,這條消息就會自動進行查找工作并返回結果。?
?、苣M用戶操作。我們有時希望模擬用戶的操作,比如關閉其他應用程序的窗口。其實只要我們能知
道那個窗口的句柄,我們就可以發(fā)送WM_CLOSE消息給那個窗口,窗口接受到這條消息就會關閉,如同用戶
關閉窗口一樣。?
3.wParam、4.lParam:
附加的消息信息。這兩個是可選的參數(shù),用來提供關于wMsg消息更多的信息,不同的wMsg可能使用這
兩個參數(shù)中的0、1或2個,如果不需要哪個附加參數(shù),則將實參賦為NULL(在VB中賦為0)。
lParam定義為Any類型。指定?Any類型可禁止VB進行類型檢查,從而允許將任意數(shù)據類型傳遞給該過
程。由于每條消息對參數(shù)的類型和傳遞方式的要求都不同:有的可能要求為Long型,有的可能要求為自定
義類型;大多數(shù)要求按傳值方式傳遞,但也有一些要求按傳地址方式。為了滿足各種要求,我們將這個參
數(shù)定義為Any類型。比如,我們要傳遞一個Long型變量lData。如果消息要求傳地址方式傳遞,可以使用:?
SendMessage?……,?lData?
而如果要求傳值方式傳遞,則使用?
SendMessage?……,?ByVal?lData?
如果傳遞常數(shù),我們則需要使用類型后綴來指定常數(shù)的類型,比如"0&",表示Long型的常數(shù)0,如?
SendMessage?……,?ByVal?0&?
我們也可以使用類型轉換函數(shù)CLng將常數(shù)指定為Long型,如CLng(0)。
程序中,有時定義?lParam?As?Any,有時定義?ByVal?lParam?As?String。這是為什么呢?對于
SendMessage函數(shù),lParam的使用是很靈活的,在一般情況下,lParam是一個指針,它指向的數(shù)據類型
有三種:長整形、自定義數(shù)據結構類型、字符串類型。對于前兩種類型,需要將?lParam定義為?lParam
As?Any,從而將?lParam?數(shù)據的指針傳遞到?SendMessage?函數(shù)。對于字符串類型,則需要定義?Byval
lParam?As?String,因為字符串類型數(shù)據不同,只有定義?ByVal,得到的才是字符串的指針,如果沒有
ByVal,得到的將是指向字符串指針的指針。另外對于少數(shù)的消息來說,SendMessage?函數(shù)需要的只是
lParam?本身的值,這時就需要將?lParam定義為?Byval?lParam?As?Long,或者在程序調用時在?lParam
之前加?ByVal。
當用戶在編輯控件上進行各種操作時,其父窗口將收到?WM_COMMAND?通知消息,lParam帶控件句柄
(hWnd),同時?wParam?的低16位帶控件的?ID,高16位帶有如下表的消息代碼:
常用編輯控件消息:
EC_LEFTMARGIN(&H1)????????????????????EC_USEFONTINF?設置左邊距時使用
EC_RIGHTMARGIN????????????????????????EC_USEFONTINF?設置右邊距時使用
EC_USEFONTINF,O,邊距??????????????????設置編輯控件的左、右邊距,當wParam含EC_LEFTMARGIN時在lParam的低16位指定左邊距點數(shù),當wParam含EC_RIGHTMARGIN時在lParam的高16位指定右邊距點數(shù)。當指定wParam為EC_USEFONTINFO時,則用當前字體的字符"A"的寬度指定右邊距和字符"C"的寬度指定左邊距l(xiāng)Param被忽略。
EM_CHARFROMPOS(&HD7=215),0,???????????取得編輯控件中指定位置的字符相對于文本頭部的偏移量。使用本操作應先在第4個參數(shù)的高16位指定行號,低16位指定列號(或一個POINTAPI結構),行列是按編輯控件的客戶區(qū)左上角為原點(0,0)計算的。如果指定的位置超出控件客戶區(qū)則返回-1
EM_CANUNDO(&HC6=198),0,0??? ?????????決定前一次編輯操作是否能夠撤消:檢測控件撤消緩沖區(qū)是否為空,通??丶炎詈笠淮卧诳丶木庉嫴僮鞅4嬖谝粋€撤消緩沖區(qū),如果緩沖區(qū)非空則返回TRUE表示上次操作可以撤消,否則返回FALSE,應用程序可以利用該返回值來禁止或允許菜單或工具條的"撤消"項。
EM_EMPTYUNDOBUFFER(&HCD=205?),0,0?????清除控件的撤消緩沖區(qū),使其不能撤消前一次編輯操作?
EM_FMTLINES(&HC8=200)??????????? ????決定是否在取回的文本宇串中包含軟回車字符
EM_GETFIRSTVISIBLEINE(&HCE=206),0,0???獲得文本控件中處于可見位置的最頂部的文本所在的行號
EM_GETLINE(&HC4=196?),行號,ByVal?變量?獲取編輯控件某一行的內容,變量須預先賦空格
EM_GETLINECOUNT(&HBA=186,0,0??????????獲取編輯控件的總行數(shù)
EM_GETMODIFY(&HB8=184),0,0 ??????????判斷編輯控件的內容是否已發(fā)生變化,返回TRUE則控件文本已被修改,返回FALSE則未變。?
EM_GETPASSWORDCHAR(?),0,0 ???????????獲取編輯控件的密碼字符,返回NULL表示沒有字符
EM_GETRECT(&HB2=178),0,結構???????? ?獲取編輯控件的格式化矩形
EM_GETTHUMB(&HBE=190),0,0?????????????取得多行文本編輯控件的滾動框的當前位置(注意:是象素值)
EM_GETSEL(&HB0=176),0,變量????????????獲取光標位置(以字節(jié)數(shù)表示),或:(緩沖區(qū)起點,緩沖區(qū)終點)取得編輯控件中選定內容的范圍,返回值中低16位為起點,高16位為終點
EM_GETHANDLE(&HBD=189),0,0????????????取得文本緩沖區(qū)
EM_GETWORDBREAKPROC(&HD1=209),0,0?????取得整字換行回調函數(shù)EditWordBreakProc指針
EM_GETLIMITTEXT(WM_USER+37=1061),0,0??獲取一個編輯控件中文本的最大長度?
EM_GETMARGINS(?),0,0??????????????????獲取編輯控件的左、右邊距,返回值低16位為左邊距,高16位為右邊距(不得用于NT3.51)?
EM_LIMITTEXT(&HC5=197),最大值,0???????設置編輯控件中的文本長度
EM_SCROLLCARET(&HB7=183),0,0??????????把可見范圍移至光標處
EM_LINEFROMCHAR(&HC9=201),偏移值,0????獲取指定位置(或:-1,0?表示光標位置)所在的行號
EM_LINEINDEX(&HBB=187),行號,0?????????獲取指定行(或:-1,0?表示光標所在行)首字符在文本中的位置(以字節(jié)數(shù)表示)
EM_LINELENGTH(&hC1=193),偏移值,0??????獲取指定位置所在行(或:-1,0?表示光標所在行)的文本長度(以字節(jié)數(shù)表示)
EM_POSFROMCHARPOINT,結構地址,偏移值???取得指定字符位置的行列號,偏移值是字符相對于文本頭部的偏移。
EM_LINESCROLL(&HB6=182),列數(shù),行數(shù)?????指定行數(shù)的文本水平滾動,每次滾動N列
EM_EXGETSEL(&H434=1076)???
EM_EXSETSEL(&H437=1079),0,結構????????RichEdit控件設置文本選定范圍,參閱?EM_SETSEL?消息,結構是指?CHARRANGE?結構
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)設置?RichTextBox?自動換行,后續(xù)代碼是:RichText.RightMargin?=?iif(RichText.RightMargin?=?0,1,0)
EM_SETTARGETDEVICE,?0,?1??????????????設置?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),字符串???用指定字符串替換編輯控件中的當前選定內容,如果第三個參數(shù)wParam為1,則本次操作允許撤消,0禁止撤消。字符串可用傳值方式,也可用傳址方式(例:SendMessage?Text1.hwnd,?EM_REPLACESEL,?0,?Text2.Text?'這是傳值方式)
EM_SETSEL(&HB1=177),起點,終點????????設置編輯控件中文本選定內容范圍(或設置光標位置),該范圍被反相顯示,用于為復制、替換、粘貼、剪切、刪除等編輯功能指定范圍,光標將被移至指定的終點后面。還可使用指定相同起點和終點來移動光標而不是選定范圍。當指定的起點等于0和終點等于-1時,文本全部被選中,此法常用在清空編輯控件。當指定的起點等于-2和終點等于-1時,全文均不選,光標移至文本未端,此法常用在文本未端追加內容。注意:當控件沒有輸入焦點時,本操作將會失敗,一般在執(zhí)行本操作前都應調用SetFocus先取得輸入焦點。
EM_UNDO(&HC7=199),0,0?????????????????撤消前一次編輯操作,當重復發(fā)送本消息,控件將在撤消和恢復中來回切換
EM_SETCHARFORMAT(&H444)???????????????改變選定文本的顏色
EM_SETHANDLE(&HBC=188),緩沖區(qū)指針,0??為編輯控件指定新的文本緩沖區(qū)。此操作僅適用對話框創(chuàng)建帶DS_LOCALEDIT風格的控件。
EM_SETLIMITTEXT,長度(字節(jié)),0??????????設置編輯控件中的文本最大長度(不得用于NT3.51)
EM_SETMARGINS(&HD3=211)???????????????設置編輯控件的左、右邊距(不得用于NT3.51)
EM_SETMODIFY(&HB9=185),1(0),0?????????設置或清除一個編輯控件的修改標志
EM_SETPASSWORDCHAR(&HCC=204),字符,0???指定控件用來顯示密碼的字符,缺省為"*"。當?shù)谌齻€參數(shù)wParam為0時,本操作將清除控件的ES_PASSWORD風格,并按實際字符顯示。
EM_SETREADONLY(&HCF=207),1(0),0???????決定是否將編輯控件設為只讀,同時決定控件的ES_READONLY風格
EM_SETRECT(&HB3=179),0(或RECT),結構地址??????為一個編輯控件設置格式化矩形
EM_SETRECTNP(&HB4=180),0(或RECT),結構地址????為一個編輯控件設置格式化矩形,只是控件此時不會重畫
EN_CHANGE(&H300=768)??????????????????編輯控件的內容發(fā)生改變。與EN_UPDATE不同,該消息是在編輯框顯示的正文被刷新后才發(fā)出的。?
EN_ERRSPACE(&H500=1280)???????????????任何時候只要由于內存不足以完成一項編輯操作?
EN_HSCROLL(&H601=1537)????????????????用戶單擊了編輯控件的水平滾動條。注意:這條消息是在控件更新顯示之前發(fā)送出去的。
EN_VSCROLL(&H602=1538)????????????????用戶單擊了編輯控件的垂直滾動條。注意:這條消息是在控件更新顯示之前發(fā)送出去的。
EN_KILLFOCUS(&H200=512)???????????????編輯控件失去了輸入焦點
EN_SETFOCUS(&H100=256)????????????????編輯控件獲得了輸入焦點
EN_UPDATE(&H400=1024)?????????????????控件準備顯示改變了的正文時發(fā)送該消息。它與EN_CHANGE通知消息相似,只是它發(fā)生于更新文本顯示出來之前。?
EN_MAXTEXT(&H501=1281)????????????????用戶輸人的文字數(shù)超出由EM_LIMITTEXT消息規(guī)定的界限,或超出由VB?Maxlength屬性規(guī)定的界限,就會發(fā)送這條消息?。此外,倘若不允許自動進行水平滾動,同時插入點要超出控件的寬度;或者不允許自動垂直滾動,同時插入點要超出控件的高度,那么也會觸發(fā)這條消息。在沒有ES_AUTOHSCROLL或ES_AUTOVSCROLL的編輯框中,當正文超出了編輯框的邊框時也會發(fā)出該消息。?
編輯風格消息:
ES_MULTILINE? ???????????????????????指定編輯控件能否進行多行文本編輯,若多行編輯器不指定ES_AUTOHSCROLL風格,則會自動換行,用戶每按一次Enter,在當前光標處輸入一個回車換行符(0Dh,0Ah),文本增加一行。若不指定ES_AUTOVSCROLL,則多行編輯器會在窗口中正文裝滿時發(fā)出警告聲響。
ES_LEFT???????????????????????????????文本顯示居左。
ES_CENTER ???????????????????????????文本顯示居中。
ES_RIGHT ????????????????????????????文本顯示居右。
ES_LOWERCASE ????????????????????????把用戶輸入的字母統(tǒng)統(tǒng)轉換成小寫字母。
ES_UPPERCASE ????????????????????????把用戶輸入的字母統(tǒng)統(tǒng)轉換成大寫字母。
ES_OEMCONVERT ???????????????????????把輸入的文本從ANSI碼轉換成OEM碼,然后又轉換成ANSI碼,目的是保證函數(shù)AnsiToOem的正確調用。這在編輯框中包含文件名時是很有用的。
ES_AUTOHSCROLL(自動增加水平滾動條?)?當用戶在行尾鍵入一個字符時,正文將自動向右滾動10個字符,當用戶按回車鍵時,正文總是滾向左邊。
ES_AUTOVSCROLL ??????????????????????當用戶在最后一個可見行按回車鍵時,正文向上滾動一頁。
ES_NUMBER ???????????????????????????只接收數(shù)碼輸入,其它字符輸入一律無效。
ES_NOHIDESEL(&H100=256)???????????????當編輯框失去輸入焦點時,選中的文本將隱藏,正文中的選擇保持不變。缺省時正文中的選擇將失效,當獲得輸入焦點后才又顯示出來。
ES_READONLY ?????????????????????????將編輯框設置成只讀的。
ES_PASSWORD(&H20=32)??????????????????使所有鍵入的字符都用"*"來顯示。
ES_WANTRETURN ???????????????????????使多行編輯器接收回車鍵輸入并換行。如果不指定該風格,按回車鍵會選擇缺省的命令按鈕,這往往會導致對話框的關閉。
列表框操作:
LB_FINDSTRING(&H18F=399),-1,ByVal?字串???查找列表項的字符串,返回值=字符串所在的列表項的索引。-1表示從第0行開始查找,如果改為一個有效的列表項索引值,將從該行開始查找。
LB_ITEMFROMPOINT(&H1A9=425)??????????????獲取光標所在的列表項的索引
LB_SETHORIZONTALEXTENT(&H194=404),長度,0?設置列表框的橫向滾動條以及滾動長度,長度為象素值
組合框操作:
CB_SHOWDROPDOWN(&H14F),1(0),0?????????打開(關閉)組合框的列表
TVM_SETBKCOLOR(&H1100+29=4381)????????設置擴展樹型列表控件的背景色(TVM開頭的常數(shù))
常用窗口消息:
WM_GETFONT(&H31=49)???????????????????得到當前控件繪制文本的字體(的句柄)
WM_GETTEXT(&HD=13),變量長度,變量???????取得窗體的標題,變量須預先賦空字串(chr(0)),變量長度=Len(變量)
WM_SETTEXT(&HC=12),0,ByVal?"字串"?????設置窗體的標題
WM_NCLBUTTONDOWN(&HA1=161),2,0????????在非客戶區(qū),即邊框及標題欄上(假如定義的是一個組件,則非客戶區(qū)包括Form等)按下鼠標左鍵;
WM_LBUTTONDOWN(&H201=513),2,0?????????在客戶區(qū),也就是除邊框及標題欄以外按下鼠標左鍵
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???????????????復制
WM_PASTE(&H302=770)),0,0??????????????粘貼
WM_CLEAR(&H303=771)),0,0??????????????刪除
WM_UNDO(&H304=772)),0,0???????????????撤消
按紐消息:
BM_SETSTYLE(&HF4)???????????????????設置按紐樣式
BS_RADIOBUTTON(&H4)?????????????????收音機旋紐式的按紐,是?BM_SETSTYLE?使用的參數(shù)
?
SendMessage函數(shù)應用(一) ????在Windows系統(tǒng)的很多消息中,有一些不僅僅是提供一個窗口消息那么簡單。它們可以控制窗口的 動作和屬性。下面向大家介紹SendMessage函數(shù)在擴充列表(ListBox)控件功能方面的應用。? 在?Windows?中,有一系列的以?LB_?開頭的列表消息,這里介紹的就是利用LB消息控制的ListBox 的應用。
1、使列表中光標移動到不同的列表項上有不同的提示(ToolTip) 在列表框控件中有一個?ToolTipText?屬性,該屬性決定了當光標在列表框上移動時出現(xiàn)的提示文 字。但是如何使得當光標在不同的列表項上移動時的提示文字也不同呢?問題的關鍵是要知道在光標移 動時光標所在的列表項的索引,使用SendMessage函數(shù)發(fā)送?LB_ITEMFROMPOINT?消息就可以獲得。 在?Form1?中加入一個?ListBox?控件,運行程序,當光標在列表中移動時,可以看到根據光標所在 的不同的列表項,提示文字也不相同。代碼如下(我已試驗成功):
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?'確定在移動鼠標的同時沒有按下功能鍵或者鼠標鍵 ??lXPoint?=?CLng(X?/?Screen.TwipsPerPixelX)?'獲得光標的位置,以像素為單位 ??lYPoint?=?CLng(Y?/?Screen.TwipsPerPixelY) ??With?List1 ????lIndex?=?SendMessage(.hwnd,?LB_ITEMFROMPOINT,?0,?ByVal?((lYPoint?*?65536)?+?lXPoint))?'獲得光標所在的標題行的索引 ????If?lIndex?<?.ListCount?Then?.ToolTipText?=?.List(lIndex)?Else?.ToolTipText?=?"" ??End?With End?If End?Sub
2、向列表中加入橫向滾動條使得可以瀏覽長列表項 當向列表中加入的列表項超出了列表的顯示范圍后,列表并不會出現(xiàn)橫向滾動條讓你可以通過滾動來瀏覽 項目的全部內容。利用?LB_SETHORIZONTALEXTENT?消息可以設置列表框的橫向滾動條以及滾動長度。 在?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、使列表框可以響應用戶擊鍵 有時我們需要列表根據用戶的敲入字符串自動調整列表的ListIndex到最接近的列表項,就象VB中動態(tài) 響應用戶輸入控件屬性的編輯器一樣。問題的關鍵是如何在列表中查找含有指定字符串的列表項,使用 LB_FINDSTRING消息可以在列表中查找指定字符串。 在?Form1?中加入一個?TextBox?控件和一個?ListBox?控件,并將?List1的?Sorted?屬性設置為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)'注意!當參數(shù)4傳入的是字符串時,必須用ByVal傳遞 ??If?L?Then?List1.ListIndex?=?L End?If End?Sub
4.在列表框中查找匹配的項目 ???在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則傳進欲搜索的字符串(必須采用值 傳遞)。 ???具體的代碼和運行畫面與下面的?5.?合并在一起演示。
5.為ListBox添加水平滾動條 ???在VB中,列表框控件僅提供垂直滾動條,沒有設置水平滾動條的能力,當某些項目的文本寬度較長 時,超出列表框寬度部分的文本就無法顯示出來,因此,很有必要為ListBox添加一個水平滾動條來方 便操作。 ???為添加水平滾動條,只需發(fā)一條?LB_SETHORIZONTALEXTENT(&H194)?消息給列表框即可。發(fā)送消息 時,wParam為滾動條的長度(以像素為單位,可通過計算得出準確的長度,上面例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?"電視機" List1.AddItem?"電視臺" List1.AddItem?"電腦" List1.AddItem?"電腦游戲軟件" SendMessage?List1.hwnd,&H194,250,0?'為列表框添加水平滾動條 End?Sub
Private?Sub?Text1_Change() '注意!當lParam傳入的是字符串時,必須用ByVal傳遞 List1.ListIndex?=?SendMessage(List1.hwnd,LB_FINDSTRING,-1,ByVal?Text1.Text) End?Sub
6.在API文本瀏覽器里,當我們在搜索欄輸入任意字母,“可用項”里以該字母開頭的項目以高亮顯 示以引起我們注意該項是不是我們所需的。象這樣的功能一切提供搜索選項的程序都應該具備。以下例 子采用SendMessage函數(shù)實現(xiàn)這一技術。
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?=?""?'按下任意鍵則令原內容消失 Text1.SelLength?=?1?'限制長度 Text1.SelText?=?Chr(KeyAscii)?'顯示鍵盤符號 KeyAscii?=?0?'禁止響應 'ListBox中的項目文本若與文本框的一致則選中(高亮) List1.ListIndex?=?SendMessage(List1.hwnd,?LB_FINDSTRING,?-1,?ByVal?CStr(Text1.Text))'經試,不需CStr函數(shù)? End?Sub
以上程序適用于單項目為多個字母的查詢,但必須注意,在TextBox的KeyPress事件中要作相應的 改動
SendMessage函數(shù)應用(二)? 介紹如何利用消息函數(shù)來擴展樹型列表?TreeView?控件的功能。相信對于樹型列表控件大家十分的 熟悉,典型的應用就是?Windows?資源管理器中的目錄列表。而在VB中,樹型列表控件包含在Microsoft Windows?Common?Control?6.0(也可能是5.0,視你的VB或者系統(tǒng)版本而定)中。在Windows?API?中, 有一系列的以?TVM_?開頭的消息值,這些消息就是擴展樹型列表控件所特定的消息值,下面向大家介紹 其中的一些應用
1、設置樹型列表控件的背景顏色 首先做如下的定義:
Const?TV_FIRST?=?&H1100 Const?TVM_SETBKCOLOR?=?TV_FIRST?+?29(4381) 調用: Call?SendMessage(TreeView1.hwnd,?4381,?0,ByVal?RGB(255,?0,?0))
上面的SendMessage調用將TreeView1的背景顏色設置為紅色。 大家可能注意到了。在上面的?Sendmessage?函數(shù)定義中,我們將?lParam?定義為?ByVal?lParam As?Long,而不是象前面的那些范例那樣定義為?Any?或者?String?類型,關于這個問題,我會在最后的 一章中做介紹。
2、設置樹型列表控件標題行高度 TVM_SETITEMHEIGHT 消息設定控件的標題行的高度,該消息的定義及調用方法如下:
Const?TV_FIRST?=?&H1100 Const?TVM_SETITEMHEIGHT?=?TV_FIRST?+?27
Call?SendMessage(TreeView1.hwnd,?TVM_SETITEMHEIGHT,?60,?0)?'將TreeView1標題行高度設置到60像素高
3、為樹型列表控件中不同的標題行設置不同的提示 介紹如何為樹型列表控件中的每一個標題設置不同的提示。同?ListBox控件不通,樹型列表控件中 并沒有根據光標位置獲得標題行索引的消息,我們需要另外想辦法。在TVM類消息中有一個TVM_HITTEST 消息,發(fā)送該消息可以檢測控件表面上的某一點,如果該點位于一個標題上,則返回該標題的句柄。而 利用?TVM_GETITEM消息,則可以根據標題句柄返回該標題行的文本。所以結合利用這兩個消息可以獲取 光標所在標題行的標題文本。具體的范例代碼如下:
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 ?。?#39;加入若干Item ?。燬et?ndX?=?TreeView1.Nodes.Add(,?,?"R",?"Root") ?。燬et?ndX?=?TreeView1.Nodes.Add("R",?tvwChild,?"Key1",?"Node1") ?。燬et?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") ?。燬et?ndX?=?TreeView1.Nodes.Add("Key1",?tvwChild,?"SubKey3",?"SubNode3") ?。燬et?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) ?。燚im?ptA?As?TPoint Dim?tf?As?TVHITTESTINFO ?。燚im?tv?As?TVITEM Dim?hStr?As?Long ?。燚im?hItem?As?Long ?。燚im?astr?As?String?*?1024 Dim?bstr ?。燨n?Error?GoTo?errLab
?。?#39;獲得當前光標所在的位置坐標 ?。爌tA.x?=?Int(x?/?Screen.TwipsPerPixelX) ptA.y?=?Int(y?/?Screen.TwipsPerPixelY) ?。爐f.pt?=?ptA tf.flags?=?TVHT_ONITEMLABEL
?。?#39;獲得光標所在的Item的句柄 hItem?=?SendMessageRef(TreeView1.hwnd,?TVM_HITTEST,?0,?tf) '如果未獲得句柄或者同上一次是同一個Item的句柄則退出 ?。營f?((hItem?<=?0)?Or?(hItem?=?hItemPrv))?Then?Exit?Sub
hItemPrv?=?hItem ?。?#39;分配一定的內存空間用以存儲Item的標題 ?。爃Str?=?GlobalAlloc(GMEM_FIXED,?1024)
If?hStr?>?0?Then ?。牐爐v.mask?=?TVIF_TEXT?'獲取標題文本 ?。牐爐v.HTreeItem?=?hItem?'Item句柄 ?。牐爐v.pszText?=?hStr tv.cchTextMax?=?1023 ?。牐?#39;發(fā)送TVM_GETITEM獲得標題文本 ?。牐燙all?SendMessageRef(TreeView1.hwnd,?TVM_GETITEM,?0,?tv) '將標題文本拷貝到字符串astr中 CopyMemory?astr,?hStr,?1024 ?。牐燽str?=?Left$(astr,?(InStr(astr,?Chr(0))?-?1)) TreeView1.ToolTipText?=?bstr '釋放分配的內存空間 GlobalFree?hStr ?。燛nd?If Exit?Sub errLab: ?。燫esume?Next End?Sub
運行上面的程序,當光標在?TreeView1上面移動時,TreeView1的?ToolTips就會根據光標所在的不 同標題行而變動。
? SendMessage函數(shù)應用(三)? ??介紹關于RichTextBox(簡稱RTF)控件的消息和ListView控件的消息控制。
1.在Windows消息中,以EM_開頭的消息是專門控制TextBox類控件和RTF類控件的。下面介紹的是如何利 用?EM_?消息實現(xiàn)向?RichTextBox?中粘貼文本和位圖。在?EM_消息中,有一個?EM_PASTESPECIAL?消息 可以從剪貼板中獲取文本或者位圖類數(shù)據并拷貝到?RTF?上。 運行程序,點擊Command1,可以將剪貼板中的數(shù)據(位圖或者文本)拷貝到RichTextBox1上。 在?EM_PASTESPECIAL?消息中,wParam?定義剪貼板數(shù)據類型,lParam?定義一個?repastespecial 類型的數(shù)據,其中的?dwAspect?說明數(shù)據以何種方式顯示到?RTF?對象上,如果是?DVASPECT_CONTENT, 則將整個數(shù)據顯示在?RTF?上,如果是?DVASPECT_ICON?,則只在?RTF?上顯示一個圖標。 經試,repastespecial?格式沒有作用,因此參數(shù)4設為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ā)中重要的控件,典型的應用就是Windows資源管理器中的文件列
表。而在VB中,ListView控件包含在Microsoft?Windows?Common?Control?6.0(也可能是5.0,視你的
VB或者系統(tǒng)版本而定)中。在?Windows?API?中,有一系列的以?LVM_開頭的消息值,這些消息就是擴展
ListView控件所特定的消息值,下面的范例介紹如何通過LVM_消息設置ListView控件中圖標的間距。范
例如下:
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?消息來控制圖標間距。其中SendMessage中的參數(shù)lParam定義圖標間距,
高位為縱向間距,低位為橫向間距,在上面的范例中,我們將圖標的縱向間距定義為60像素,橫向間距
定義為190像素。
SendMessage函數(shù)的應用(四)?
?
1,獲得光標位置和字符個數(shù).
Cpos=SendMessage(text1.hwnd,187,-1,0)???'光標所在行的首字符在文本中的位置
Lpos=SendMessage(text1.hwnd,201,Cpos,0)?'光標所在的行號
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ù)據放在str中
text1.text?=?StrConv(str,vbUnicode)?'轉換為字符串后顯示
???
說明:在調用SendMessage獲取第N行字符串時,lParam需要說明為字節(jié)數(shù)組,在調用完成后,再將
字節(jié)數(shù)組轉換為字符串;另外,調用前必須在lParam的前兩個字節(jié)指明允許存放的最大長度,其中第一
個字節(jié)為低位,第二個字節(jié)為高位,本例將高位(即str(1))置1.說明最大允許存放256個字符。
3.開關顯示器.
SendMessage?Handle,?WM_SYSCOMMAND,?SC_MONITORPOWER,?0?'關閉顯示器.
SendMessage?Handle,?WM_SYSCOMMAND,?SC_MONITORPOWER,?-1?'打開顯示器
4.程序控制拉下或收起組合框的下拉列表
???一般情況下,為了拉下或收起組合框的下拉列表,需要用鍵盤或鼠標進行操作,而有時我們希望程
序運行的某個時刻自動拉出下拉列表(比如在一些演示程序中),為了實現(xiàn)這個目的,我們也只有借助
于SendMessage函數(shù),方法是發(fā)一個CB_SHOWDROPDOWN(&H14F)消息給組合框。
???在發(fā)CB_SHOWDROPDOWN消息時,wParam參數(shù)決定了是拉下列表(=True)還是收起表(=False),
lParam無用(設為0)。
???為說明具體的使用方法,下面提供簡單的程序片段:
Const?CB_SHOWDROPDOWN=&H14F
???當程序中某處需要拉下組合框Combol的列表時,調用如下語句:
SendMessage?Combol.hwnd,CB_SHOWDROPDOWN,True,0
???當需要收起組合框Combol的列表時,調用如下語句:
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ù):(經試,總是引起程序崩潰)
'獲取當前字體的矩形區(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???????????'字體的粗細輕重程度
??tmOverhang?As?Long?????????'加入某些拼接字體上的附加高度
??tmDigitizedAspectX?As?Long?'字體設計所針對的設備水平方向
??tmDigitizedAspectY?As?Long?'字體設計所針對的設備垂直方向
??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.設置控件的左邊距。?
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
運行后點擊按鈕,就可以把按鈕變成一個收音機按鈕(經試,變成一個圓孔,有點象單選按紐)。
如要得到圓形或橢圓形按紐可使用另外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?'關閉窗體
Public?Const?SC_MINIMIZE?=?&HF020?'最小化窗體
Public?Const?SC_MAXIMIZE?=?&HF030?'最大化窗體
Public?Const?SC_RESTORE?=?&HF120?'恢復窗體大小
Public?Const?WM_SETTEXT?=?&HC?'設置窗體的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)'設置窗體的Caption,由于Text1.text屬于Variant類型,所以一定先要用CStr把它轉換成字符串
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&'窗體恢復原來的大小
Case?5:?SendMessage?Me.hwnd,?WM_SYSCOMMAND,?SC_CLOSE,?ByVal?0&'關閉窗體
End?Select
End?Sub
11.文本垂直居中:
實現(xiàn)這個效果首先TextBox的MultiLine屬性必須為True(多行文本,其實這個屬性關系創(chuàng)建TextBox內部
使用哪個類,因此一旦創(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ū)域的邊界
???'進行位置數(shù)據計算
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ù)據計算完畢,再發(fā)送EM_SETRECTNP消息(為一個編輯控件設置格式化矩形,與EM_SETRECT類似,只是控件此時不會重畫)
Call?SendMessage(mText.hwnd,?EM_SETRECTNP,?0&,?rc)
mText.Refresh
End?Sub
12.調整邊距:
如果你查看TextBox中常用的消息,你會發(fā)現(xiàn)有這樣一對消息:EM_GETMARGINS?和?EM_SETMARGINS,MSDN的解
釋是:獲取和設置編輯控件的左、右邊距(不得用于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ù)應用(五)
RichEdit控件的正文操作
一、正文搜索
?????RichEdit?控件具有幾種正文操作,搜索指定正文就是其中的一種。搜索正文是通過發(fā)送
EM_FINDTEXT?或者?EM_FINDTEXTEX?消息來完成的。這兩個消息有一點很小的不同點。
1.EM_FINDTEXT
wParam=搜索選項,可以是下面3個參數(shù)的任意組合值(這些選項對?EM_FINDTEXT?和?EM_FINDTEXTEX
都是一樣的):
①FR_DOWN(&H1):搜索方向。如果指定了這個標志值,搜索操作從當前選定的?end?位置開始,直到控件
中正文的?end?位置結束(向下搜索)。這個標志影響?RichEdit?2.0?和以后版本,是?RichEdit?1.0
的缺省行為。RichEdit?2.0或以后版本的缺省行為是:在當前選定正文內的從結尾搜索到開始位置
(向前搜索)。概括來說就是,如果你使用?RichEdit?1.0,?無論你做什么都沒法影響搜索的方向,它
總使用向后搜索。但是如果你使用?RichEdit?2.0?而且你想使用向后搜索的話,你必須指定這個標
志值,否則使用的是向前搜索了。
②FR_MATCHCASE(&H4):區(qū)分大小寫。
③FR_WHOLEWORD(&H2):匹配指定搜索串的整個詞。
lParam?=?FINDTEXT?結構的指針。
Type?FINDTEXT????????'STRUCT
??chrg?As?CHARRANGE??'
??lpstrText?As?Long
End?Type
??chrg?是一個?CHARRANGE?結構,其定義如下:
Type?CHARRANGE???????'STRUCT
??cpMin?As?Long??????'包含字符數(shù)組中第一個字符的字符索引
??cpMax?As?Long??????'包含緊跟在字符數(shù)組中最后一個字符的字符的字符索引
End?Type?
基本上,要搜索一個正文串,你必須指定要搜索的字符范圍。cpMin?和?cpMax?的具體意義根據搜索是向
后還是向前是不同的。
如果是向后搜索,cpMin?指定搜索的開始字符索引,而?cpMax?則是結束字符索引。
如果是向前搜索,則反過來才對,也就是說?cpMin?包含結束字符索引而cpMax?包含開始字符索引。
??lpstrText?是要搜索的正文串的指針。
2.EM_FINDTEXTEX
返回控件中跟搜索串匹配的的正文串的一個字符的索引。如果沒找到匹配的則返回?-1。
??wParam?=?搜索選項,跟?EM_FINDTEXT?的一樣。
??lParam?=?FINDTEXTEX?結構的指針。
Type?FINDTEXTEX??????'STRUCT
??chrg?As?CHARRANGE??'
??lpstrText?As?Long?
??chrgText?CHARRANGE?'CHARRANGE
End?Type
??FINDTEXTEX?中開始的兩個成員是跟?FINDTEXT?結構中的一樣的。
??chrgText?是一個?CHARRANGE?結構,如果搜索到匹配串的話,其開始/結束字符索引會被填入這個結構中。
??EM_FINDTEXTEX?的返回值跟?EM_FINDTEXT的是一樣的。
??EM_FINDTEXT?跟?EM_FINDTEXTEX?的不同處:
FINDTEXTEX?結構有一個另外的chrgText成員,?如果搜索到匹配串的話,其開始/結束字符索引會被填入這個成
員中。如果我們想對這個正文串進行更多的正文操作的話,有這個就方便多了。
二、替換/插入正文
??RichEdit?控件提供了?EM_SETTEXTEX?來進行正文替換/插入操作。這個消息混合了?WM_SETTEXT?和
EM_REPLACESEL?的功能.?它具有以下語法:
??wParam?=?SETTEXTEX?結構的指針。
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?來編程選擇正文.其中任意的一個都可以工作的很好。
要使用哪一個消息要根據可用的字符索引格式來選擇。如果它們保存在一個?CHARRANGE?結構中,則使用
EM_EXSETSEL更容易實現(xiàn)。
??EM_EXSETSEL
??wParam?=?沒有使用,必須為?0?。
??lParam?=?CHARRANGE?結構的指針,包含想要選定的正文字符范圍。
四、事件通知
??在使用多行Edit控件時,你必須子類化它以便得到輸入信息象鼠標/鍵盤事件等。RichEdit?控件提供了一
個更好的方案,它可以把這些消息通知父窗口。為了注冊得到通知消息,父窗口發(fā)送?EM_SETEVENTMASK?消息
給?RichEdit?控件,指定它對哪些消息感興趣。?
EM_SETEVENTMASK?具有以下的語法:
wParam??沒有使用,必須為?0?。
lParam?=?事件掩碼值,可以是以下標志值的任意組合:
??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?或以后版本:?當鼠標在具有?CFE_LINK?風格的正文上面移過,而且執(zhí)行了一個
或幾個鼠標動作時,就發(fā)送?EN_LINK?通知。
??ENM_MOUSEEVENTS?為鼠標消息發(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?為鼠標滑輪發(fā)送?EN_MSGFILTER?通知。
??ENM_SELCHANGE?發(fā)送?EN_SELCHANGE?通知
??ENM_UPDATE?發(fā)送?EN_UPDATE?通知
??Rich?Edit?2.0?和以后版本:?這個標志值會被忽略,而經常發(fā)送?EN_UPDATE?通知。然而如果?RichEdit?
3.0?模擬?RichEdit?1.0的話,你必須使用這個標志值來發(fā)送?EN_UPDATE?通知
??上面的所有通知都被做為?WM_NOTIFY?消息來發(fā)送:你必須檢查?NMHDR?結構的?code?成員來得到通知消
息。譬如,如果你想注冊得到鼠標消息(也就是說,你想提供一給上下文相關的彈出菜單)
?
?
轉載于:https://www.cnblogs.com/zhaobl/p/3326332.html
總結
以上是生活随笔為你收集整理的SendMessage函数的常用消息及其应用大全的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工行信用卡激活需要多长时间?柜台激活比线
- 下一篇: 中信小白two联名卡面签流程及注意事项