You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用EM_GETTEXTEX获取富编辑控件中选中的RTF文本?

获取RichTextBox选中RTF(含隐藏文本)的Win32 API方案

可行性确认

可以通过EM_GETTEXTEX消息实现需求。该消息支持指定文本范围、是否包含隐藏内容等参数,不受.NET Framework版本限制,能稳定获取选区中包含所有隐藏文本的RTF格式内容,替代在4.7+版本中不可靠的SelectedRtf属性。

VB.NET 实现代码

Imports System.Runtime.InteropServices

Public Class RichTextBoxRtfHelper
    ' Win32 常量定义
    Private Const EM_GETTEXTEX As Integer = &H44A
    Private Const GT_SELECTION As Integer = &H1
    Private Const GT_HIDDEN As Integer = &H8
    Private Const GT_USECRLF As Integer = &H2

    ' EM_GETTEXTEX 结构体
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
    Private Structure GETTEXTEX
        Public cb As Integer
        Public flags As Integer
        Public codepage As Integer
        Public lpDefaultChar As IntPtr
        Public lpUsedDefChar As IntPtr
    End Structure

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function

    ' 获取包含隐藏文本的选中RTF
    Public Shared Function GetSelectedRtfWithHidden(rtb As RichTextBox) As String
        If rtb.SelectionLength = 0 Then Return String.Empty

        ' 计算所需缓冲区大小
        Dim gte As New GETTEXTEX() With {
            .flags = GT_SELECTION Or GT_HIDDEN Or GT_USECRLF,
            .codepage = 1200 ' Unicode编码
        }
        Dim gtePtr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(gte))
        Marshal.StructureToPtr(gte, gtePtr, False)
        Dim bufferSize As Integer = SendMessage(rtb.Handle, EM_GETTEXTEX, gtePtr, IntPtr.Zero)
        Marshal.FreeHGlobal(gtePtr)

        If bufferSize <= 0 Then Return String.Empty

        ' 分配缓冲区并读取RTF内容
        Dim buffer As IntPtr = Marshal.AllocHGlobal(bufferSize * 2) ' Unicode字符占2字节
        gte.cb = bufferSize * 2
        gtePtr = Marshal.AllocHGlobal(Marshal.SizeOf(gte))
        Marshal.StructureToPtr(gte, gtePtr, False)

        SendMessage(rtb.Handle, EM_GETTEXTEX, gtePtr, buffer)
        Dim rtfContent As String = Marshal.PtrToStringUni(buffer)

        ' 释放内存资源
        Marshal.FreeHGlobal(buffer)
        Marshal.FreeHGlobal(gtePtr)

        Return rtfContent
    End Function
End Class

使用示例

在WinForms窗体中直接调用方法:

' 假设你的RichTextBox控件名为richTextBox1
Dim selectedRtf As String = RichTextBoxRtfHelper.GetSelectedRtfWithHidden(richTextBox1)

关键参数说明

  • GT_SELECTION:限定只获取当前选中的文本范围
  • GT_HIDDEN:强制包含选区中的所有隐藏文本,不受其在选区中的位置影响
  • codepage=1200:指定使用Unicode编码,确保RTF格式的完整性和正确性
  • 先获取缓冲区大小再分配内存,避免内存溢出或内容截断

内容的提问来源于stack exchange,提问作者Robert Gustafson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:46:27