【发布时间】:2018-12-23 21:05:58
【问题描述】:
我在数据库中使用 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 <> ' ') 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/ stop 命令似乎停止将 HTML 页面加载到控件中。我偶然使用过,因为在另一个地方它可以防止在 html 中加载数据时发生锁定。无论如何,获得转换并摆脱 HTML 组件真是太好了!
编辑2: 我终于找到了解决方案,而且很简单。只需在设计时将 Dhtml 组件添加到表单中,而不是在代码中创建它。这样,busy 属性是错误的,它可以正常工作。无需在 while 循环中检查忙,因为这是在 SetSource 方法中完成的。我给jachquate 打勾,因为他告诉我该组件是异步的。转换字符串的最终代码如下所示:
function _ConvertToRtf(aHtml: String; aRichEdit: TcxRichEdit): Integer;
begin
if (aHtml <> '') and (aHtml <> ' ') 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;
感谢您对我的问题的支持和承诺!
【问题讨论】: