Board index » delphi » Hooking Items.ItemAdd event in Outlook

Hooking Items.ItemAdd event in Outlook


2005-04-18 10:48:55 PM
delphi56
Hi all,
My Delphi applicaiton is working with Outlook via COM. I want to hook the
ItemAdd event of the Items collection of a folder. I approached this as
follows. First, created a class:
TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
protected
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
end;
All methods are stubs - just return S_OK. Then I attempt to connect my class
as a sink to the Items collection:
var
OutlookApplication : TOutlookApplication;
Connection : Integer;
...
Folder :=
OutlookApplication.GetNamespace('MAPI').GetDefaultFolder(olFolderSentMail);
InterfaceConnect(Folder.Items, DIID_ItemsEvents,
TFolderItemsEventSink.Create, Connection);
InterfaceConnect works correctly. Now I expect that when an item is added to
the Sent folder, my Invoke method is called. But it just never happens. What
am I doing wrong? Can anyone suggest how to hook the event properly?
Thanks,
Leonid
 
 

Re:Hooking Items.ItemAdd event in Outlook

Quote
TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
protected
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
end;

All methods are stubs - just return S_OK. Then I attempt to connect my
class
as a sink to the Items collection:
I suppose you should return that you implement a certain method (fixed Name)
for it to call you back on that ID. There was a nice tutorial for COM
callbacks / event sinks etc. for Delphi online. Let me know if you can't
find it (had found it using Copernic agent)
--
-----
George Birbilis (XXXX@XXXXX.COM)
Microsoft Most Valuable Professional
MVP J# for 2004 & 2005
www.kagi.com/birbilis
--------------
 

Re:Hooking Items.ItemAdd event in Outlook

Hi George,
Do you have a link to that tutorial? I can not seem to find it.
BTW, even GetIDsOfNames is not called for my sink object.
Thanks,
Leonid
"George Birbilis" <XXXX@XXXXX.COM>сообщи?сообщила ?новостях следующе?
Quote
>TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
>protected
>function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
>function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo):
HResult;
>stdcall;
>function GetIDsOfNames(const IID: TGUID; Names: Pointer;
>NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
>function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
>Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
>HResult; stdcall;
>end;
>
>All methods are stubs - just return S_OK. Then I attempt to connect my
>class
>as a sink to the Items collection:

I suppose you should return that you implement a certain method (fixed
Name)
for it to call you back on that ID. There was a nice tutorial for COM
callbacks / event sinks etc. for Delphi online. Let me know if you can't
find it (had found it using Copernic agent)


--
-----
George Birbilis (XXXX@XXXXX.COM)
Microsoft Most Valuable Professional
MVP J# for 2004 & 2005
www.kagi.com/birbilis
--------------


 

Re:Hooking Items.ItemAdd event in Outlook

Nope, all event interfaces are dispinterfaces, they do not have a v-table.
Everything is done through IDispatch.Invoke.
Dmitry Streblechenko (MVP)
www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
"George Birbilis" <XXXX@XXXXX.COM>writes
Quote
>TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
>protected
>function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
>function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
>stdcall;
>function GetIDsOfNames(const IID: TGUID; Names: Pointer;
>NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
>function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
>Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
>HResult; stdcall;
>end;
>
>All methods are stubs - just return S_OK. Then I attempt to connect my
>class
>as a sink to the Items collection:

I suppose you should return that you implement a certain method (fixed
Name) for it to call you back on that ID. There was a nice tutorial for
COM callbacks / event sinks etc. for Delphi online. Let me know if you
can't find it (had found it using Copernic agent)


--
-----
George Birbilis (XXXX@XXXXX.COM)
Microsoft Most Valuable Professional
MVP J# for 2004 & 2005
www.kagi.com/birbilis
--------------


 

Re:Hooking Items.ItemAdd event in Outlook

You *must* store Folder.Items in a global (class) variable to make sure it
is referenced and alive at all times. The way yourr code is implemented
right now, the compiler creates an implicit local variable to store
Folder.Items, which is then dereferenced and released as soon as it goes out
of scope (the current method?).
Dmitry Streblechenko (MVP)
www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
"Leonid Zeitlin" <XXXX@XXXXX.COM>writes
Quote
Hi all,
My Delphi applicaiton is working with Outlook via COM. I want to hook the
ItemAdd event of the Items collection of a folder. I approached this as
follows. First, created a class:

TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
protected
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
end;

All methods are stubs - just return S_OK. Then I attempt to connect my
class
as a sink to the Items collection:

var
OutlookApplication : TOutlookApplication;
Connection : Integer;
...
Folder :=
OutlookApplication.GetNamespace('MAPI').GetDefaultFolder(olFolderSentMail);
InterfaceConnect(Folder.Items, DIID_ItemsEvents,
TFolderItemsEventSink.Create, Connection);

InterfaceConnect works correctly. Now I expect that when an item is added
to
the Sent folder, my Invoke method is called. But it just never happens.
What
am I doing wrong? Can anyone suggest how to hook the event properly?

Thanks,
Leonid


 

Re:Hooking Items.ItemAdd event in Outlook

I think it was:
www.gekko-software.nl/Delphi/art10.htm
or one of the other articles at that site (don't have that page cached to
take a look)
Quote
Do you have a link to that tutorial? I can not seem to find it.

BTW, even GetIDsOfNames is not called for my sink object.

Thanks,
Leonid


"George Birbilis" <XXXX@XXXXX.COM>сообщи?сообщила ?новостях
следующе?
news:XXXX@XXXXX.COM...
>>TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
>>protected
>>function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
>>function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo):
HResult;
>>stdcall;
>>function GetIDsOfNames(const IID: TGUID; Names: Pointer;
>>NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
>>function Invoke(DispID: Integer; const IID: TGUID; LocaleID:
>>Integer;
>>Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
>>HResult; stdcall;
>>end;
>>
>>All methods are stubs - just return S_OK. Then I attempt to connect my
>>class
>>as a sink to the Items collection:
>
>I suppose you should return that you implement a certain method (fixed
Name)
>for it to call you back on that ID. There was a nice tutorial for COM
>callbacks / event sinks etc. for Delphi online. Let me know if you can't
>find it (had found it using Copernic agent)
>
>
>--
>-----
>George Birbilis (XXXX@XXXXX.COM)
>Microsoft Most Valuable Professional
>MVP J# for 2004 & 2005
>www.kagi.com/birbilis
>--------------
>
>


 

Re:Hooking Items.ItemAdd event in Outlook

Thanks a lot, Dmitry, your suggestion solved my problem.
Regards,
Leonid
"Dmitry Streblechenko" <XXXX@XXXXX.COM>сообщи?сообщила ?новостях
следующе? news:42654a35$XXXX@XXXXX.COM...
Quote
You *must* store Folder.Items in a global (class) variable to make sure it
is referenced and alive at all times. The way yourr code is implemented
right now, the compiler creates an implicit local variable to store
Folder.Items, which is then dereferenced and released as soon as it goes
out
of scope (the current method?).

Dmitry Streblechenko (MVP)
www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

"Leonid Zeitlin" <XXXX@XXXXX.COM>writes
news:XXXX@XXXXX.COM...
>Hi all,
>My Delphi applicaiton is working with Outlook via COM. I want to hook
the
>ItemAdd event of the Items collection of a folder. I approached this as
>follows. First, created a class:
>
>TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
>protected
>function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
>function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo):
HResult;
>stdcall;
>function GetIDsOfNames(const IID: TGUID; Names: Pointer;
>NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
>function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
>Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
>HResult; stdcall;
>end;
>
>All methods are stubs - just return S_OK. Then I attempt to connect my
>class
>as a sink to the Items collection:
>
>var
>OutlookApplication : TOutlookApplication;
>Connection : Integer;
>...
>Folder :=
>
OutlookApplication.GetNamespace('MAPI').GetDefaultFolder(olFolderSentMail);
>InterfaceConnect(Folder.Items, DIID_ItemsEvents,
>TFolderItemsEventSink.Create, Connection);
>
>InterfaceConnect works correctly. Now I expect that when an item is
added
>to
>the Sent folder, my Invoke method is called. But it just never happens.
>What
>am I doing wrong? Can anyone suggest how to hook the event properly?
>
>Thanks,
>Leonid
>
>


 

Re:Hooking Items.ItemAdd event in Outlook

Thanks for the link, George
Regards,
Leonid
"George Birbilis" <XXXX@XXXXX.COM>сообщи?сообщила ?новостях следующе?
Quote
I think it was:
www.gekko-software.nl/Delphi/art10.htm
or one of the other articles at that site (don't have that page cached to
take a look)

>Do you have a link to that tutorial? I can not seem to find it.
>
>BTW, even GetIDsOfNames is not called for my sink object.
>
>Thanks,
>Leonid
>
>
>"George Birbilis" <XXXX@XXXXX.COM>сообщи?сообщила ?новостях
>следующе?
>news:XXXX@XXXXX.COM...
>>>TFolderItemsEventSink = class(TInterfacedObject, IDispatch)
>>>protected
>>>function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
>>>function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo):
>HResult;
>>>stdcall;
>>>function GetIDsOfNames(const IID: TGUID; Names: Pointer;
>>>NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
stdcall;
>>>function Invoke(DispID: Integer; const IID: TGUID; LocaleID:
>>>Integer;
>>>Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
>>>HResult; stdcall;
>>>end;
>>>
>>>All methods are stubs - just return S_OK. Then I attempt to connect
my
>>>class
>>>as a sink to the Items collection:
>>
>>I suppose you should return that you implement a certain method (fixed
>Name)
>>for it to call you back on that ID. There was a nice tutorial for COM
>>callbacks / event sinks etc. for Delphi online. Let me know if you
can't
>>find it (had found it using Copernic agent)
>>
>>
>>--
>>-----
>>George Birbilis (XXXX@XXXXX.COM)
>>Microsoft Most Valuable Professional
>>MVP J# for 2004 & 2005
>>www.kagi.com/birbilis
>>--------------
>>
>>
>
>