在这一期的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下运行通过->
|