gpt4 book ai didi

html - 将 HTML 转换为 RTF

转载 作者:可可西里 更新时间:2023-11-01 12:53:23 25 4
gpt4 key购买 nike

我在数据库中使用 DHtml 组件将注释存储为 html。但我想将格式更改为 RTF 并改为使用 DevExpress TcxRichEdit,因为我觉得这是一个更简单的组件,更稳定等。用户遇到了我当然无法复制的消失文本的问题。

TcxRichEdit 工作正常,可以再次保存和加载笔记。问题是 html 格式的旧注释。我试过this routine但我从来没有让它工作。生成了一个 rtf 字符串,但 TcxRichEdit 不接受它。

然后我有了使用剪贴板的想法。通过并排放置 DHtml 和 TcxRichEdit,我应该在它们之间进行复制和粘贴,让剪贴板进行实际转换。实际上并没有我想象的那么简单......

这是一些代码:

  function _ConvertToRtf(aHtml: String; aRichEdit: TcxRichEdit): Boolean;
begin
Result := False;
if (aHtml <> '') and (aHtml <> '&nbsp;') then
begin
if not AnsiStartsStr('{\rtf1', aHtml) then
begin
vHtmlDlg.InitDoc := aHtml;
vHtmlDlg.Editor.Stop;
if vHtmlDlg.Editor.SelectAll then
if vHtmlDlg.Editor.CutToClipboard then
begin
aRichEdit.Clear;
aRichEdit.PasteFromClipboard;
end;
end;

Result := True;
end;
end;

问题是 vHtmlDlg.Editor.SelectAll 总是返回 False。

function TCustomProfDHTMLEdit.SelectAll: Boolean;
const
CGID_MSHTML: TGUID = '{DE4BA900-59CA-11CF-9592-444553540000}';
var
D: IDispatch;
CommandTarget: IOleCommandTarget;
vaIn, vaOut: OleVariant;
hr: HRESULT;
begin
Result := False;
if GetDOM(D) then
try
CommandTarget := D as IOleCommandTarget;
hr := CommandTarget.Exec(@CGID_MSHTML, 31, OLECMDEXECOPT_DODEFAULT, vaIn, vaOut);
Result := SUCCEEDED(hr)
except
end
end;

返回False的其实是GetDOM:

function TProfDHTMLEdit2.GetDOM(out P: IDispatch): Boolean;
begin
if Busy then
begin
P := nil;
Result := False
end
else
try
P := (IDispatch(GetOleObject) as IWebBrowser2).Document;
Result := True
except
P := nil;
Result := False
end
end;

不,返回 true 的是 GetBusy...

function TProfDHTMLEdit2.GetBusy: Boolean;
begin
if FDocumentCompleteReason <> dcrUndefined then
Result := True
else
Result := False
end;

所以我已经尝试在 html 组件中进行更深入的挖掘,但我仍然不明白为什么我不能使用 SelectAll。

这是我如何初始化和使用它的简化版本。

  vHtmlDlg := TDhtmlEditorForm.Create(nil);
vHtmlDlg.Show;
vHtmlDlg.BrowseMode := False;
try
// Call ConvertToRtf with strings in a loop here
finally
vHtmlDlg.Free;
end;

知道为什么 SelectAll 返回 false 并且不起作用吗?

编辑1: 还有一件事。 html 组件的文档在此处 http://www.profgrid.com/documentation/htmledit/停止命令似乎停止将 HTML 页面加载到控件中。我偶然使用了它,因为在另一个地方它可以防止在以 html 加载数据时发生锁定。无论如何,获得转换并摆脱 HTML 组件真的很棒!

编辑2:我终于找到了解决方案,而且非常简单。只需在设计时将 Dhtml 组件添加到表单中,而不是在代码中创建它。这样, busy 属性是错误的,它就可以正常工作。无需在 while 循环中检查忙,因为这是在 SetSource 方法中完成的。我给jachquate复选标记,因为他注意到我的组件是异步的。转换字符串的最终代码如下所示:

  function _ConvertToRtf(aHtml: String; aRichEdit: TcxRichEdit): Integer;
begin
if (aHtml <> '') and (aHtml <> '&nbsp;') then
begin
if not AnsiStartsStr('{\rtf1', aHtml) then
begin
DhtmlMemo.Source := aHtml;
if DhtmlMemo.SelectAll then
if DhtmlMemo.CutToClipboard then
begin
aRichEdit.Clear;
aRichEdit.PasteFromClipboard;
end;

if VarIsNull(aRichEdit.EditValue) then
Result := 0 // Not valid. The caller would delete the note.
else
Result := 2; // String was converted
end
else
Result := 1; // String already in rtf. Do nothing.
end
else
Result := 0;
end;

感谢您对我的问题的支持和 promise !

最佳答案

由于这是一次性转换,因此我同意您使用剪贴板。

HTML 组件看起来像一种Async 组件,因此您必须等待,因为它会在其他线程中处理加载/表示提供的 HTML,所有这些都由组件封装。我不知 Prop 体的组件,但我敢打赌这会起作用:

  function _ConvertToRtf(aHtml: String; aRichEdit: TcxRichEdit): Boolean;
begin
Result := False;
if (aHtml <> '') and (aHtml <> '&nbsp;') then
begin
if not AnsiStartsStr('{\rtf1', aHtml) then
begin
vHtmlDlg.InitDoc := aHtml;
vHtmlDlg.Editor.Stop;
//before or after stop, I'm not sure what stop means
while vHtmlDlg.Busy do
Sleep(1); // or maybe Application.ProcessMessages, try both
if vHtmlDlg.Editor.SelectAll then
if vHtmlDlg.Editor.CutToClipboard then
begin
aRichEdit.Clear;
aRichEdit.PasteFromClipboard;
Result := True; //of course you return true only if this succeeds.
end;
end;
end;
end;

如果这是要在用户计算机上完成的多次转换,请阅读 @Chris answer .

关于html - 将 HTML 转换为 RTF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5433881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com