SendMessage

简介:

在这一期的SendMessage函数应用中,我将向大家介绍如何利用消息函数来扩展树型列表(TreeView)控件的功能相信对于树型列表控件大家十分的熟悉,典型的应用就是Windows资源管理器中的目录列表。在VB中,树型列表控件包含在Microsoft Windows Common Control 6.0(也可能是5.0,视你的VB或者系统版本而定)中。在Windows API中,有一系列的以TVM_ 开头的消息值,这些消息就是扩展树型列表控件所特定的消息值,下面向大家介绍其中的一些应用。

1、设置树型列表控件的背景颜色

首先做如下的定义:

Private Declare Function SendMessage Lib "user32" Alias "Send MessageA" (ByVal hwnd As Long,ByVal wMsg As Long, ByVal wParam As Long,ByVal lParam As Long) As Long
Const TV-FIRST = &H1100
Const TVM-SETBKCOLOR = TV_FIRST + 29


然后再作如下调用:

Call SendMessage(TreeView1.hwnd, TVM-SETBKCOLOR, 0, RGB(255, 0, 0))


上面的SendMessage调用将TreeView1的背景颜色设置为红色。

大家可能注意到了。在上面的Sendmessage函数定义中,我们将lParam定义为 ByVal lParam As Long,而不是象前面的那些范例那样定义为Any或者String类型,关于这个问题,我会在最后的一章中做介绍。

2、设置树型列表控件标题行高度

利用TVM_SETITEMHEIGHT消息可以设定控件的标题行的高度,该消息的定义及调用方法如下:

定义:

 Const TV_FIRST = &H1100
Const TVM-SETITEMHEIGHT = TV_FIRST + 27
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

  
调用:

CallSendMessage(TreeView1.hwnd, TVM-SETITEMHEIGHT, 60, 0)


上面的代码将TreeView1的标题行高度设置到60像素高

3、为树型列表控件中不同的标题行设置不同的提示

在第一期的ListBox控件介绍中,我向大家介绍了如何为列表中的每一个标题行设置不同的提示(ToolTips),在这里为要向大家介绍如何为树型列表控件中的每一个标题设置不同的提示。

同ListBox控件不通,树型列表控件中并没有根据光标位置获得标题行索引的消息,我们需要另外想办法。在TVM类消息中有一个TVM_HITTEST消息,发送该消息可以检测控件表面上的某一点,如果该点位于一个标题上,则返回该标题的句柄。而利用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 Send MessageRef 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
'获得当前光标所在的位置坐标
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)) Then Exit Sub
hItemPrv = hItem
'分配一定的内存空间用以存储Item的标题
hStr = GlobalAlloc(GMEM-FIXED, 1024)
If hStr > 0 Then
tv.mask = TVIF_TEXT 
'获取标题文本
tv.HTreeItem = hItem
'Item句柄
tv.pszText = hStr
tv.cchTextMax = 1023
'发送TVM_GETITEM获得标题文本
CallSendMessageRef(TreeView1.hwnd, TVM-GETITEM, 0, tv)
'将标题文本拷贝到字符串astr中
CopyMemory astr, hStr, 1024
bstr = Left$(astr, (InStr(astr, Chr(0)) - 1))
TreeView1.ToolTipText = bstr
'释放分配的内存空间
GlobalFree hStr
End If
Exit Sub
errLab:
Resume Next
End Sub

  运行上面的程序,当光标在TreeView1上面移动时,TreeView1的ToolTips就会根据光标所在的不同标题行而变动。

本文转自kenty博客园博客,原文链接http://www.cnblogs.com/kentyshang/archive/2006/05/29/411764.html如需转载请自行联系原作者


kenty

相关文章
|
8天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
3691 16
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
16天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3604 13
|
10天前
|
人工智能 自然语言处理 供应链
|
12天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
2997 7
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
19天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
3729 25
|
10天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全+三种模式+记忆体系+实战工作流完整手册
Claude Code 是当前最流行的终端级 AI 编程助手,能够直接在命令行中完成代码生成、项目理解、文件修改、命令执行、错误修复等全流程开发工作。它不依赖图形界面、不占用额外资源,却能深度理解项目结构,自动生成规范代码,大幅提升研发效率。
1471 3
|
3天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
502 0
|
17天前
|
存储 Linux iOS开发
【2026最新】MarkText中文版Markdown编辑器使用图解(附安装包)
MarkText是一款免费开源、跨平台的Markdown编辑器,主打所见即所得实时预览,支持Windows/macOS/Linux。内置数学公式、流程图、代码高亮、多主题及PDF/HTML导出,是Typora的轻量免费替代首选。(239字)