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

RichEdit控件调用EM_POSFROMCHAR触发访问违例异常咨询

问题诱因

该异常是Rich Edit控件版本兼容逻辑的文档误导、系统二进制实现偏差共同导致的,核心原因有三点:

  • 类名不代表实际控件版本:GetClassName()返回RichEdit20W仅能说明创建控件时使用了2.0版本对应的类名字符串,从Windows XP开始系统自带的riched20.dll已经全部是3.0及以上版本的实现,仅保留RichEdit20A/W类名注册做向下兼容,不存在独立的2.0版本二进制运行逻辑。
  • 文档描述的自动兼容检测逻辑存在严重缺陷:所谓“检测到wParam不是有效POINTL指针就自动切换为2.0调用语法”的逻辑,在绝大多数系统版本的实现中仅做了wParam != NULL的判断,不会校验指针指向的内存是否可写、是否为合法的用户态地址。你传入的wParam值为0x69,属于非零值,控件直接将其识别为POINTL结构指针,尝试向该地址写入坐标数据,直接触发访问违例。
  • 64位环境下参数匹配偏差:如果你在x64架构下编译程序,将字符索引强转为WPARAM传入、lParam传0的写法,完全匹配3.0版本EM_POSFROMCHAR的参数格式,控件根本不会进入兼容判断分支,直接按3.0规则解析参数。
修复方式

不要依赖不可靠的自动版本兼容逻辑,采用全版本兼容的写法调用即可:

POINTL pt = {0};
// 所有版本的Rich Edit都支持3.0格式的EM_POSFROMCHAR调用
SendMessage(hrichedit, EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)pos);
// 坐标直接从pt结构中读取,无需依赖消息返回值

如果确实需要使用2.0版本的调用语法,必须先发送EM_GETRICHEDITVERSION消息获取控件真实版本号,确认版本为2.0及以下时再使用对应参数格式。

你观察到的反汇编向0x0000000000000069地址写入的行为,完全符合3.0版本的参数解析逻辑,也佐证了控件并没有进入你预期的2.0兼容分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:06:47