Basic COM add-in questions

M

Matt Jacobs

Hi,

I have an Office COM Add-In written in VB and I have a few basic
questions related to usage.

Goal: The goal is to distribute a single add-in DLL that works in
Office 2000, Office XP, and Office 2003.

Here are the parameters:
1. The add-in was written in VB 6 SP5 and developed on Windows 2000 w/
Office 2000.
2. The add-in has two designers; one for Word 9 and one for Excel 9.
3. The add-in uses the VB "References" feature to early-bind to the
following Office 2000 typelibs:

MSO9.DLL (Microsoft Office 9.0 Object Library)
EXCEL9.OLB (Microsoft Excel 9.0 Object Library)
MSPPT9.OLB (Microsoft PowerPoint 9.0 Object Library)
MSWORD9.OLB (Microsoft Word 9.0 Object Library)
MSACC9.OLB (Microsoft Access 9.0 Object Library)

4. The add-in does not need access to the new Office XP or Office 2003
methods/properties, if any.

Questions:

1. Will the add-in run unchanged in Office XP and Office 2003?

* Do I need to switch to late-binding to make the single binary usable
in Office 2000, XP, and 2003?
* Do I have to distribute one binary for each Office version?

2. If Excel is not present, will it cause the add-in to fail under
Word or vice-versa?

* Being that I include designers for both Word and Excel, I was
wondering if the absence of either application will cause the add-in
to failure in the other application.

3. Are there any issues with referencing the PowerPoint and Access
typelibs in the case where those products are not installed?

Thanks,

Matt Jacobs
 
T

Thomas Winter

Matt Jacobs said:
Hi,

I have an Office COM Add-In written in VB and I have a few basic
questions related to usage.

Goal: The goal is to distribute a single add-in DLL that works in
Office 2000, Office XP, and Office 2003.

Here are the parameters:
1. The add-in was written in VB 6 SP5 and developed on Windows 2000 w/
Office 2000.
2. The add-in has two designers; one for Word 9 and one for Excel 9.
3. The add-in uses the VB "References" feature to early-bind to the
following Office 2000 typelibs:

MSO9.DLL (Microsoft Office 9.0 Object Library)
EXCEL9.OLB (Microsoft Excel 9.0 Object Library)
MSPPT9.OLB (Microsoft PowerPoint 9.0 Object Library)
MSWORD9.OLB (Microsoft Word 9.0 Object Library)
MSACC9.OLB (Microsoft Access 9.0 Object Library)

4. The add-in does not need access to the new Office XP or Office 2003
methods/properties, if any.

Questions:

1. Will the add-in run unchanged in Office XP and Office 2003?

* Do I need to switch to late-binding to make the single binary usable
in Office 2000, XP, and 2003?
* Do I have to distribute one binary for each Office version?

2. If Excel is not present, will it cause the add-in to fail under
Word or vice-versa?

* Being that I include designers for both Word and Excel, I was
wondering if the absence of either application will cause the add-in
to failure in the other application.

3. Are there any issues with referencing the PowerPoint and Access
typelibs in the case where those products are not installed?

Thanks,

Matt Jacobs



--

My reply-to address is purposely mangled to thwart auto-reply bots.
Please remove the two leading underscores if you wish to reply via
e-mail.

1. You should not have any problem having your add-in run on newer versions
of Office. You'll only need one binary and you can use early-binding. The
one thing to be careful about (which you have been) is to reference to
OLDEST type library in your VB project. (In your case, Word, etc. 9.0).
Office applications (and COM/automation servers in general) are designed to
stay compatible through newer versions. You only need late-binding if you
want to work with versions of Office OLDER than the type library you are
referencing, or if you want to use Objects that are newer than the type
library you are referencing. For more details on this stuff, check my post
under the message "Re: Run time error 9118 Parameter value was out of
acceptable range" under "microsoft.public.word.vba.general".

2. You should not have any problem if Excel is not present, assuming your
Word code doesn't try to do anything with Excel. You would have to error
check that obviously. The registration for the Excel COM Add-In just
wouldn't do anything. As long as you've got at least one of the Office 2000
or later applications, you won't have any problem registering your add-in.
(If the end-user has NONE of the Office 2000 or later applications, they may
get an error when trying to register your DLL. I can explain if you want.)

3. You can reference any type library you want. It will only be a problem if
you try to USE any of the objects you've reference when their applications
are not there. Obviously you need to do error trapping when you reference
these applications.

Want to know anything else, just ask!

By the way, I have written a COM Add-In that works in Word 97, Word 2000,
Word XP, and Word 2003, all with one binary and referencing the Word 2000
type library. Yes, it runs on Word 97! Ask me how...

-Tom
 
C

Cindy M -WordMVP-

Hi Thomas,
By the way, I have written a COM Add-In that works in Word 97, Word 2000,
Word XP, and Word 2003, all with one binary and referencing the Word 2000
type library. Yes, it runs on Word 97! Ask me how...
How?

Cindy Meister
 
T

Thomas Winter

Cindy M -WordMVP- said:
Hi Thomas,

How?

Cindy Meister

OK, the way my situation worked was I had a COM Add-In that was originally
developed for Word 2000 and later. No considerations was given to Word 97 at
the time (3 years ago). The COM Add-In works great on Word 2000/XP/2002.
Well I recently wanted to get rid of the old, much less powerful version of
this system that I wrote eight years ago for Word 6.0, which was still
limping along in Word 97 using WordBasic. We had the much more powerful
version of this system written in VB6 but it used a COM Add-In to connect
with Word. So I added in the few things necessary to make it "connect" with
Word 97.

First, you need a traditional .DOT add-in that is installed in Word's
STARTUP folder. Yes, that is the one big gotcha. As long as you can make
that happen, you can get the rest of this to work. It is fairly easy with a
setup creator like Inno Setup (www.innosetup.com).

Anyway, within this traditional .DOT add-in, you need a module with code
like this. I've taken out error handling for brevity.

--------------- Code Sample ----------------

Private m_oWord97Helper As MyComAddInProject.Word97Helper

Public Sub AutoExec()

Set m_oWord97Helper = New MyComAddInProject.Word97Helper

m_oWord97Helper.AutoExec Application

End Sub

Public Sub AutoExit()

If Not m_oWord97Helper Is Nothing Then

m_oWord97Helper.AutoExit Application

Set m_oWord97Helper = Nothing

End If

End Sub

--------------- Code Sample ----------------

The Word97Helper object is implemented by your VB6 COM Add-In project, which
I've called "MyComAddInProject". These AutoExec() and AutoExit() macros get
called when Word starts up and shuts down. Note that since we've declared
the variable m_oWord97Helper as the module level, it retains its value as
long a Word is running. That way AutoExec() and AutoExit() are working with
the same Word97Helper object (which is important).

Now in your VB6 project, MyComAddInProject, you will have an Add-In Designer
for Word, just like usual. In the VB6 project, you also implement the
Word97Helper object as a MultiUse object (so the macros can create it). In
the Word97Helper object, you basically have this code (again without error
checking):

--------------- Code Sample ----------------

Private m_oMyComAddInDesigner As AddInDesignerObjects.IDTExtensibility2

Private Enum WordStartupModes

' Found these values out by experimentation

WordStartupNormal = 1
WordStartupEmbedded = 2 ' For example, a Word document embedded in an
Excel spreadsheet
WordStartupAutomation = 3 ' For example, when a VB app uses
CreateObject("Word.Application")

End Enum

Public Sub AutoExec(Application As Object)

' Word passes in a custom array to COM Add-ins whose first element
indicates how Word was started up. We simulate this.

Dim vCustom(1 To 1) As Variant

' In case our .DOT add-in gets loaded by Word 2000 or later, we want
to catch that. If that's the case, Word will load
' us the normal COM Add-In way, so we don't want to do anything
here.

If IsWord97(Application) Then

If m_oMyComAddInDesigner Is Nothing Then

Set m_oMyComAddInDesigner = New
MyComAddInProject.MyComAddInDesigner

vCustom(1) = WordStartupNormal

m_oMyComAddInDesigner.OnConnection Application,
ext_cm_Startup, Nothing, vCustom

vCustom(1) = Empty

m_oMyComAddInDesigner.OnStartupComplete vCustom

End If

End If

End Sub

Public Sub AutoExit(Application As Object)

Dim vCustom(1 To 1) As Variant

If IsWord97(Application) Then

If Not m_oMyComAddInDesigner Is Nothing Then

vCustom(1) = Empty

m_oMyComAddInDesigner.OnBeginShutdown vCustom

m_oMyComAddInDesigner.OnDisconnection ext_dm_HostShutdown,
vCustom

Set m_oMyComAddInDesigner = Nothing

End If

End If

End Sub

Public Function IsWord97(oWord As Object) As Boolean

On Error GoTo ErrorHandler

' As first though, you'd think we would use the Application.Version
of Application.Build
' properties of Word.Application, but they return strings in a goofy
format with
' multiple periods or alphabetic characters. FIX/INT/CINT choke on
those.
' So instead, we simply check for an object that exists starting in
Word 2000. If COMAddIns
' does not exist, then an error will be raised and we know we have
Word 97.
' We use oWord as an Object to make sure we get late binding, so
we'll find out
' at run time if we can get the COMAddIns property.

Dim oCOMAddIns As Object

Set oCOMAddIns = oWord.COMAddIns

IsWord97 = False

Set oCOMAddIns = Nothing

Exit Function

ErrorHandler:

IsWord97 = True

End Function

--------------- Code Sample ----------------

Basically what the Word97Helper object does is PRETEND TO BE WORD 2000! It
creates an instance of your COM Add-In Designer object, just like Word does.
Note that we reference the object using the
AddInDesignerObjects.IDTExtensibility2 interface, which is how Word accesses
it. We have to save the object of course so we can shut it down later. We
then act just like Word, calling the appropriate methods and passing in the
appropriate parameters. Unless your COM Add-In Designer code actually used
the WordStartupMode values, you don't really need to worry about them. My
code did use them. One important thing is that we pass in the Application
parameter to AutoExec() and AutoExit() as an Object, rather than
Word.Application. Things can get goofy depending on what version of the Word
type library your VB6 project references. Those macros in our Word 97 .DOT
add-in expect a Word 97 Application object basically. Better to be safe than
sorry and use Object here.

Now your COM Add-In in your VB6 project should start up just like normal.
Obviously you have to be careful about what objects, methods and parameters
you use in your VB project. Or do version checking to make sure you use the
right ones. It is really best to reference the Word 97 type library, and
then do version checking and put your objects into Object variables if you
need post-Word 97 objects or methods. Check my post under the message "Re:
Run time error 9118 Parameter value was out of acceptable range" under
"microsoft.public.word.vba.general" for details on why this is important.

Two other gotchas: If you need to use custom CommandBarButtons, etc., you
MUST use the .OnAction property set to a macro name. You cannot use the
Click event of the button object (the "normal" way of doing it in Word
2000.) This is because Word 97 does not support the Click event on buttons.
The ONLY way to get your buttons in Word 97 to do anything is to have them
call a macro using the .OnAction property. You could probably use version
checking and then only do one or the other, but what's the bother? Yes I
know macros are the "old way of doing it", but it works just fine.

What you do is, again in your traditional .DOT add-in, include some macros
that your command bar buttons call. Those macros would then call a method in
one of your COM Add-In's object. For example, you could put these macros in
the same module as the AutoExec() and AutoExit() macros, and then have them
call some other methods of the Word97Helper object.

The other important gotcha is distributing your .DLL. Remember, even on Word
97 only systems, when you register your VB6 DLL, it will still register the
COM Add-In. The problem is that the Add-In Designer (msaddndr.dll) MUST be
on the end-user's system when registering the DLL or you will get a
registration error. This is normally not a problem on Word 2000 or later
systems, since the Add-In Designer comes with Word 2000 and later.
Obviously, Word 97 only systems will not have the DLL. So your setup program
must install and register msaddndr.dll in C:\Program Files\Common
Files\Designer. (I read an MS KB article that talked about redistributing
the DLL, so you area allowed to.)

That's about it! I hope that made sense. Any questions, let me know!

-Tom
 
M

Matt Jacobs

Thomas, thanks a lot for the information. That was exactly what I need
to know.

Do tell, how did you get a COM add-in to run under Office 97? ;-)

Thanks again!

Matt
 
T

Thomas Winter

Matt Jacobs said:
Thomas, thanks a lot for the information. That was exactly what I need
to know.

Do tell, how did you get a COM add-in to run under Office 97? ;-)

Thanks again!

Matt



--

My reply-to address is purposely mangled to thwart auto-reply bots.
Please remove the two leading underscores if you wish to reply via
e-mail.

See my reply to Cindy in this same thread.

-Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top