Delphi 64位环境下RTF流插入RichEdit控件失败求助
解决Delphi 10.4 64位下RichEdit插入RTF流的访问违例问题
问题根源是自定义的TEditStream结构和回调函数参数类型与64位Windows API定义不匹配:32位环境下指针和Longint都是4字节,不会截断;但64位下指针是8字节,用4字节类型存储会导致指针截断,触发访问违例。以下是修正后的完整代码:
修正后的代码
type // 严格匹配Windows API的EDITSTREAMCALLBACK定义,64位下dwCookie为指针大小 TEditStreamCallBack = function(dwCookie: DWORD_PTR; pbBuff: PByte; cb: DWORD; var pcb: DWORD): DWORD; stdcall; // 对齐Windows原生EDITSTREAM结构 TEditStream = record dwCookie: DWORD_PTR; dwError: DWORD; pfnCallback: TEditStreamCallBack; end; TpRichEditUtils = class public class procedure RTFInsertStream(const ARichEdit : TRichEdit; const AStream: TStream); end; implementation uses Winapi.RichEdit, SysUtils; function EditStreamReader(dwCookie: DWORD_PTR; pbBuff: PByte; cb: DWORD; var pcb: DWORD): DWORD; stdcall; begin Result := 0; // 默认无错误 try // 64位下DWORD_PTR可完整存储TStream指针,避免截断 pcb := TStream(dwCookie).Read(pbBuff^, cb); except Result := $FFFF; // 向调用方报告错误 end; end; class procedure TpRichEditUtils.RTFInsertStream(const ARichEdit : TRichEdit; const AStream: TStream); var EditStream: TEditStream; StreamPos: Int64; begin ARichEdit.Lines.BeginUpdate; try // 保存流当前位置,操作完成后恢复 StreamPos := AStream.Position; AStream.Position := 0; // 调整RichEdit最大长度以容纳插入内容 ARichEdit.MaxLength := ARichEdit.MaxLength + AStream.Size; // 初始化流回调结构 EditStream.dwCookie := DWORD_PTR(AStream); EditStream.dwError := 0; EditStream.pfnCallback := @EditStreamReader; // 发送EM_STREAMIN消息,将RTF插入选中位置 ARichEdit.Perform( EM_STREAMIN, SFF_SELECTION or SF_RTF or SFF_PLAINRTF, LPARAM(@EditStream) ); if EditStream.dwError <> 0 then raise Exception.CreateFmt('插入RTF流出错,错误码: %d', [EditStream.dwError]); finally AStream.Position := StreamPos; ARichEdit.Lines.EndUpdate; end; end; // 调用示例 var OStream: TStringStream; begin OStream := TStringStream.Create(ODmRemarqueStandard.REMSTD_TEXTE); try TpRichEditUtils.RTFInsertStream(TcxRichInnerEdit(EdtConditionGenerale.InnerControl), OStream); finally FreeAndNil(OStream) end; end;
核心修改说明
- 类型对齐:将
TEditStream的dwCookie改为DWORD_PTR(64位下占8字节,可完整存储指针),dwError改为DWORD,与Windows原生结构完全一致。 - 回调参数修正:回调函数的
cb、pcb参数改为DWORD,dwCookie改为DWORD_PTR,彻底避免类型转换时的指针截断。 - 流状态保护:新增保存/恢复流位置的逻辑,防止操作后流位置被修改影响后续使用。
- 错误信息优化:通过格式化输出错误码,便于问题排查。
内容的提问来源于stack exchange,提问作者Michael Desboeufs
相关产品推荐
相关产品推荐

