⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 word_97_faq.htm

📁 一个好的word的控件
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html>

<head>
<title>How to Use Word 97 as a Report Engine</title>
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<meta name="Microsoft Border" content="none">
</head>

<body bgcolor="#FFFFCC">

<p align="center"><font color="#804040"><strong><em><big><big><big>Word 97 Frequently
Asked Questions</big></big></big></em></strong></font></p>

<p><font color="#804040">Last updated 22 August 1999</font></p>

<p><a href="#Delphi_5_Components">Delphi 5 comes with the Word objects as components -
surely your classes are no longer needed?</a></p>

<p><a href="#Class_Not_Registered">Project Demo.exe raised exception class EOleSysError
with message 'Class not registered'. Process stopped. Use Step or Run to continue.</a></p>

<p><a href="#Word_TLB.dcu">[Fatal Error] Word97.pas(29): File not found: 'Word_TLB.dcu' or
'Word97.pas'</a></p>

<p><a href="#Application_">[Error] Word97.pas(267): Undeclared identifier: 'Application_'<br>
[Error] Word97.pas(271): Undeclared identifier: 'CoApplication_'</a></p>

<p><a href="#Word8">Where is the Borland demo version of Word97?</a></p>

<p><a href="#Delphi_Version">Which versions of Delphi can use these classes?</a></p>

<p><a href="#C++Builder">Is there a C++ Builder version of these classes?</a></p>

<p><a href="#Early_Binding">Why use early binding?</a></p>

<p><a href="#Late_Binding">I'm odd - I would like to use late binding. How to I get a
handle on Word?</a></p>

<p><a href="#EmptyParam">Delphi 3 has no EmptyParam, how can I survive?</a></p>

<p><a href="#Bloatware">Why is Word slow to load and eats vast amounts of memory?</a></p>

<p><a href="#Faster_Automation">Automating Word is faster if I drop down a Word menu
&#151; How can I get this speed advantage in code?</a></p>

<p><a href="#Report_Advice">I want to use Word to produce xxx, what is the best way to do
this?</a></p>

<p><a href="#TOleContainer">How do I use Word inside the TOleContainer object?</a></p>

<p><a href="#RedefineFileNew">I want to re-define what Word does for x menu item (e.g.,
FileNew)</a></p>

<p><a href="#Macros">I want to convert my Word macros/VBA code to Delphi as Delphi is
compiled and therefor fast</a></p>

<p><a href="#Outside_Links">Where can I get more information on Word automation and Delphi
COM in general?</a></p>

<p><strong><a name="Delphi_5_Components"></a><font color="#804040">Delphi 5 comes with the
Word objects as components - surely your classes are no longer needed?</font></strong></p>

<p><font color="#000000">Delphi 5 wraps the automation classes up into a set of 5
components (TWordApplication, TWordDocument, TWordFont, TWordLetterContent,
TWordParagraphFormat). These components publish a standard set of OleServer properties and
expose specific properties and methods as a public interface. The events are also specific
to the object. The advantages of these new components over the existing classes are:</font>

<ol>
  <li>They expose the component's events as easily as any other component - this has to be the
    main advantage</li>
  <li>They make it easy to connect to an existing server or create a new one</li>
  <li>They connect using early binding</li>
  <li>By using method overloading, they provide a way to make OLE default parameters easy to
    code</li>
</ol>

<p>The components also have a number of down sides: 

<ol>
  <li>There is no point that I can see to having any object other than the TWordApplication as
    a component as almost all users create the document object at runtime. I cannot see any
    use for the other three components. They seem to be have been created because the code
    generator found them</li>
  <li>By using method overloading, they have made the import libraries huge - they are now
    about 180% of what they were in Delphi 4. Although this is an attractive way to make
    optional parameters easy to code for, the alternative way (to actually use Delphi's
    optional parameters) is neater. However, you cannot make OleVariants optional (see next
    problem)</li>
  <li>They continue to use OleVariant for almost all parameters. This is a difficult to use
    type as you cannot substitute its value with a constant and you cannot give it a default
    value for optional parameters. My classes get round this by using standard Delphi types
    for the method parameters and converting them in code to OleVariants. This makes the code
    insight features more intuitive and makes optional parameters simpler to code.</li>
  <li>The events exposed by Word are inconsistent and incomplete and the classes do nothing to
    help with this. My classes go some way toward making the events useable.</li>
</ol>

<p><strong><a name="Class_Not_Registered"></a><font color="#804040">Project Demo.exe
raised exception class EOleSysError with message 'Class not registered'. Process stopped.
Use Step or Run to continue.</font></strong></p>
<div align="left">

<table border="0" cellpadding="0" cellspacing="0" width="75%"
style="background-color: rgb(255,255,255); border: thin groove rgb(192,192,192); margin: 0; padding: 0">
  <tr>
    <td width="100%"><code>class function CoGlobal.Create: _Global;</code></td>
  </tr>
  <tr>
    <td width="100%"><code>begin</code></td>
  </tr>
  <tr>
    <td width="100%" bgcolor="#000080"><font color="#FFFFFF"><code>&nbsp; Result :=
    CreateComObject(CLASS_Global) as _Global;</code></font></td>
  </tr>
  <tr>
    <td width="100%"><code>end;</code></td>
  </tr>
</table>
</div>

<p><font color="#000000"><br>
This is not a bug in the demo. The Global class is registered when any instance of Word is
present. If an exception occurs when trying to refer to the class, this implies that there
is no active Word present and the creator method will have to create a new one. While an
exception is raised when you run the code within Delphi, the exception will be silent in a
free-standing program.</font></p>

<p><font color="#000000">I have updated the constructor to use a different means of
getting the active application object. This uses </font>GetActiveObject and checks its
return value to see if it succeeds (most examples of using this function wrap it up in
OleCheck&#151;all this procedure does is raise an appropriate exception if the function
result indicates failure). I check for a specific error (no application object present)
and deal with that by creating a new instance. Note that I still use OleCheck to cope with
any other errors that I have not coded for. My demo should now run without any exceptions.
Note that I now get the application object from &quot;GetActiveObject&quot; rather than
from the Global object. In a senario where several instance of Word are in existance, this
may not return the same instance of Word as before (haven't checked as it is of no
relevance to me - may be important to you). Let me know if this is a problem.</p>

<p>&nbsp;</p>

<p><a name="Word_TLB.dcu"></a><strong><font color="#804040">[Fatal Error] Word97.pas(29):
File not found: 'Word_TLB.dcu' or Word97.pas'</font></strong></p>

<p>I don't provide Word_TLB.pas for two reasons:</p>

<p>1. It is huge - 859k when created by Delphi 4 and 699k when created by Delphi 3<br>
2. It is Delphi version specific<br>
3. You can easily roll-your-own:<br>
&nbsp;&nbsp;&nbsp; In Delphi choose File_Open<br>
&nbsp;&nbsp;&nbsp; Select Files of Type &quot;Type Library&quot; and open the file
&quot;C:\Program Files\Microsoft Office\Office\Msword8.olb&quot;<br>
&nbsp;&nbsp;&nbsp; Make sure &quot;$(DELPHI)\Imports&quot; is in your Library path.<br>
&nbsp;&nbsp;&nbsp; If you own Delphi 3, you will need to make a small fix to the pascal
file - see the <a href="#Application_">FAQ on &quot;Application_&quot;</a></p>

<p>NB Delphi 5 imports the library as C:\Program
Files\Borland\Delphi5\Ocx\Servers\Word97.pas<br>
This is rather annoying and means I have had to change my unit to AHDelphi97.pas</p>

<p>&nbsp;</p>

<p><a name="Application_"></a><font color="#804040"><strong>[Error] Word97.pas(267):
Undeclared identifier: 'Application_'<br>
[Error] Word97.pas(271): Undeclared identifier: 'CoApplication_'</strong></font></p>

<p align="left">This occurs with Delphi 3 and is due to the way it creates the
Word_TLB.pas file.</p>

<p align="left">With COM objects, when you refer to an object, property or method, you are
just refering to an GUID class ID (i.e., a big number). The actual name used is not
important. You can change the names of entities in the type library pascal file and still
use it (provided you refer to the new name in your code). This is similar to aliases for
DLL imports. When Delphi imports a type library and writes out the pascal file, it alters
quite a few of the objects names because of conflicts with its &quot;reserved names&quot;.
You will see this at the start of the file:</p>

<p align="left"><code>{ Conversion log:<br>
&nbsp; Warning: 'Object' is a reserved word. Parameter 'Object' in
_Application.IsObjectValid changed to 'Object_'<br>
&nbsp; ...</code></p>

<p align="left">Reserved words have been part of pascal from the beginning. They are
fundamental names used in pascal that should not be used as identifiers to avoid confusion
with the original pascal meaning. Since pascal is strictly typed, it won't allow you to
reuse these special words (unlike C++). Delphi 3 does a fairly good job at removing these
conflicts when it imports type libraries (Microsoft's type libraries are full of
&quot;reserved words&quot;). However there is one object that was not a renamed because it
was not a reserved word in Delphi 3. The object is of course &quot;Application&quot;.
Application is an object in the Forms.pas file. VCL object names were not considered
important enough for reserving/renaming, even one as fundamental as Application - if you
think you have never used it, you have not looked - you will find it in all your project
files (*.dpr):</p>

<p align="left"><code>begin<br>
&nbsp; Application.Initialize;<br>
&nbsp; Application.CreateForm(TfrmDemo, frmDemo);<br>
&nbsp; Application.Run;<br>
end.</code></p>

<p align="left">Now, if you were to compile a program that &quot;used&quot; Word_TLB.pas,
when the compiler gets to Application it may look in Word_TLB.pas first and complain at
the lack of an Initialize method.The application object is also used elsewhere in the VCL
and can be of use in your own code (e.g. to get the EXEname). You can specify which file
to look in for an object by prefixing it with the unit name (e.g., Forms.Application or
Word_TLB.Application). This is fine for your own code, but a hassle for the autocreated
code in the dpr and you shouldn't change code in the VCL.</p>

<p align="left">When Delphi 4 came along, Borland realised that this was a problem and
made &quot;Application&quot; a reserved word in the eyes of the type library. Thus the
Delphi 4 version of Word_TLB.pas uses &quot;Application_&quot; instead of
&quot;Application&quot;. NB do not confuse either with &quot;_Application&quot;.</p>

<p align="left">The solution to all this is to edit Word_TLB.pas. Now Delphi warns you
that any edits to a type library pascal file will be overwritten if you re-import the type
library. However, since the Word 97 type library will never change, you will never need to
re-import it. The changes you should make are:</p>
<div align="left">

<table border="0" cellpadding="0" width="100%">
  <tr>
    <td width="17%"><strong><span style="font-family: sans-serif">Line number</span></strong></td>
    <td width="41%"><strong><span style="font-family: sans-serif">Original line</span></strong></td>
    <td width="42%"><strong><span style="font-family: sans-serif">New line</span></strong></td>
  </tr>
  <tr>
    <td width="17%"><small><code>3059</code></small></td>
    <td width="41%"><small><code>Application = _Application;</code></small></td>
    <td width="42%"><small><code>Application_ = _Application;</code></small></td>
  </tr>
  <tr>
    <td width="17%"><small><code>many - do a search</code></small></td>
    <td width="41%"><small><code>function Get_Application: Application; safecall;</code></small></td>
    <td width="42%"><small><code>function Get_Application_: Application_; safecall;</code></small></td>
  </tr>
  <tr>
    <td width="17%"><small><code>many - do a search</code></small></td>
    <td width="41%"><small><code>property Application: Application read Get_Application;</code></small></td>
    <td width="42%"><small><code>property Application_: Application_ read Get_Application_;</code></small></td>
  </tr>
  <tr>
    <td width="17%"><small><code>many - do a search</code></small></td>
    <td width="41%"><small><code>property Application: Application readonly dispid 1000;</code></small></td>
    <td width="42%"><small><code>property Application_: Application_ readonly dispid 1000;</code></small></td>
  </tr>
  <tr>
    <td width="17%"><small><code>14663</code></small></td>
    <td width="41%"><small><code>CoApplication = class</code></small></td>
    <td width="42%"><small><code>CoApplication_ = class</code></small></td>
  </tr>
  <tr>
    <td width="17%"><small><code>14709</code></small></td>
    <td width="41%"><small><code>class function CoApplication.Create: _Application;</code></small></td>
    <td width="42%"><small><code>class function CoApplication_.Create: _Application;</code></small></td>
  </tr>
  <tr>
    <td width="17%"><small><code>14714</code></small></td>
    <td width="41%"><small><code>class function CoApplication.CreateRemote(const MachineName:
    string): _Application;</code></small></td>
    <td width="42%"><small><code>class function CoApplication_.CreateRemote(const MachineName:
    string): _Application;</code></small></td>
  </tr>
</table>
</div>

<p align="left">Note, the line numbers are for my copy of Word_TLB.pas produced by Delphi
3. They will probably be the same for you (but MS/Delphi service packs may alter this).</p>

<p align="left">NB Delphi 5 changes these again and refers to WordApplication,
WordDocument, etc..</p>

<p align="left">&nbsp;</p>

<p align="left"><a name="Word8"></a><font color="#804040"><strong>Where is the Borland
demo version of Word97?</strong></font></p>

<p>If you installed Delphi in the default directory, you should find it at:</p>

<p>C:\Program Files\Borland\Delphi4\Demos\Activex\Oleauto\Word8\Word97.pas</p>

<p>or</p>

<p>C:\Program Files\Borland\Delphi5\Demos\Activex\Oleauto\Word8\AutoImpl.pas</p>

<p>&nbsp;</p>

<p><a name="C++Builder"></a><font color="#804040"><strong>Is there a C++ Builder version
of these classes?</strong></font></p>

<p>No. I don't own C++ Builder and have little C++ experience. I presume you could use the
compiled unit in a version compatible with Delphi 4. I could send this unit to anyone who
want to try it and doesn't have Delphi 4. I know there are some compatibility issued with
sharing units but have no time/desire to find out. Jacques Mainville asked this question
but the return e-mail address bounced -this is why you have not received a reply!</p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -