当前位置:首页 > 技术 > 正文内容

SendMessage API 消息处理详解与实战应用

访客 技术 2026年7月17日 1

SendMessage 函数核心机制解析

在 Windows 编程中,SendMessage 是实现控件底层交互的核心函数。其声明如下:

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

参数说明

  • hwnd:目标控件的窗口句柄(Window Handle),用于标识要操作的具体控件。例如,在 VB 中可通过 TextBox1.hwnd 获取对应控件句柄。
  • wMsg:指定要发送的消息类型,如 EM_SETSEL 表示设置文本选择范围。
  • wParam:附加消息参数,根据具体消息类型决定用途,可为数值或标志位。
  • lParam:传递额外数据,类型定义为 Any 以支持多种数据格式,包括字符串、结构体或指针。

常见控件消息分类与用法

编辑框(TextBox / RichTextBox)消息

通过 EM_ 开头的消息可精确控制文本内容与显示行为。

  • EM_GETLINECOUNT:获取文本总行数
  • EM_GETSEL:获取当前选中文本的起始与结束位置(返回值低16位为起点,高16位为终点)
  • EM_REPLACESEL:用指定字符串替换选中文本,支持是否记录撤销操作
  • EM_SETSEL:设置光标位置或选定区域,常用于清空控件或追加内容
  • EM_FINDTEXT:在文本中搜索指定字符串,适用于动态筛选功能

列表框(ListBox)扩展功能

利用 LB_ 系列消息增强列表控件能力。

  • LB_FINDSTRING:从指定索引开始查找匹配项,返回匹配项索引
  • LB_ITEMFROMPOINT:获取鼠标当前位置对应的列表项索引,可用于实现悬浮提示
  • LB_SETHORIZONTALEXTENT:设置水平滚动条长度,解决长文本无法完整显示问题

组合框(ComboBox)控制

使用 CB_SHOWDROPDOWN 可程序化展开或收起下拉菜单:

SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, True, 0   ' 展开下拉列表
SendMessage Combo1.hwnd, CB_SHOWDROPDOWN, False, 0  ' 收起下拉列表

树形控件(TreeView)高级定制

通过 TVM_ 消息实现视觉与交互优化。

  • TVM_SETBKCOLOR:设置背景颜色,例如:SendMessage TreeView1.hwnd, TVM_SETBKCOLOR, 0, ByVal RGB(255, 0, 0)
  • TVM_HITTEST:检测鼠标位置是否落在某节点上,结合 TVM_GETITEM 可读取节点文本

富文本控件(RichTextBox)进阶操作

支持复杂文本处理与事件监听。

  • EM_PASTESPECIAL:从剪贴板粘贴位图或文本,适用于图文混合内容插入
  • EM_SETEVENTMASK:注册事件通知,如 ENM_SELCHANGE 监听选区变化
  • EM_EXSETSEL:以 CHARRANGE 结构精确设定选区,适合批量文本操作

窗口与系统级控制

实现对窗体及系统的直接干预。

  • WM_SYSCOMMAND:执行最小化、最大化、关闭等系统命令
  • WM_GETTEXT / WM_SETTEXT:获取或修改窗体标题
  • WM_CLOSE:模拟用户点击关闭按钮,关闭任意窗口
  • WM_MONITORPOWER:控制显示器电源状态,实现节能管理

典型应用场景示例

自动匹配输入(类似智能提示)

Private Sub TextBox1_KeyPress(KeyAscii As Integer)
    If KeyAscii >= 65 And KeyAscii <= 90 Or KeyAscii >= 97 And KeyAscii <= 122 Then
        Dim searchStr As String
        searchStr = searchStr + Chr(KeyAscii)
        Dim index As Long
        index = SendMessage(ListBox1.hwnd, LB_FINDSTRING, -1, ByVal searchStr)
        If index > -1 Then ListBox1.ListIndex = index
    End If
End Sub

动态添加水平滚动条

Private Function GetMaxTextWidth(lst As ListBox) As Long
    Dim hdc As Long
    Dim rect As RECT
    Dim maxWidth As Long
    hdc = lst.Parent.hdc
    For i = 0 To lst.ListCount - 1
        DrawText hdc, lst.List(i), -1, rect, DT_CALCRECT
        If (rect.Right - rect.Left) > maxWidth Then maxWidth = rect.Right - rect.Left
    Next
    GetMaxTextWidth = maxWidth + 10
End Function

Private Sub Form_Load()
    SendMessage List1.hwnd, LB_SETHORIZONTALEXTENT, GetMaxTextWidth(List1), 0
End Sub

实现垂直居中显示文本

Public Sub CenterTextInTextBox(txt As TextBox)
    Dim rc As RECT
    SendMessage txt.hwnd, EM_GETRECT, 0, rc
    With txt.Font
        .Name = txt.Font.Name
        .Size = txt.Font.Size
        .Bold = txt.Font.Bold
    End With
    Dim lineHeight As Long
    lineHeight = txt.Parent.TextHeight("H") \ Screen.TwipsPerPixelY
    Dim topOffset As Long
    topOffset = ((rc.Bottom - rc.Top) - lineHeight) \ 2
    rc.Top = rc.Top + topOffset
    rc.Bottom = rc.Bottom - topOffset
    SendMessage txt.hwnd, EM_SETRECTNP, 0, rc
    txt.Alignment = vbCenter
End Sub

注意事项与最佳实践

  • 参数类型处理:若传递字符串,必须使用 ByVal;若传递结构体或指针,则使用 Any 类型。
  • 内存管理:使用 GlobalAlloc 申请临时内存存储文本时,务必调用 GlobalFree 释放。
  • 错误处理:建议使用 On Error Resume Next 防止因无效句柄导致崩溃。
  • 兼容性限制:部分消息(如 EM_SETMARGINS)不适用于 NT 3.51 以下系统。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。