📄 word_97_faq.htm
字号:
<p> </p>
<p><a name="Delphi_Version"></a><font color="#804040"><strong>Which versions of Delphi can
use these classes?</strong></font></p>
<p>The classes were developed in Delphi 4. <a href="mailto:MQamar@usa.net">Quamar Ali</a>
has converted the original Word97 for Delphi 3. As new features have been added, I have
tried to keep the Delphi 3 up-to-date. However, I no longer have Delphi 3 installed. All I
can do is check that the code compiles in Delphi 4, using the Delphi 3 type library.
Delphi 4 has lots of nice extras that make working with COM objects easier - especially
default/optional parameters. Quamar Ali removed the event sink from the Delphi 3 version.
I have no way of knowing if you can use event sinking in Delphi 3 - I suspect not. If
someone wants to copy the code over and try - be my guest.</p>
<p>Delphi 1 and 2 are not able to use these classes.</p>
<p>I have just made the classes Delphi 5 compatible.</p>
<p> </p>
<p><a name="Early_Binding"></a><strong><font color="#804040">Why use early binding?</font></strong></p>
<p>There are several reasons why early binding has not taken off with Word:
<ol>
<li>Many are still put off by the difficulties they had with type libraries from Delphi 3 </li>
<li>Word's objects make great use of optional parameters. Early binding forbids their use.
Borland were not very forthcoming with a method for passing 'null' optional parameters in
Delphi 3 (see Appendix 1) and didn't exactly advertise the existence of the EmptyParam
'constant' in Delphi 4. </li>
<li>Many arguments are enumerate types (TOleEnum). You need to constantly look these up in
Word VBA help. </li>
<li>Far too many arguments are of type OleVariant. These require that you pass a variable of
OleVarient type, i.e., you cannot do something like Selection.MoveLeft(wdWord, 1, wdMove)
as these arguments are constants, not OleVariants. </li>
<li>Code for getting the current word application using late binding was frequently give in
the OleAutomation newsgroups (see Appendix 2). This is useful; otherwise you end up with
loads of copies of word. </li>
</ol>
<p>Here are a few reasons why early binding is better:
<ol>
<li>We all know it is faster (although Word is d*** slow so you may not notice - see <a
href="#Bloatware">Why is Word slow to load and eats vast amounts of memory?</a>).</li>
<li>It is language independent (more of a problem with Word versions before '97).</li>
<li>You get tool tips to show you all 11 parameters required to do ActiveDocument.SaveAs
(…) </li>
<li>You are guaranteed to get a Word 97 object. If you use
CreateOLEObject('Word.Application') then you may get an error if an older version of word
is present as there was no Application object then (you would have used Word.WordBasic).
You may still get this error if you have both Word 97 and a previous version installed on
the same machine. This is very important if you application is distributed to unknown
machines (with goodness knows what on them). </li>
<li>You can interface with the events generated from Word (for what it's worth).</li>
<li>Late binding is for script interpreters - you bought Delphi because you're a grown-up
and can handle the raw speed, why use crayons to write your masterpiece?</li>
</ol>
<p> </p>
<p><a name="Late_Binding"></a><font color="#804040"><strong>I'm odd - I would like to use
late binding. How to I get a handle on Word?</strong></font></p>
<p>Use the following code: </p>
<blockquote>
<p><tt>var</tt> <br>
<tt> wrdApp : OleVariant;</tt> <br>
<tt>begin</tt> <br>
<tt> try</tt> <br>
<tt> wrdApp := GetActiveOLEObject('Word.Application');</tt> <br>
<tt> except on EOleSysError do</tt> <br>
<tt> wrdApp := CreateOLEObject('Word.Application');</tt> <br>
<tt> end;</tt></p>
<p> </p>
</blockquote>
<p><a name="EmptyParam"></a><font color="#804040"><strong>Delphi 3 has no EmptyParam, how
can I survive?</strong></font></p>
<p>To roll your own EmptyParam for Delphi 3, declare the following as a global variable in
a unit: </p>
<blockquote>
<p><tt>var</tt> <br>
<tt> EmptyParam: OleVariant;</tt> <br>
<tt>At the end of the unit, put these lines in the initialization section</tt> <br>
<tt>initialization</tt> <br>
<tt> TVarData (EmptyParam).VType := varError;</tt> <br>
<tt> TVarData (EmptyParam).VError := DISP_E_PARAMNOTFOUND;</tt> <br>
<tt>end.</tt></p>
</blockquote>
<p> </p>
<p><a name="Bloatware"></a><font color="#804040"><strong>Why is Word slow to load and eats
vast amounts of memory?</strong></font></p>
<p>Short answer - because of the bloatware wars with WordPerfect.</p>
<p>Better answer -</p>
<p>- start Word (opens new document for you)<br>
- in the new document, type the word Blue<br>
- select this word and use Format->Font to change it to be bold and blue<br>
- select OK<br>
- enter a space after the word Blue<br>
- choose Help->About<br>
- on the Word icon, press Control-Shift-(Left)Click<br>
<br>
After a bit of thinking, a full screen pinball game appears!</p>
<p> </p>
<p><a name="Faster_Automation"></a><font color="#804040"><strong>Automating Word is faster
if I drop down a Word menu — How can I get this speed advantage in code?</strong></font></p>
<p>This is a FAQ of the OleAutomation newsgroups. If you have a lot of automation to
perform and you switch to Word, then click on the File menu, the automation process will
be much faster. This is probably because Word suspends any background tasks (like
spell-checking) when you do this. You may get a speed advantage if you turn off the
intellisense, spelling and grammar features of Word (but preserve them when finished or
you will upset the user). However, it appears that you still don't get the full advantage
that you get when you drop a menu. If you have read this far in the hope that I have the
answer — sorry! I have put this FAQ in so that anyone who finds the solution may feel
charitable enough to share it with me (and the rest of the Delphi community). So far I
have not seen a solution on the newsgroups.</p>
<p> </p>
<p><a name="Report_Advice"></a><font color="#804040"><strong>I want to use Word to produce
xxx, what is the best way to do this?</strong></font></p>
<p>My Word97 classes were developed for writing one or two letters or a few pages of a
report. Data is read from an Access file and heavily processed to generate natural English
text for inserting inside Word. The processing is the main reason I use Delphi — I
would have great difficulty coding it in VBA.</p>
<p>Having the letters in Word format is important so that the secretaries can save/edit
them just like all their other letters.</p>
<p>When you are considering Word to generate letters consider the following:
<ol>
<li>Are you sure you want to use Word?</li>
</ol>
<blockquote>
<ul>
<li>Word is huge, slow, bloated and bug-ridden. It takes a while to load up and automating
it is not speedy.</li>
<li>You will need to supply your users with Word, or demand that they own it (costly).</li>
<li>Microsoft are not very good at backward compatibility. There is no guarrantee that code
written to automate Word 97 will work for Word 2000 (actually, almost a dead-cert that it
won't — does anyone know?). Word VBA code is likely to be upgradable though.</li>
<li>However templates are familiar to many users and allow easy customisation of letters.</li>
<li>If you have been disappointed with QuickReports, have a look at other report generators
before dismissing them.</li>
</ul>
</blockquote>
<ol start="2">
<li>Are you sure you want to use Delphi?</li>
</ol>
<blockquote>
<p>I know this is heresy, but there are good reasons for considering coding within Word
VBA (see <a href="#Macros">converting Word macros/VBA code to Delphi</a>).<br>
You can go half way and use my classes as well as call Word macros for part of the work.</p>
<p>You may also want to consider mail-merging if you are producing lots of similar
letters.</p>
<p>Using Visual Basic itself (as opposed to Word VBA) has no advantages to my mind.</p>
</blockquote>
<ol start="3">
<li>Are you sure you want to write the letter/report by automating each step.</li>
</ol>
<blockquote>
<p>There are other methods to consider:<ol>
<li>Generate ASCII or RTF output and then import it into Word. You can do this by using
Word's filters. You can also directly read/write the RTF of a Word document using OLE -
see <a href="http://www.softmosis.ca/WordFAQ.html">Joel Milne's Delphi / Word pages</a>.</li>
<li>Use QuickReport's Word filter. I have not studies this in depth, but I suspect this just
exports RTF. I believe that little formatting or placement is kept during the transfer so
it is probably of limited use. It is certainly not up to the quality of Access' Report to
Word export.</li>
</ol>
</blockquote>
<p> </p>
<p><a name="TOleContainer"></a><font color="#804040"><strong>How do I use Word inside the
TOleContainer object?</strong></font></p>
<p>There has been quite a lot written about TOleContainer in the OleAutomation newsgroup.
Basically, it seems to be a partly implemented container class, unlike the Visual Basic
version. It has been suggested that since the Borland team don't use it, it has not been
developed to its full potential. I have no idea whether this is true — what is clear
is that you are largely on your own here. I have read that some very brave/clever
programmers have rewritten it to do what they need. However, these are in-house rewrites
and I have yet to see TSuperOleContainer on Torry's.</p>
<p>*** I have managed the impossible - I have got the TOleContainer to work and have
converted the demo to show it off (Demo2.dpr). Nothing fancy as I don't use it - perhaps
someone who does could add menu merging and thus answer that other FAQ - how do I redefine
the menu File...</p>
<p> </p>
<p><a name="RedefineFileNew"></a><font color="#804040"><strong>I want to re-define what
Word does for x menu item (e.g., FileNew)</strong></font></p>
<p>It is quite easy to get Word to perform a different task when the user chooses a
standard menu item. Just use the standard action's name as the name of your macro, e.g.,</p>
<p><code>Sub FileNew<br>
' This proc alters the "view" of the templates<br>
SendKeys "%2"<br>
Dialogs(wdDialogFileNew).Show<br>
End Sub</code></p>
<p>If you cannot do what you want to do using VBA, you could always call a Delphi DLL. I
am interested in ways to communicate back to the controlling Delphi application (rather
than an in-process DLL). If anyone has done this or has a good idea how this could be done
easily and reliably, I would be very interested to hear from you.</p>
<p> </p>
<p><a name="Macros"></a><font color="#804040"><strong>I want to convert my Word macros/VBA
code to Delphi as Delphi is compiled and therefor fast</strong></font></p>
<p>In general, don't.</p>
<p>Prototyping how to automate Word using macros is a great way to learn how to control
Word from a Delphi program. However if you have existing macros in Word, particularly if
they are big, keep them there. Just call the macro and let it run inside Word.</p>
<p>When Delphi automates Word it has to pass a fair amount across process boundaries. COM
marshalls this so you don't have to think about it but you should be aware that this is a
costly exercise, even when you use early binding. When Word executes VBA code, all the
action happens inside Word's process space. Despite the fact that VBA is interpreted,
automation commands run faster inside Word.</p>
<p>You may wish to convert to Delphi if you want to hide the code (although you can hide
code in VBA). You will get a speed advantage if you have to do a fair amount of
non-automation tasks (e.g, calculations/database lookups). Programming that kind of stuff
is more enjoyable in Delphi too.</p>
<p>It is easier to amend VBA code inside a Word template that it is to recompile and
re-install your program. Bear in mind that you can use the DAO and ADO within the VBA
quite easily to read databases. If all you want to do is read names and addresses from a
database and fill in the headings for a letter, this is almost certainly easier from
inside Word that it is from Delphi.</p>
<p>If you were put off using Word basic and Word forms in the past, have a look at VBA for
Word 97 now. I was pleasantly suprised at how easy it was to make up a <em>simple</em>
form and put code behind it. Before I get shot as a traitor, I should say that the VBA
environment and language is still miles behind Delphi. I can just about bear it for very
simple forms (a bit like Access).</p>
<blockquote>
<p> </p>
</blockquote>
<p><a name="Outside_Links"></a><font color="#804040"><strong>Where can I get more
information on Word automation and Delphi COM in general?</strong></font></p>
<p><br>
MS Word Articles - <a href="http://www.microsoft.com./WordDev/w-a&sa.htm">http://www.microsoft.com./WordDev/w-a&sa.htm</a>
<br>
Microsoft Office 97 Automation Help File Available on MSL - <a
href="http://support.microsoft.com/support/kb/articles/Q167/2/23.asp">http://support.microsoft.com/support/kb/articles/Q167/2/23.asp</a>
</p>
<p>Other COM programmers are <a href="mailto:graham.marshall@virgin.net">Graham Marshall</a>,
<a href="mailto:jmilne@softmosis.ca">Joel Milne</a>, <a href="mailto:bly@castle.net">Binh
Ly</a> and <a href="mailto:debs@djpate.freeserve.co.uk">Deborah Pate</a><br>
They all know far more about Delphi and COM than I do and frequent the delphi
OleAutomation newsgroup.</p>
<p>Graham Marshall's Delphi /Word / Excel page is <a
href="http://vzone.virgin.net/graham.marshall/default.htm">http://vzone.virgin.net/graham.marshall/default.htm</a></p>
<p>Joel Milne's Delphi / Word page is <a href="http://www.softmosis.ca/WordFAQ.html">http://www.softmosis.ca/WordFAQ.html</a>
</p>
<p>Binh Ly's Delphi / COM page is <a
href="http://www.castle.net/~bly/Programming/Delphi/index.html">http://www.castle.net/~bly/Programming/Delphi/index.html</a></p>
<p>Deborah Pate's Delphi Automation page is <a
href="http://www.djpate.freeserve.co.uk/Automation.htm">http://www.djpate.freeserve.co.uk/Automation.htm</a></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -