Accessing Outlook via COM

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Accessing Outlook via COM

Scott
I have generated all the COM interfaces for Outlook (c:\program
files\Microsoft office\office\msoutl9.olb) with a prefix of ‘Outlook'

I am having trouble getting events hooked up.  

According to the following typelib info:

[
  uuid(0006F03A-0000-0000-C000-000000000046),
  helpcontext(0x004de932),
  appobject
]
coclass Application {
    [default] interface _Application;
    [default, source] dispinterface ApplicationEvents;
};

Outlook.Application should have a coclass dispinterface of
ApplicationEvents (no interface classes are generated for this) , but
when I execute the following code

outlook := Outlook_Application new.
typeInfo := ((outlook queryInterface: IUnknown) coclassTypeInfoIfNone:
[^nil]) defaultSourceInterface.
sink := AXEventSink target: self sourceTypeInfo: typeInfo
sink connect: outlook

typeInfo is nil.  (I believe this should be Outlook_ApplicationEvents)


Even when using the Active-X Control Browser and doing the File | New
with ‘Outlook.Application', no events show up in the event pane.

What am I doing wrong?

Thanks,
Scott

Window 2000 Pro SP2, Dolphin XP, Outlook 9.0.0.2711, logged in as
administrator.


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Don Rylander-3
Scott,
"Scott" <[hidden email]> wrote in message
news:[hidden email]...
[...]
> Outlook.Application should have a coclass dispinterface of
> ApplicationEvents (no interface classes are generated for this) , but
> when I execute the following code
>
> outlook := Outlook_Application new.
> typeInfo := ((outlook queryInterface: IUnknown) coclassTypeInfoIfNone:
> [^nil]) defaultSourceInterface.
> sink := AXEventSink target: self sourceTypeInfo: typeInfo
> sink connect: outlook

Take a look in the class hierarchy below Outlook_Application and you should
find something like OutlookApplicationEvents (with no underscore).  If it's
there, you should be able to use this:

outlook := Outlook_Application new.
sink := AXEventSink target: outlook sourceTypeInfo: OutlookApplicationEvents
typeInfo
sink connect: outlook
sink isTracingEnabled: true

BIG WARNING: This code was just copied from some functioning code, and
hand-modified =8^O, so I can't attest to its complete validity, but it's
pretty close.

HTH,

Don

>
> typeInfo is nil.  (I believe this should be Outlook_ApplicationEvents)
>
>
> Even when using the Active-X Control Browser and doing the File | New
> with 'Outlook.Application', no events show up in the event pane.
>
> What am I doing wrong?
>
> Thanks,
> Scott
>
> Window 2000 Pro SP2, Dolphin XP, Outlook 9.0.0.2711, logged in as
> administrator.


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Scott
No class named OutlookApplicationEvents is generated (nor any of the
other event type classes) for and may be part of my problem.

I can use "Outlook_Application typeLib at: 'ApplicationEvents'" to get
the typeInfo, but looking at using AXControlSite with
Outlook_Application not showing the events, I believe that something
is not working correctly.

Thanks for the info,
Scott

"Don Rylander" <[hidden email]> wrote in message news:<ai4cbb$10k3uc$[hidden email]>...

> Scott,
> "Scott" <[hidden email]> wrote in message
> news:[hidden email]...
> [...]
> > Outlook.Application should have a coclass dispinterface of
> > ApplicationEvents (no interface classes are generated for this) , but
> > when I execute the following code
> >
> > outlook := Outlook_Application new.
> > typeInfo := ((outlook queryInterface: IUnknown) coclassTypeInfoIfNone:
> > [^nil]) defaultSourceInterface.
> > sink := AXEventSink target: self sourceTypeInfo: typeInfo
> > sink connect: outlook
>
> Take a look in the class hierarchy below Outlook_Application and you should
> find something like OutlookApplicationEvents (with no underscore).  If it's
> there, you should be able to use this:
>
> outlook := Outlook_Application new.
> sink := AXEventSink target: outlook sourceTypeInfo: OutlookApplicationEvents
> typeInfo
> sink connect: outlook
> sink isTracingEnabled: true
>
> BIG WARNING: This code was just copied from some functioning code, and
> hand-modified =8^O, so I can't attest to its complete validity, but it's
> pretty close.
>
> HTH,
>
> Don
>
> >
> > typeInfo is nil.  (I believe this should be Outlook_ApplicationEvents)
> >
> >
> > Even when using the Active-X Control Browser and doing the File | New
> > with 'Outlook.Application', no events show up in the event pane.
> >
> > What am I doing wrong?
> >
> > Thanks,
> > Scott
> >
> > Window 2000 Pro SP2, Dolphin XP, Outlook 9.0.0.2711, logged in as
> > administrator.


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Blair McGlashan
"Scott" <[hidden email]> wrote in message
news:[hidden email]...
> No class named OutlookApplicationEvents is generated (nor any of the
> other event type classes) for and may be part of my problem.

Dolphin XP no longer generates wrapper classes for source dispinterfaces.
This is because they contained no behaviour and we wanted to try and reduce
the number of classes generated from large type libraries.

>
> I can use "Outlook_Application typeLib at: 'ApplicationEvents'" to get
> the typeInfo, but looking at using AXControlSite with
> Outlook_Application not showing the events, I believe that something
> is not working correctly.

Works OK for me, for example:

    outlook := Outlook_Application new.
    sink := AXEventSink target: outlook sourceTypeInfo: (outlook class
typeLib at: 'ApplicationEvents').
    sink connect: outlook.
    sink isTracingEnabled: true.

    "Now try sending some mail"
    mail := (outlook createItem: olMailItem) asImplType.
    mail to: '[hidden email]'.
    mail subject: 'Outlook test'.
    mail htmlBody: '<EM>Hello from Dolphin</EM>'.
    mail send

On evaluation of the last expression I got this trace on the Transcript:

    Event: #ItemSend:Cancel: args: #(an IDispatch('Outlook test')
VARIANT_FALSE)

Of course it would be more convenient to use #coclassTypeInfoIfNone: to get
the type info for the default source interface as follows:

    sink := AXEventSink target: outlook sourceTypeInfo: outlook
coclassTypeInfo defaultSourceInterface.

but there is a bug in COMInterface>>coclassTypeInfoIfNone: in that if the
object does not implement IProvideClassInfo, then it ends up answering the
type info for the interface, not that for the associated coclass. The
attached patch corrects this so that expressions such as the above will
work. I believe this bug has been reported before (by Bill Schwab I think),
but for some reason it has slipped through the net.

BTW: I attempted to inspect 'outlook' on my machine using the Flipper
inspector, and it locked up Dolphin. Or at least I thought it had. Killing
Outlook.exe from the task manager brought Dolphin back to life after a short
timeout. I tried essentially the same operation from VB and the same thing
happened (i.e. the VB IDE locked up). It was then I noticed that Outlook had
in fact popped up a message box, which I couldn't see because it came up
behind all the VB/Dolphin windows, complaining of some configuration error.
Something to watch out for.

Regards

Blair

-------------------------
!COMInterface methodsFor!

coclassTypeInfoIfNone: exceptionHandler
 "Answer any type information that exists for the object on which the
receiver is an interface."

 ^(self queryInterface: IProvideClassInfo)
  ifNil: [self class typeInfoIfNone: [^exceptionHandler value]]
  ifNotNil:
   [:ipc |
   [AXTypeInfoAnalyzer onTypeInfo: ipc getClassInfo] on: HRESULTError
    do: [:ex | ^exceptionHandler value]]! !
!COMInterface categoriesFor: #coclassTypeInfoIfNone:!accessing!public! !

!COMInterface class methodsFor!

coclassTypeInfoIfNone: exceptionHandler
 "Answer any type information that exists for the object on which the
receiver is the default interface.
 This link can only be made if the #clsid method is defined and a type
library with the relevant
 information is available."

 | tlb |
 ^(tlb := self typeLib) isNil
  ifTrue: [exceptionHandler value]
  ifFalse: [tlb typeInfoForGuid: self clsid ifNone: [^exceptionHandler
value]]! !
!COMInterface class categoriesFor: #coclassTypeInfoIfNone:!accessing!public!
!

!COMInterface class methodsFor!

coclassTypeInfo
 "Answer any type information that exists for the object on which the
receiver is an interface."

 ^self coclassTypeInfoIfNone: [self errorNoTypeInfo]! !
!COMInterface class categoriesFor: #coclassTypeInfo!accessing!public! !


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Scott
In reply to this post by Scott
Can any one get the ActiveX Control Browser to display the Events for
'Outlook.Application' with Dolphin XP version 5.01?  No events show up
in the display.

When I use the sourceTypeInfo with "Outlook_Application typeLib at:
'ApplicationEvents'", none of the events are triggered (#NewMail
#Startup #Reminder: or #Quit).

Any help will be great.

Thanks,
Scott



[hidden email] (Scott) wrote in message news:<[hidden email]>...

> No class named OutlookApplicationEvents is generated (nor any of the
> other event type classes) for and may be part of my problem.
>
> I can use "Outlook_Application typeLib at: 'ApplicationEvents'" to get
> the typeInfo, but looking at using AXControlSite with
> Outlook_Application not showing the events, I believe that something
> is not working correctly.
>
> Thanks for the info,
> Scott
>
> "Don Rylander" <[hidden email]> wrote in message news:<ai4cbb$10k3uc$[hidden email]>...
> > Scott,
> > "Scott" <[hidden email]> wrote in message
> > news:[hidden email]...
> > [...]
> > > Outlook.Application should have a coclass dispinterface of
> > > ApplicationEvents (no interface classes are generated for this) , but
> > > when I execute the following code
> > >
> > > outlook := Outlook_Application new.
> > > typeInfo := ((outlook queryInterface: IUnknown) coclassTypeInfoIfNone:
> > > [^nil]) defaultSourceInterface.
> > > sink := AXEventSink target: self sourceTypeInfo: typeInfo
> > > sink connect: outlook
> >
> > Take a look in the class hierarchy below Outlook_Application and you should
> > find something like OutlookApplicationEvents (with no underscore).  If it's
> > there, you should be able to use this:
> >
> > outlook := Outlook_Application new.
> > sink := AXEventSink target: outlook sourceTypeInfo: OutlookApplicationEvents
> > typeInfo
> > sink connect: outlook
> > sink isTracingEnabled: true
> >
> > BIG WARNING: This code was just copied from some functioning code, and
> > hand-modified =8^O, so I can't attest to its complete validity, but it's
> > pretty close.
> >
> > HTH,
> >
> > Don
> >
> > >
> > > typeInfo is nil.  (I believe this should be Outlook_ApplicationEvents)
> > >
> > >
> > > Even when using the Active-X Control Browser and doing the File | New
> > > with 'Outlook.Application', no events show up in the event pane.
> > >
> > > What am I doing wrong?
> > >
> > > Thanks,
> > > Scott
> > >
> > > Window 2000 Pro SP2, Dolphin XP, Outlook 9.0.0.2711, logged in as
> > > administrator.


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Blair McGlashan
"Scott" <[hidden email]> wrote in message
news:[hidden email]...
> Can any one get the ActiveX Control Browser to display the Events for
> 'Outlook.Application' with Dolphin XP version 5.01?  No events show up
> in the display.
>
> When I use the sourceTypeInfo with "Outlook_Application typeLib at:
> 'ApplicationEvents'", none of the events are triggered (#NewMail
> #Startup #Reminder: or #Quit).
> ...

No, because the Active-X Control Browser is intended for exploring Active-X
controls that implement IProvideClassInfo. Since Outlook is not really an
OCX, it does not provide the necessary "link" between the objects main
interface and its default event interface. Although we have seen that this
link can be made through the type library, the Active-X control browser is
not set up to do that. Anyway this doesn't really buy you anything over
running scripts like the ones I posted, since the principle use of the AXCB
is to see visual effects that result from changing properties, etc, and the
events generated in response to particular actions.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Don Rylander-3
In reply to this post by Scott
Scott, I generated a brand new Outlook_Application (Outlook 10, aka XP,
running in corporate/workgroup mode on Windows XP) in Dolphin XP, and set it
up this way:

ol := Outlook_Application new.
typeInfo := Outlook_Application typeLib at: 'ApplicationEvents'.
sink := AXEventSink target: ol sourceTypeInfo: typeInfo.
sink connect: ol; isTracingEnabled: true.

I got these displayed on the Transcript:

Event: #ItemSend:Cancel: args: #(an IDispatch('Test again') VARIANT_FALSE)
Event: #Reminder: args: #(an IDispatch('This is a reminder'))
Event: #NewMail args: #()
Event: #Quit args: #()

The first time I tried using it, it didn't work quite as expected.  I left
Dolphin running, but shut down Outlook (making sure it was gone from the
task list), and restarted it.  Then it worked as expected.  If you'd like I
can send you the stuff I generated, although I don't know how well the 10.0
object model maps to the 9.0 one (they work fine the other way).

HTH,

Don

"Scott" <[hidden email]> wrote in message
news:[hidden email]...

> Can any one get the ActiveX Control Browser to display the Events for
> 'Outlook.Application' with Dolphin XP version 5.01?  No events show up
> in the display.
>
> When I use the sourceTypeInfo with "Outlook_Application typeLib at:
> 'ApplicationEvents'", none of the events are triggered (#NewMail
> #Startup #Reminder: or #Quit).
>
> Any help will be great.
>
> Thanks,
> Scott
>
>
>
> [hidden email] (Scott) wrote in message
news:<[hidden email]>...

> > No class named OutlookApplicationEvents is generated (nor any of the
> > other event type classes) for and may be part of my problem.
> >
> > I can use "Outlook_Application typeLib at: 'ApplicationEvents'" to get
> > the typeInfo, but looking at using AXControlSite with
> > Outlook_Application not showing the events, I believe that something
> > is not working correctly.
> >
> > Thanks for the info,
> > Scott
> >
> > "Don Rylander" <[hidden email]> wrote in
message news:<ai4cbb$10k3uc$[hidden email]>...
> > > Scott,
> > > "Scott" <[hidden email]> wrote in message
> > > news:[hidden email]...
> > > [...]
> > > > Outlook.Application should have a coclass dispinterface of
> > > > ApplicationEvents (no interface classes are generated for this) ,
but
> > > > when I execute the following code
> > > >
> > > > outlook := Outlook_Application new.
> > > > typeInfo := ((outlook queryInterface: IUnknown)
coclassTypeInfoIfNone:
> > > > [^nil]) defaultSourceInterface.
> > > > sink := AXEventSink target: self sourceTypeInfo: typeInfo
> > > > sink connect: outlook
> > >
> > > Take a look in the class hierarchy below Outlook_Application and you
should
> > > find something like OutlookApplicationEvents (with no underscore).  If
it's
> > > there, you should be able to use this:
> > >
> > > outlook := Outlook_Application new.
> > > sink := AXEventSink target: outlook sourceTypeInfo:
OutlookApplicationEvents
> > > typeInfo
> > > sink connect: outlook
> > > sink isTracingEnabled: true
> > >
> > > BIG WARNING: This code was just copied from some functioning code, and
> > > hand-modified =8^O, so I can't attest to its complete validity, but
it's
> > > pretty close.
> > >
> > > HTH,
> > >
> > > Don
> > >
> > > >
> > > > typeInfo is nil.  (I believe this should be
Outlook_ApplicationEvents)
> > > >
> > > >
> > > > Even when using the Active-X Control Browser and doing the File |
New
> > > > with 'Outlook.Application', no events show up in the event pane.
> > > >
> > > > What am I doing wrong?
> > > >
> > > > Thanks,
> > > > Scott
> > > >
> > > > Window 2000 Pro SP2, Dolphin XP, Outlook 9.0.0.2711, logged in as
> > > > administrator.


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Blair McGlashan
In reply to this post by Scott
"Scott" <[hidden email]> wrote in message
news:[hidden email]...
> No class named OutlookApplicationEvents is generated (nor any of the
> other event type classes) for and may be part of my problem.

Dolphin XP no longer generates wrapper classes for source dispinterfaces.
This is because they contained no behaviour and we wanted to try and reduce
the number of classes generated from large type libraries.

>
> I can use "Outlook_Application typeLib at: 'ApplicationEvents'" to get
> the typeInfo, but looking at using AXControlSite with
> Outlook_Application not showing the events, I believe that something
> is not working correctly.

Works OK for me, for example:

    outlook := Outlook_Application new.
    sink := AXEventSink target: outlook sourceTypeInfo: (outlook class
typeLib at: 'ApplicationEvents').
    sink connect: outlook.
    sink isTracingEnabled: true.

    "Now try sending some mail"
    mail := (outlook createItem: olMailItem) asImplType.
    mail to: '[hidden email]'.
    mail subject: 'Outlook test'.
    mail htmlBody: '<EM>Hello from Dolphin</EM>'.
    mail send

On evaluation of the last expression I got this trace on the Transcript:

    Event: #ItemSend:Cancel: args: #(an IDispatch('Outlook test')
VARIANT_FALSE)

Of course it would be more convenient to use #coclassTypeInfoIfNone: to get
the type info for the default source interface as follows:

    sink := AXEventSink target: outlook sourceTypeInfo: outlook
coclassTypeInfo defaultSourceInterface.

but there is a bug in COMInterface>>coclassTypeInfoIfNone: in that if the
object does not implement IProvideClassInfo, then it ends up answering the
type info for the interface, not that for the associated coclass. The
attached patch corrects this so that expressions such as the above will
work. I believe this bug has been reported before (by Bill Schwab I think),
but for some reason it has slipped through the net.

BTW: I attempted to inspect 'outlook' on my machine using the Flipper
inspector, and it locked up Dolphin. Or at least I thought it had. Killing
Outlook.exe from the task manager brought Dolphin back to life after a short
timeout. I tried essentially the same operation from VB and the same thing
happened (i.e. the VB IDE locked up). It was then I noticed that Outlook had
in fact popped up a message box, which I couldn't see because it came up
behind all the VB/Dolphin windows, complaining of some configuration error.
Something to watch out for.

Regards

Blair

-------------------------
!COMInterface methodsFor!

coclassTypeInfoIfNone: exceptionHandler
 "Answer any type information that exists for the object on which the
receiver is an interface."

 ^(self queryInterface: IProvideClassInfo)
  ifNil: [self class typeInfoIfNone: [^exceptionHandler value]]
  ifNotNil:
   [:ipc |
   [AXTypeInfoAnalyzer onTypeInfo: ipc getClassInfo] on: HRESULTError
    do: [:ex | ^exceptionHandler value]]! !
!COMInterface categoriesFor: #coclassTypeInfoIfNone:!accessing!public! !

!COMInterface class methodsFor!

coclassTypeInfoIfNone: exceptionHandler
 "Answer any type information that exists for the object on which the
receiver is the default interface.
 This link can only be made if the #clsid method is defined and a type
library with the relevant
 information is available."

 | tlb |
 ^(tlb := self typeLib) isNil
  ifTrue: [exceptionHandler value]
  ifFalse: [tlb typeInfoForGuid: self clsid ifNone: [^exceptionHandler
value]]! !
!COMInterface class categoriesFor: #coclassTypeInfoIfNone:!accessing!public!
!

!COMInterface class methodsFor!

coclassTypeInfo
 "Answer any type information that exists for the object on which the
receiver is an interface."

 ^self coclassTypeInfoIfNone: [self errorNoTypeInfo]! !
!COMInterface class categoriesFor: #coclassTypeInfo!accessing!public! !


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Blair McGlashan
In reply to this post by Scott
"Scott" <[hidden email]> wrote in message
news:[hidden email]...
> Can any one get the ActiveX Control Browser to display the Events for
> 'Outlook.Application' with Dolphin XP version 5.01?  No events show up
> in the display.
>
> When I use the sourceTypeInfo with "Outlook_Application typeLib at:
> 'ApplicationEvents'", none of the events are triggered (#NewMail
> #Startup #Reminder: or #Quit).
> ...

No, because the Active-X Control Browser is intended for exploring Active-X
controls that implement IProvideClassInfo. Since Outlook is not really an
OCX, it does not provide the necessary "link" between the objects main
interface and its default event interface. Although we have seen that this
link can be made through the type library, the Active-X control browser is
not set up to do that. Anyway this doesn't really buy you anything over
running scripts like the ones I posted, since the principle use of the AXCB
is to see visual effects that result from changing properties, etc, and the
events generated in response to particular actions.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Scott
In reply to this post by Blair McGlashan
In order for the following code to work, the following change needs to
be made to the code.

outlook := Outlook_Application new.
sink := AXEventSink target: outlook sourceTypeInfo:outlook
coclassTypeInfo defaultSourceInterface.

> !COMInterface methodsFor!
>
> coclassTypeInfoIfNone: exceptionHandler
>  "Answer any type information that exists for the object on which the
> receiver is an interface."
>
>  ^(self queryInterface: IProvideClassInfo)
>   ifNil: [self class typeInfoIfNone: [^exceptionHandler value]]

change>   ifNil: [self class coclassTypeInfoIfNone: [^exceptionHandler
value]]

>   ifNotNil:
>    [:ipc |
>    [AXTypeInfoAnalyzer onTypeInfo: ipc getClassInfo] on: HRESULTError
>     do: [:ex | ^exceptionHandler value]]! !
> !COMInterface categoriesFor: #coclassTypeInfoIfNone:!accessing!public! !
>
> !COMInterface class methodsFor!
>
> coclassTypeInfoIfNone: exceptionHandler
>  "Answer any type information that exists for the object on which the
> receiver is the default interface.
>  This link can only be made if the #clsid method is defined and a type
> library with the relevant
>  information is available."
>
>  | tlb |
>  ^(tlb := self typeLib) isNil
>   ifTrue: [exceptionHandler value]
>   ifFalse: [tlb typeInfoForGuid: self clsid ifNone: [^exceptionHandler
> value]]! !
> !COMInterface class categoriesFor: #coclassTypeInfoIfNone:!accessing!public!
> !
>
> !COMInterface class methodsFor!
>
> coclassTypeInfo
>  "Answer any type information that exists for the object on which the
> receiver is an interface."
>
>  ^self coclassTypeInfoIfNone: [self errorNoTypeInfo]! !
> !COMInterface class categoriesFor: #coclassTypeInfo!accessing!public! !

Thanks for your help.

Scott


Reply | Threaded
Open this post in threaded view
|

Re: Accessing Outlook via COM

Blair McGlashan
"Scott" <[hidden email]> wrote in message
news:[hidden email]...

> In order for the following code to work, the following change needs to
> be made to the code.
>
> outlook := Outlook_Application new.
> sink := AXEventSink target: outlook sourceTypeInfo:outlook
> coclassTypeInfo defaultSourceInterface.
>
> > !COMInterface methodsFor!
> >
> > coclassTypeInfoIfNone: exceptionHandler
> >  "Answer any type information that exists for the object on which the
> > receiver is an interface."
> >
> >  ^(self queryInterface: IProvideClassInfo)
> >   ifNil: [self class typeInfoIfNone: [^exceptionHandler value]]
>
> change>   ifNil: [self class coclassTypeInfoIfNone: [^exceptionHandler
> value]]

Yes, that's right. Sorry, but I posted the wrong version of the method (the
unpatched one).

Regards

Blair