我在存儲爲html的DHtml組件中記錄了數據庫中的註釋。但我想將格式更改爲RTF,並使用DevExpress TcxRichEdit來代替,因爲我覺得這是一個更簡單的組件,更穩定等。用戶在消除文本方面存在問題,我當然無法重現。將HTML轉換爲RTF
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;
它實際上是的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;
不,它是GetBusy返回true ...
function TProfDHTMLEdit2.GetBusy: Boolean;
begin
if FDocumentCompleteReason <> dcrUndefined then
Result := True
else
Result := False
end;
所以我試圖挖的更深depper 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組件添加到表單中,而不是在代碼中創建它。這樣繁忙的財產是錯誤的,它只是起作用。不需要在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;
感謝您對我的問題的支持和承諾!
是的,它是一個約700個需要轉換爲RTF格式的html字符串。有點無聊,做手動.... – 2011-03-26 06:33:36
而且它不是在用戶機器上。它位於連接了許多用戶的服務器上。因此,當版本與新的Richedit組件一起更改時,我運行一個在數據庫中執行轉換的maintanance方法。之後,用戶可以登錄。 – 2011-03-26 06:49:37
@羅蘭,你試過我的建議嗎?它看起來像你必須擺脫停止方法,只是等待(如建議),直到組件不再忙碌 – jachguate 2011-03-26 06:55:43