在這一期的SendMessage函數應用中,我將向大家介紹如何利用消息函數來擴展樹型列表(TreeView)控件的功能相信對於樹型列表控件大家十分的熟悉,典型的應用就是Windows資源管理器中的目錄列表。在VB中,樹型列表控件包含在MicrosoftWindowsCommonControl6.0(也可能是5.0,視你的VB或者系統版本而定)中。在WindowsAPI中,有一系列的以TVM_開頭的消息值,這些消息就是擴展樹型列表控件所特定的消息值,下面向大家介紹其中的一些應用。
1、設置樹型列表控件的背景顏色
首先做如下的定義:
PrivateDeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLong
ConstTV-FIRST=&H1100
ConstTVM-SETBKCOLOR=TV_FIRST+29
然後再作如下調用:
CallSendMessage(TreeView1.hwnd,TVM-SETBKCOLOR,0,RGB(255,0,0))
上面的SendMessage調用將TreeView1的背景顏色設置為紅色。
大家可能注意到了。在上面的Sendmessage函數定義中,我們將lParam定義為ByVallParamAsLong,而不是象前面的那些范例那樣定義為Any或者String類型,關於這個問題,我會在最後的一章中做介紹。
2、設置樹型列表控件標題行高度
利用TVM_SETITEMHEIGHT消息可以設定控件的標題行的高度,該消息的定義及調用方法如下:
定義:
ConstTV_FIRST=&H1100
ConstTVM-SETITEMHEIGHT=TV_FIRST+27
PrivateDeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,lParamAsAny)AsLong
調用:
CallSendMessage(TreeView1.hwnd,TVM-SETITEMHEIGHT,60,0)
上面的代碼將TreeView1的標題行高度設置到60像素高
3、為樹型列表控件中不同的標題行設置不同的提示
在第一期的ListBox控件介紹中,我向大家介紹了如何為列表中的每一個標題行設置不同的提示(ToolTips),在這裡為要向大家介紹如何為樹型列表控件中的每一個標題設置不同的提示。
同ListBox控件不通,樹型列表控件中並沒有根據光標位置獲得標題行索引的消息,我們需要另外想辦法。在TVM類消息中有一個TVM_HITTEST消息,發送該消息可以檢測控件表面上的某一點,如果該點位於一個標題上,則返回該標題的句柄。而利用TVM_GETITEM消息,則可以根據標題句柄返回該標題行的文本。所以結合利用這兩個消息可以獲取光標所在標題行的標題文本。具體的范例代碼如下:
OptionExplicitPrivateTypeTPoint
xAsLong
yAsLong
EndType
PrivateTypeTVHITTESTINFO
ptAsTPoint
flagsAsLong
hItemAsLong
EndType
PrivateTypeTVITEM
maskAsLong
HTreeItemAsLong
stateAsLong
stateMaskAsLong
pszTextAsLong
cchTextMaxAsLong
iImageAsLong
iSelectedImageAsLong
cChildrenAsLong
lParamAsLong
EndType
ConstTV-FIRST=&H1100
ConstTVM_HITTEST=TV-FIRST+17
ConstTVM_GETITEM=TV-FIRST+12
ConstTVHT-ONITEMLABEL=&H4
ConstTVIF-TEXT=&H1
ConstGMEM-FIXED=&H0
PrivateDeclareFunctionSendMessageRefLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,lParamAsAny)AsLong
PrivateDeclareSubCopyMemoryLib"kernel32"Alias"RtlMoveMemory"(ByValDestinationAsString,ByValSourceAsLong,ByValLengthAsLong)
PrivateDeclareFunctionGlobalAllocLib"kernel32"(ByValwFlagsAsLong,ByValdwBytesAsLong)AsLong
PrivateDeclareFunctionGlobalFreeLib"kernel32"(ByValhMemAsLong)AsLong
DimhItemPrvAsLong
PrivateSubForm_Load()
DimndXAsNode
`加入若干Item
SetndX=TreeView1.Nodes.Add(,,"R","Root")
SetndX=TreeView1.Nodes.Add("R",tvwChild,"Key1","Node1")
SetndX=TreeView1.Nodes.Add("Key1",tvwChild,"SubKey1","SubNode1")
SetndX=TreeView1.Nodes.Add("SubKey1",tvwChild,"SubKeys1","SubNode1")
SetndX=TreeView1.Nodes.Add("Key1",tvwChild,"SubKey2","SubNode2")
SetndX=TreeView1.Nodes.Add("Key1",tvwChild,"SubKey3","SubNode3")
SetndX=TreeView1.Nodes.Add("Key1",tvwChild,"SubKey4","SubNode4")
EndSub
PrivateSubTreeView1_MouseMove(ButtonAsInteger,ShiftAsInteger,xAsSingle,yAsSingle)
DimptAAsTPoint
DimtfAsTVHITTESTINFO
DimtvAsTVITEM
DimhStrAsLong
DimhItemAsLong
DimastrAsString*1024
Dimbstr
OnErrorGoToerrLab
`獲得當前光標所在的位置坐標
ptA.x=Int(x/Screen.TwipsPerPixelX)
ptA.y=Int(y/Screen.TwipsPerPixelY)
tf.pt=ptA
tf.flags=TVHT_ONITEMLABEL
`獲得光標所在的Item的句柄
hItem=SendMessageRef(TreeView1.hwnd,TVM_HITTEST,0,tf)
`如果未獲得句柄或者同上一次是同一個Item的句柄則退出
If((hItem<=0)Or(hItem=hItemPrv))ThenExitSub
hItemPrv=hItem
`分配一定的內存空間用以存儲Item的標題
hStr=GlobalAlloc(GMEM-FIXED,1024)
IfhStr>0Then
tv.mask=TVIF_TEXT
`獲取標題文本
tv.HTreeItem=hItem
`Item句柄
tv.pszText=hStr
tv.cchTextMax=1023
`發送TVM_GETITEM獲得標題文本
CallSendMessageRef(TreeView1.hwnd,TVM-GETITEM,0,tv)
`將標題文本拷貝到字符串astr中
CopyMemoryastr,hStr,1024
bstr=Left$(astr,(InStr(astr,Chr(0))-1))
TreeView1.ToolTipText=bstr
`釋放分配的內存空間
GlobalFreehStr
EndIf
ExitSub
errLab:
ResumeNext
EndSub
運行上面的程序,當光標在TreeView1上面移動時,TreeView1的ToolTips就會根據光標所在的不同標題行而變動。
以上程序在Win98、Win2000,VB6下運行通過->