Click Event Context

Add-in Express™ Support Service
That's what is more important than anything else

Click Event Context
 
Rick Koch




Posts: 172
Joined: 2006-09-05
using VSTO;
using C#;
using Outlook 2003;

I'm writing click event handlers for Explorer and Inspector commandbar buttons. I've used the standard "button.click += new..." syntax to generate stubs. I've noticed that the function prototypes all have a single "object sender" parameter.

I need a reference back to the explorer.selection or inspector.currentitem. Can I get there via the sender parameter? Or am I supposed to retrieve ActiveExplorer() and ActiveInspector()? I can do that, but it seems "kludgy" -- is it absolutely reliable? I don't know that the threading would ever permit it to happen, but I'm worried that by the time I evaluate Active Explorer() or ActiveInspector() the user might have changed focus. Is my event guaranteed to fire before the user gets a chance to switch to another window?
Posted 19 Sep, 2006 14:18:28 Top
Matt Driver


Matt


Posts: 152
Joined: 2004-08-17
Hi

How I am doing the above reliably;

Explorer events:

object currentItem = null; //defined as object as we don't know type of object when we get it

Outlook.Explorer activeExplorer = null;
Outlook.Selection selItem = null;

Outlook.MailItem MailItem = null;
activeExplorer = OutlookApp.ActiveExplorer();
selItem = activeExplorer.Selection;
currentItem = selItem[1];
uint itemClass = Convert.ToUInt32(currentItem.GetType().InvokeMember("Class", BindingFlags.GetProperty, null, currentItem, null));
if (itemClass == (uint)Outlook.OlObjectClass.olMail)
{
carry on
}

This basically gets the active explorer selected item and does something if it is a mail item.

Inspector:

Outlook.MailItem MailItem = null;
Outlook.Inspector activeInspector = null;
activeInspector = OutlookApp.ActiveInspector();
MailItem = (Outlook.MailItem) activeInspector.CurrentItem;
if (MailItem != null)
{
uint itemclass = (uint)MailItem.Class;
if (itemclass == (uint)43)
{
we have a mail item so do something
}

Just remember where every you create a variable to a object e.g. MailItem or Inspector or Explorer

do the following after you have finished with it:

if (MailItem != null)
{
Marshal.ReleaseComObject(MailItem);
MailItem = null;
}

This stops outlook hanging around when you close the add-in etc.

Remember never release any ADX build in objects though as it will crash the add-in


I have this deployed to 200+ reliable. I think the sender is ADX so not sure what you can do with that.

Just my thoughts Matt
Posted 19 Sep, 2006 16:47:03 Top
Matt Driver


Matt


Posts: 152
Joined: 2004-08-17
Oh Events fire correctly before the user gets a chance to do anything.

Matt
Posted 19 Sep, 2006 16:47:44 Top
Rick Koch




Posts: 172
Joined: 2006-09-05
Thanks. That's pretty much what I'm doing.

Are you using the .Net/VSTO version? Does Marshal.ReleaseComObject apply to the .Net/VSTO version?
Posted 19 Sep, 2006 17:42:34 Top
Matt Driver


Matt


Posts: 152
Joined: 2004-08-17
I'm using pure .net ADX not VSTO so I don't know about VSTO but I would expect it to be the same. I would try releasing an object and if you get an exception when releasing then you don't need to release this is how I learnt how to do it although I had a developer guy that used to work at Microsoft working with me so I have a little inside help (nice when you need it)

matt
Posted 19 Sep, 2006 17:51:19 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi Rick.

I've used the standard "button.click += new..." syntax to generate stubs.

Why don't you use the designer to add events in the add-in code?

Rick, you should use the Marshal.ReleaseComObject method whenever you manipulate Outlook objects. The 'sender' is a parameter to be used to determine what ADX component has raised the event. It allows you to use the same event handler for several components.
Posted 20 Sep, 2006 07:53:38 Top
Rick Koch




Posts: 172
Joined: 2006-09-05
Sergey Grischenko wrote:
Why don't you use the designer to add events in the add-in code?


How is this done in C#? I can only find examples for VB.

Sergey Grischenko wrote:
The 'sender' is a parameter to be used to determine what ADX component has raised the event.


Is there a type associated with this? How do I use sender to identify the selected item without having to poll for the ActiveExplorer or the ActiveInspector?

Sergey Grischenko wrote:
you should use the Marshal.ReleaseComObject method whenever you manipulate Outlook objects


I thought the point of VSTO is that we don't manipulate COM objects; that this manipulation is done by generated code that we don't see, and that the Dispose methods of that code would release the COM objects? Is that not the theory? I guess it's still not clear to me whether any of the objects that are accessible to me actually are "COM" objects at all. If I'm referencing a managed code object which is referencing a COM object, exactly which object is available for me to ReleaseComObject on that actually refers to the underlying COM object in the first place?

I'm not trying to be argumentative; I'm simply trying to understand what may be Microsoft's most poorly-documented programming model to date.
Posted 21 Sep, 2006 14:48:08 Top
Rick Koch




Posts: 172
Joined: 2006-09-05
Okay, I finally found the event wire-up in the designer. Pretty well hidden!

Still need to know how to get from object sender to the actual selection/item that was associated with the click.
Posted 21 Sep, 2006 15:20:26 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi Rick.

The item associated with click is:
Outlook.Inspector insp = OutlookApp.ActiveInspector();

I thought the point of VSTO is that we don't manipulate COM objects; that this manipulation is done by generated code that we don't see, and that the Dispose methods of that code would release the COM objects?

VSTO runtimes knows nothing about COM objects that you use in the add-in code. So you will have to release them manually in the code.
Posted 21 Sep, 2006 17:09:15 Top
Rick Koch




Posts: 172
Joined: 2006-09-05
Using ReleaseComObject in VSTO 2005 seems contrary to some stuff I've seen from Microsoft.

"In particular calling ReleaseComObject on references to Outlook objects is a bad idea - although superficially it may seem like a good one (See the VSTO book by Carter and Lippert, p940)"

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=291185&SiteID=1
Posted 22 Sep, 2006 07:59:59 Top