请问如何在自己的程序中调用OFFICE软件的文档转换器?(200分)

  • 主题发起人 lighttop
  • 开始时间
L

lighttop

Unregistered / Unconfirmed
GUEST, unregistred user!
请问如何在自己的程序中调用OFFICE软件的文档转换器? <br>(注意:不是通过OLE控制WORD来实现转换)<br><br>比如把WORD文档转换成RTF文档等.
 
看看VBA中是否有相关函数,然后就可以调用了
 
如果使用VBA,就要在后台启动WORD, 这样速度就很慢,而且大量占用资源.<br>我看到一个"文档管理助手"软件(作者:吴联民) &nbsp;, 它的导入功能好象调用了OFFICE带<br>的转换程序,而不需要启动任何一个OFFICE程序, 速度很快.<br>
 
安装office后文本转换单元在<br>C:/Program Files/Common Files/Microsoft Shared/TextConv<br>图形转换单元在C:/Program Files/Common Files/Microsoft Shared/Grphflt<br>其中Doc-&gt;rtf使用TextConv下的MsWord832.cnv<br>导入Html使用html32.cnv<br>导入excel表格使用Excel32.cnv<br>这些个路径在注册表下有说明<br>HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Shared Tools/Text Converters<br>HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Shared Tools/Graphics Filters<br>下面是使用转换器的单元<br>unit Converters;<br><br>{ -----------------------------------------------------------------------------}<br>{ Unit: Converters &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ Purpose: import and export to Office known formats &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ Required: the TRichEdit98. See enclosed zip. This demo could also use &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; an imported RICHTX32.OCX, but you'll have to modify the form for &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this to work. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Authors: Fred Jansma, Paul te Bokkel &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Incontrol Business Engineers &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ -----------------------------------------------------------------------------}<br><br>{ Copyright (c) 1998 Paul te Bokkel &amp; Fred Jansma, Incontrol Business Engineers}<br><br>{ This program is free software; you can redistribute it and/or &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ modify it under the terms of the GNU General Public License &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ as published by the Free Software Foundation; either version 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ of the License, or (at your option) any later version. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br><br>{ This program is distributed in the hope that it will be useful, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ but WITHOUT ANY WARRANTY; without even the implied warranty of &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. &nbsp;See the &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ GNU General Public License for more details. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br><br>{ You should have received a copy of the GNU General Public License &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ along with this program; if not, write to the Free Software &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA &nbsp;02111-1307, USA. &nbsp;}<br><br><br>interface<br><br>uses<br>&nbsp; Registry, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, FileCtrl, OleCtrls, ComCtrls, ExtCtrls, AxCtrls, RichEdit2;<br><br>// -----------------------------------------------------------------<br>// Functions to call when you want to convert something<br>// -----------------------------------------------------------------<br><br>// Function to import a file to a WideString.<br>function ImportAsRTF(FileName: String; Converter: String; rtbApp: TRichEdit98): Boolean;<br><br>// Function to export RTF to a file.<br>function ExportRTF(FileName: String; Converter: String; rtbApp: TRichEdit98): Boolean;<br><br>// -----------------------------------------------------------------<br>// Functions to call if you want to know what can be converted<br>// -----------------------------------------------------------------<br><br>// Function to build a filter list, with available import and export converters.<br>function BuildFilterList(ForImport: Boolean): string;<br><br>// Function to build a list with available conveters.<br>function BuildConverterList(ForImport: Boolean; StrLst: TStringList): Boolean;<br><br>// -----------------------------------------------------------------<br>// Supportive functions - not to be called direct, unless you<br>// know what you are doing<br>// -----------------------------------------------------------------<br><br>// Initialize the selected converter.<br>function LoadConverter(Description: string; Import: boolean): HWND;<br><br>// Check if current file is of right format.<br>function IsKnownFormat(FileName: string): Boolean;<br><br>// Convert string to HGLOBAL.<br>function StringToHGLOBAL(const str: string): HGLOBAL;<br><br>// Procedure to free the converters.<br>procedure DoFreeConverters;<br><br>// Function to obtain the directory of WordPad. Not needed to be public, but maybe<br>// someone is looking for it.<br>function WordPadDir: string;<br><br>// Callback functions for reading and writing.<br>function Reading(CCH, nPercentComplete: integer): Integer; stdcall;<br>function Writing(flags, nPercentComplete: integer): Integer; stdcall;<br><br><br>implementation<br><br>type<br>&nbsp; // Our functions to convert the RTF-format to a foreign format, or a foreign format to the RTF-format.<br>&nbsp; // These functions are hidden in the converters.<br>&nbsp; RTF_CALLBACK = function(CCH, nPercentComplete: integer): Integer; stdcall;<br>&nbsp; TInitConverter = function(ParentWin: THandle; ParentAppName: LPCSTR): integer; stdcall;<br>&nbsp; TIsFormatCorrect = function(FileName, Desc: HGLOBAL): integer; stdcall;<br>&nbsp; TForeignToRtf = function(FileName: HGLOBAL; void: pointer{LPSTORAGE}; Buf, Desc, Subset: HGLOBAL; Callback: RTF_CALLBACK): integer; stdcall;<br>&nbsp; TRtfToForeign = function(FileName: HGLOBAL; void: pointer{LPSTORAGE}; Buf, Desc: HGLOBAL; Callback: RTF_CALLBACK): integer; stdcall;<br><br>var<br>&nbsp; CurrentConverter: HWND;<br>&nbsp; InitConverter: TInitConverter = nil;<br>&nbsp; IsFormatCorrect: TIsFormatCorrect = nil;<br>&nbsp; ForeignToRtf: TForeignToRtf = nil;<br>&nbsp; RtfToForeign: TRtfToForeign = nil;<br>&nbsp; hBuf: HGLOBAL;<br>&nbsp; bytesRead: integer = 0;<br>&nbsp; WritePos: integer = 0; // in Char, not WChar<br>&nbsp; WriteMax: integer = 0; // in Char, not WChar<br>&nbsp; RTFToWrite: string;<br>&nbsp; mstream: TMemorystream = nil;<br><br>const<br>&nbsp; nBufSize: integer = 4096;<br>&nbsp; MSTextConvKey = 'SOFTWARE/Microsoft/Shared Tools/Text Converters/';<br><br><br>function ImportAsRTF(FileName: String; Converter: String; rtbApp: TRichEdit98): Boolean;<br>var<br>&nbsp; // Variables used for the actual conversion.<br>&nbsp; hSubset,<br>&nbsp; hFileName,<br>&nbsp; hDesc: HGLOBAL;<br>&nbsp; res: integer;<br>begin<br>&nbsp; Result := False; // We are very pessimistic.<br>&nbsp; try<br>&nbsp; &nbsp; if LoadConverter(Converter, True) &lt;&gt; 0 then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // Check selected file format.<br>&nbsp; &nbsp; &nbsp; &nbsp; if IsKnownFormat(FileName) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // prepare parameters<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hSubset := StringToHGLOBAL('');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hDesc := StringToHGLOBAL('');<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hFileName := StringToHGLOBAL(FileName);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hBuf := GlobalAlloc(GHND, nBufSize + 1);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Screen.Cursor := crHourGlass;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mstream := TMemoryStream.Create;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mstream.SetSize(512 * 1024); // initial: 512 kB, seems reasonable.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Assigned(ForeignToRtf) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res := ForeignToRtf(hFileName, nil, hBuf, hDesc, hSubset, Reading)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res := -1; // no valid entry point for DLL<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if res = 0 then // Don't know any other states. Might be boolean.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mstream.SetSize(mstream.Position); // shrink to right size<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mstream.Position := 0;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rtbApp.Lines.LoadFromStream(mStream);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mStream.Free;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := True;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hBuf);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hFileName);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hDesc);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hSubset);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Screen.Cursor := crDefault;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowMessage('Not the correct file format');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; except<br>&nbsp; &nbsp; Result := False;<br>&nbsp; end;<br>end;<br><br><br>function ExportRTF(FileName: String; Converter: String; rtbApp: TRichEdit98): Boolean;<br>var<br>&nbsp; hSubset,<br>&nbsp; hFileName,<br>&nbsp; hDesc: HGLOBAL;<br>&nbsp; res: integer;<br>&nbsp; iSelStart, iSelLength: Integer;<br>begin<br>&nbsp; if LoadConverter(Converter, False) &lt;&gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if not (Assigned(InitConverter)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and LongBool(InitConverter(Application.Handle, PChar(Uppercase(Application.ExeName))))) then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowMessage('Please report: InitConverter failed');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; hSubset := StringToHGLOBAL('');<br>&nbsp; &nbsp; &nbsp; hDesc := StringToHGLOBAL('');<br>&nbsp; &nbsp; &nbsp; hFileName := StringToHGLOBAL(FileName);<br>&nbsp; &nbsp; &nbsp; hBuf := GlobalAlloc(GHND, nBufSize + 1);<br><br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; Screen.Cursor := crHourGlass;<br>&nbsp; &nbsp; &nbsp; &nbsp; WritePos := 0;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; if Assigned(RtfToForeign) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iSelStart := rtbApp.SelStart;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iSelLength := rtbApp.SelLength;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rtbApp.SelectAll; // This is done quick-and-dirty, but at the moment it works.<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RTFToWrite := rtbApp.RTFSelText;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rtbApp.SelStart := iSelStart;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rtbApp.SelLength := iSelLength;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteMax := length(RTFToWrite);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res := RtfToForeign(hFileName, nil, hBuf, hDesc, Writing);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RTFToWrite := '';<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if res = 0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := True<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowMessage('Coult not export document');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hBuf);<br>&nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hFileName);<br>&nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hDesc);<br>&nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hSubset);<br>&nbsp; &nbsp; &nbsp; &nbsp; Screen.Cursor := crDefault;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; Result := False;<br>end;<br><br><br>// Try to obtain the WordPad directory.<br>function WordPadDir: string;<br>var<br>&nbsp; reg: TRegistry;<br>begin<br>&nbsp; reg := TRegistry.Create;<br><br>&nbsp; with reg do<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RootKey := HKEY_LOCAL_MACHINE;<br><br>&nbsp; &nbsp; &nbsp; Result := '';<br><br>&nbsp; &nbsp; &nbsp; if OpenKey('/SOFTWARE/Microsoft/Windows/CurrentVersion/App Paths/WORDPAD.EXE', False) then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := ReadString('');<br><br>&nbsp; &nbsp; &nbsp; Result := ExtractFilePath(Result); // leaves the trailing backslash intact<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; Free;<br>&nbsp; &nbsp; end;<br>end;<br><br><br>// The function "BuildFilterList" creates a string, that we can use as a filterlist<br>// in the dialog.<br>function BuildFilterList(ForImport: Boolean): string;<br>const<br>&nbsp; saImEx: array[False..True] of string = ('Export', 'Import');<br>var<br>&nbsp; regTxtConv: TRegistry;<br>&nbsp; regConvEntry: TRegistry;<br>&nbsp; slEntries: TStringList;<br>&nbsp; x,<br>&nbsp; i: integer;<br>&nbsp; extensions: string;<br>begin<br>&nbsp; regTxtConv := TRegistry.Create;<br>&nbsp; regConvEntry := TRegistry.Create;<br>&nbsp; slEntries := TStringList.Create;<br>&nbsp; Result := '';<br><br>&nbsp; with regTxtConv do<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RootKey := HKEY_LOCAL_MACHINE;<br>&nbsp; &nbsp; &nbsp; if OpenKey(MSTextConvKey + saImEx[ForImport], False) then<br>&nbsp; &nbsp; &nbsp; &nbsp; GetKeyNames(slEntries);<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; CloseKey;<br>&nbsp; &nbsp; &nbsp; Free;<br>&nbsp; &nbsp; end;<br><br>&nbsp; regConvEntry.RootKey := HKEY_LOCAL_MACHINE;<br>&nbsp; try<br>&nbsp; &nbsp; for i := 0 to slEntries.Count-1 do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if regConvEntry.OpenKey(MSTextConvKey + saImEx[ForImport] + '/' + slEntries, false) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; extensions := '*.' + regConvEntry.ReadString('Extensions');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x := pos(' ', extensions);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while x &gt; 0 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete(extensions, x, 1);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; insert(';*.', extensions, x);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x := pos(' ', extensions);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := Result + regConvEntry.ReadString('Name') + '|' + extensions + '|';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // catch a faulty key mismatch<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; regConvEntry.CloseKey;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; regConvEntry.Free;<br>&nbsp; &nbsp; slEntries.Free;<br>&nbsp; end;<br><br>&nbsp; // We can always im/export RTF, but there is no (trivial) converter for,<br>&nbsp; // but we do want to show it...<br>&nbsp; Result := 'Rich Text Format|*.rtf|' + Result;<br><br>&nbsp; // Since the WordPad converters are identically to the Office converters,<br>&nbsp; // we test if WordPad is installed and if so, if we did find Word and/or<br>&nbsp; // Write format. If not, add them.<br>&nbsp; // NB: these are valid for both im- and export.<br>&nbsp; if WordPadDir &lt;&gt; '' then<br>&nbsp; begin<br>&nbsp; &nbsp; if (pos('Windows Write', Result) = 0) and<br>&nbsp; &nbsp; &nbsp; &nbsp;(FileExists(WordPadDir + 'write32.wpc')) then<br>&nbsp; &nbsp; &nbsp; Result := 'Windows Write|*.wri|' + Result;<br>&nbsp; &nbsp; if FileExists(WordPadDir + 'mswd6_32.wpc') then // do we have W6 converter?<br>&nbsp; &nbsp; &nbsp; if (pos('Word 6.0/95', Result) = 0) then<br>&nbsp; &nbsp; &nbsp; &nbsp; // no office converter for W6, add Wordpad as default converter<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := 'Word 6.0/95|*.doc|' + Result<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; // Since Office converter seems buggy, add Wordpad converter as default<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := 'Word 95 via WordPad|*.doc|' + Result;<br>&nbsp; end;<br><br>&nbsp; if (Result &lt;&gt; '') and (Result[Length(Result)] = '|') then<br>&nbsp; &nbsp; Delete(Result, Length(Result), 1); // strip trailing |<br>end;<br><br><br>// The function "BuildConverterList" creates a stringlist, in which all available<br>// converters are stored.<br>function BuildConverterList(ForImport: Boolean; StrLst: TStringList): Boolean;<br>const<br>&nbsp; saImEx: array[False..True] of string = ('Export', 'Import');<br>var<br>&nbsp; regTxtConv: TRegistry;<br>&nbsp; regConvEntry: TRegistry;<br>&nbsp; slEntries: TStringList;<br>&nbsp; i: integer;<br>begin<br>&nbsp; if not Assigned(StrLst) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; &nbsp; Exit; // StrLst must be initialized.<br>&nbsp; &nbsp; end;<br><br>&nbsp; regTxtConv := TRegistry.Create;<br>&nbsp; regConvEntry := TRegistry.Create;<br>&nbsp; slEntries := TStringList.Create;<br><br>&nbsp; try<br>&nbsp; &nbsp; with regTxtConv do<br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; RootKey := HKEY_LOCAL_MACHINE;<br>&nbsp; &nbsp; &nbsp; &nbsp; if OpenKey(MSTextConvKey + saImEx[ForImport], False) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetKeyNames(slEntries);<br>&nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; CloseKey;<br>&nbsp; &nbsp; &nbsp; &nbsp; Free;<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; regConvEntry.RootKey := HKEY_LOCAL_MACHINE;<br><br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; for i := 0 to slEntries.Count-1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if regConvEntry.OpenKey(MSTextConvKey + saImEx[ForImport] + '/' + slEntries, False) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StrLst.Add(regConvEntry.ReadString('Name'));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // catch a faulty key mismatch<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; regConvEntry.CloseKey;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; regConvEntry.Free;<br>&nbsp; &nbsp; &nbsp; slEntries.Free;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; // We can always im/export RTF, but there is no (trivial) converter for,<br>&nbsp; &nbsp; // but we do want to show it...<br>&nbsp; &nbsp; StrLst.Insert(0, 'Rich Text Format');<br><br>&nbsp; &nbsp; // Since the WordPad converters are identically to the Office converters,<br>&nbsp; &nbsp; // we test if WordPad is installed and if so, if we did find Word and/or<br>&nbsp; &nbsp; // Write format. If not, add them.<br>&nbsp; &nbsp; // NB: these are valid for both im- and export.<br>&nbsp; &nbsp; if WordPadDir &lt;&gt; '' then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if (pos('Windows Write', StrLst.Text) = 0) and<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(FileExists(WordPadDir + 'write32.wpc')) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;StrLst.Insert(0, 'Windows Write');<br>&nbsp; &nbsp; &nbsp; &nbsp; if FileExists(WordPadDir + 'mswd6_32.wpc') then // do we have W6 converter?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (pos('Word 6.0/95', StrLst.Text) = 0) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // no office converter for W6, add Wordpad as default converter<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StrLst.Insert(0, 'Word 6.0/95')<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Since Office converter seems buggy, add Wordpad converter as default<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StrLst.Insert(0, 'Word 95 via WordPad');<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; Result := True;<br>&nbsp; except<br>&nbsp; &nbsp; Result := False;<br>&nbsp; end;<br>end;<br><br><br>// The function "LoadConverter" loads a specific converter.<br>// We set the converter-functions as well.<br>function LoadConverter(Description: string; Import: boolean): HWND;<br>const<br>&nbsp; saImEx: array[false..true] of string = ('Export', 'Import');<br>var<br>&nbsp; regTxtConv: TRegistry;<br>&nbsp; regConvEntry: TRegistry;<br>&nbsp; slEntries: TStringList;<br>&nbsp; i: integer;<br>&nbsp; ConverterDLL: string;<br>begin<br>&nbsp; regTxtConv := TRegistry.Create;<br>&nbsp; regConvEntry := TRegistry.Create;<br><br>&nbsp; slEntries := TStringList.Create;<br><br>&nbsp; Result := 0;<br>&nbsp; ConverterDLL := '';<br><br>&nbsp; with regTxtConv do<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RootKey := HKEY_LOCAL_MACHINE;<br>&nbsp; &nbsp; &nbsp; if OpenKey(MSTextConvKey + saImEx[Import], false) then<br>&nbsp; &nbsp; &nbsp; &nbsp; GetKeyNames(slEntries);<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; CloseKey;<br>&nbsp; &nbsp; &nbsp; Free;<br>&nbsp; &nbsp; end;<br><br>&nbsp; regConvEntry.RootKey := HKEY_LOCAL_MACHINE;<br><br>&nbsp; try<br>&nbsp; &nbsp; for i := 0 to slEntries.Count - 1 do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; regConvEntry.OpenKey(MSTextConvKey + saImEx[Import] + '/' + slEntries, False);<br>&nbsp; &nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if regConvEntry.ReadString('Name') = Description then // we've found our dll<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ConverterDLL := regConvEntry.ReadString('Path'); // get dll-location &amp; name<br>&nbsp; &nbsp; &nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // catch a faulty key mismatch to be able to continue<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; regConvEntry.CloseKey;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; regConvEntry.Free;<br>&nbsp; &nbsp; slEntries.Free;<br>&nbsp; end;<br><br>&nbsp; if ConverterDLL = '' then // It could be a Wordpad provided converter<br>&nbsp; begin<br>&nbsp; &nbsp; if pos('Word 6.0/95', Description) &gt; 0 then<br>&nbsp; &nbsp; &nbsp; ConverterDLL := WordPadDir + 'mswd6_32.wpc'<br>&nbsp; &nbsp; else if pos('Windows Write', Description) &gt; 0 then<br>&nbsp; &nbsp; &nbsp; ConverterDLL := WordPadDir + 'write32.wpc'<br>&nbsp; &nbsp; else if pos('WordPad', Description) &gt; 0 then<br>&nbsp; &nbsp; &nbsp; ConverterDLL := WordPadDir + 'mswd6_32.wpc';<br>&nbsp; end;<br><br>&nbsp; if ConverterDLL &lt;&gt; '' then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if CurrentConverter &lt;&gt; 0 then // Unload the current loaded converter.<br>&nbsp; &nbsp; &nbsp; &nbsp; FreeLibrary(CurrentConverter);<br><br>&nbsp; &nbsp; &nbsp; Result := LoadLibrary(PChar(ConverterDLL)); // Load the new converter.<br><br>&nbsp; &nbsp; &nbsp; if Result &lt;&gt; 0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CurrentConverter := Result; // Try to initialize our functions.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @InitConverter := GetProcAddress(Result, 'InitConverter32');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @IsFormatCorrect := GetProcAddress(Result, 'IsFormatCorrect32');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @ForeignToRtf := GetProcAddress(Result, 'ForeignToRtf32');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @RtfToForeign := GetProcAddress(Result, 'RtfToForeign32');<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br><br>&nbsp; if Result = 0 then<br>&nbsp; &nbsp; begin // On failure, reset...<br>&nbsp; &nbsp; &nbsp; @InitConverter := nil;<br>&nbsp; &nbsp; &nbsp; @IsFormatCorrect := nil;<br>&nbsp; &nbsp; &nbsp; @ForeignToRtf := nil;<br>&nbsp; &nbsp; &nbsp; @RtfToForeign := nil;<br>&nbsp; &nbsp; end;<br>end;<br><br><br>// The function "StringToHGlobal" converts a string in HGLOBAL.<br>function StringToHGLOBAL(const str: string): HGLOBAL;<br>var<br>&nbsp; new: PChar;<br>begin<br>&nbsp; Result := GlobalAlloc(GHND, Length(str) * 2 + 1);<br><br>&nbsp; new := GlobalLock(Result);<br><br>&nbsp; if new &lt;&gt; nil then<br>&nbsp; &nbsp; strcopy(new, PChar(str));<br><br>&nbsp; GlobalUnlock(Result);<br>end;<br><br><br>// The function "IsKnownFormat" is used to check if a selected file<br>// matches a converter-type.<br>function IsKnownFormat(FileName: string): Boolean;<br>var<br>&nbsp; hFileName,<br>&nbsp; hDesc: HGLOBAL;<br>begin<br>&nbsp; Result := False;<br><br>&nbsp; if not (Assigned(InitConverter)<br>&nbsp; &nbsp; &nbsp;and LongBool(InitConverter(Application.Handle, PChar(Uppercase(Application.ExeName))))) then<br>&nbsp; &nbsp; ShowMessage('Please report: InitConverter failed') // Question only is: report to who?<br>&nbsp; else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; hFileName := StringToHGLOBAL(FileName);<br>&nbsp; &nbsp; &nbsp; hDesc := StringToHGLOBAL('');<br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; if Assigned(IsFormatCorrect) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := LongBool(IsFormatCorrect(hFileName, hDesc)); // hDesc gets like 'MSWord6'<br>&nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hDesc);<br>&nbsp; &nbsp; &nbsp; &nbsp; GlobalFree(hFileName);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>end;<br><br><br>// The function "Reading" is used by the converter-DLL's.<br>// It is used to import a foreign format to the RTF-format.<br>function Reading(CCH, nPercentComplete: integer): Integer; stdcall;<br>var<br>&nbsp; tempBuf: PChar;<br>begin<br>&nbsp; tempBuf := GlobalLock(hBuf);<br><br>&nbsp; if CCH &gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if mstream.Position + CCH &gt;= mstream.Size then // enlarge stream<br>&nbsp; &nbsp; &nbsp; &nbsp; mstream.SetSize(mstream.size + (mstream.size div 4)); // by .25<br>&nbsp; &nbsp; &nbsp; mstream.Write(tempBuf^, CCH);<br>&nbsp; &nbsp; end;<br><br>&nbsp; GlobalUnlock(hBuf);<br><br>&nbsp; inc(BytesRead, CCH);<br><br>&nbsp; Result := 0; // everything OK<br>end;<br><br><br>// The function "Writing" is used by the converter-DLL's.<br>// It is used to export the RTF-format to a foreign format.<br>function Writing(flags, nPercentComplete: integer): Integer; stdcall;<br>var<br>&nbsp; tempBuf: PChar;<br>begin<br>&nbsp; tempBuf := GlobalLock(hBuf);<br><br>&nbsp; if tempBuf = nil then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Result := -8; // out of memory?<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br><br>&nbsp; if writePos &lt; writeMax then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if (writeMax - writePos) &lt; nBufSize then<br>&nbsp; &nbsp; &nbsp; &nbsp; bytesRead := writeMax - writePos<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; bytesRead := nBufSize;<br><br>&nbsp; &nbsp; &nbsp; move(RTFToWrite[WritePos+1], tempBuf^, bytesRead);<br><br>&nbsp; &nbsp; &nbsp; inc(writePos, bytesRead);<br>&nbsp; &nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; bytesRead := 0;<br><br>&nbsp; GlobalUnlock(hBuf);<br>&nbsp; Result := bytesRead;<br>end;<br><br><br>procedure DoFreeConverters;<br>begin<br>&nbsp; if CurrentConverter &lt;&gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; FreeLibrary(CurrentConverter);<br>&nbsp; &nbsp; &nbsp; CurrentConverter := 0;<br>&nbsp; &nbsp; end;<br>end;<br><br>initialization<br><br>finalization<br>&nbsp; DoFreeConverters;<br><br>end.<br>具体的用法,有点大了,留个地址吧,sorry<br>
 
to jlutt-sadan:<br>&nbsp; 请问能发一份给我吗? Email:xzuse@szonline.net<br>谢谢!<br>
 
接受答案了.
 
to jlutt-sadan:<br>&nbsp; &nbsp;终于找到你了.:)<br>&nbsp; 这几天正为word与html之间的转换发愁呢.能否帮小弟一把呀,把单元Converters的具体用法发给我一份?先谢了.Email:real200180@sina.com
 
顶部