Delphi 64位将rtf流插入richedit

syqv5f0l  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(124)

我尝试在richedit中插入一个rtf(特别是保存在数据库中的rtf,然后在选择点处插入到当前richedit控件中)。
下面的代码以32位工作。但无法使其在64位工作,即使通过阅读其他语言在谷歌不同的答复。
我想我有些型号的尺寸不对。
已经谢谢你帮我了。
版本 Delphi 10.4(但我不认为这是相关的)

type
  TEditStreamCallBack = function(dwCookie: Longint; pbBuff: PByte;  
    cb: Longint; var pcb: Longint): DWORD;  
  stdcall;

  TEditStream = record
    dwCookie: Longint;
    dwError: Longint;
    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; pBuff: Pointer; cb: LongInt; pcb: PLongInt): DWORD; stdcall;
begin
  Result := $0000;  // assume no error
  try
    pcb^ := TStream(dwCookie).Read(pBuff^, cb); // read data from stream
  except
    Result := $FFFF;  // indicates error to calling routine
  end;
end;

class procedure TpRichEditUtils.RTFInsertStream(const ARichEdit : TRichEdit; const AStream: TStream);
var
  EditStream: TEditStream;  // callback used to read inserted RTF
begin
  ARichEdit.Lines.BeginUpdate;
  try
    // Make sure rich edit is large enough to take inserted code
    ARichEdit.MaxLength := ARichEdit.MaxLength + AStream.Size;
    // Stream in the RTF via EM_STREAMIN message
    EditStream.dwCookie := DWORD(AStream);
    EditStream.dwError := $0000;
    EditStream.pfnCallback := @EditStreamReader;
    ARichEdit.Perform(
      EM_STREAMIN,
      SFF_SELECTION or SF_RTF or SFF_PLAINRTF, LPARAM(@EditStream)
    );
    // Report any errors as a bug
    if EditStream.dwError <> $0000 then
      raise Exception.Create('RTFInsertStream: Error inserting stream');
  finally
    ARichEdit.Lines.EndUpdate;
  end;
end;

OStream := TStringStream.Create(ODmRemarqueStandard.REMSTD_TEXTE);
try
  TpRichEditUtils.RTFInsertStream(TcxRichInnerEdit(EdtConditionGenerale.InnerControl), OStream);
finally
  FreeAndNil(OStream)
end;

我试着修改了dwCookie:Longint到DWORD_PTR。并尝试了其他方法,但总是访问冲突。

0g0grzrc

0g0grzrc1#

您的TEditStreamCallBackEditStreamReader声明不匹配。
此外,您在32位和64位构建中都将cookie作为32位整数处理,这是错误的。在32位构建中,它需要是32位整数,在64位构建中,它需要是64位整数。Win32 API将cookie声明为DWORD_PTR,正是为了达到这个目的。
TEditStreamCallBackTEditStream已经在Winapi.RichEdit单元中声明,您不需要在自己的代码中手动声明它们。
试试这个:

uses
  Winapi.RichEdit, SysUtils;

function EditStreamReader(dwCookie: DWORD_PTR; pbBuff: PByte; cb: Longint; var pcb: Longint): Longint; stdcall;
begin
  Result := 0;  // assume no error
  try
    pcb := TStream(dwCookie).Read(pBuff^, cb); // read data from stream
  except
    Result := -1;  // indicates error to calling routine
  end;
end;

class procedure TpRichEditUtils.RTFInsertStream(const ARichEdit : TRichEdit; const AStream: TStream);
var
  EditStream: TEditStream;  // callback used to read inserted RTF
begin
  ARichEdit.Lines.BeginUpdate;
  try
    // Make sure rich edit is large enough to take inserted code
    ARichEdit.MaxLength := ARichEdit.MaxLength + AStream.Size;
    // Stream in the RTF via EM_STREAMIN message
    EditStream.dwCookie := DWORD_PTR(AStream);
    EditStream.dwError := 0;
    EditStream.pfnCallback := @EditStreamReader;
    ARichEdit.Perform(
      EM_STREAMIN,
      SFF_SELECTION or SF_RTF or SFF_PLAINRTF,
      LPARAM(@EditStream)
    );
    // Report any errors as a bug
    if EditStream.dwError <> 0 then
      raise Exception.Create('RTFInsertStream: Error inserting stream');
  finally
    ARichEdit.Lines.EndUpdate;
  end;
end;

相关问题