Outlook "To-Do" bar with Addin

J

John C

I have written an Add-in to trap appointment item events, add, change and
(with some tricks using explorer selection change) delete actions by users.

My problem now is that I can not see when an appointment item is deleted via
the "To-Do" bar.

Is there any way to trap an event in the TO-DO bar?

Or is there some other way to see when and which item has been deleted?
 
K

Ken Slovak - [MVP - Outlook]

For Outlook 2007 you can use the BeforeItemMove() event of the calendar
Folder object. The item being moved is the first argument passed to that
event handler, the second argument is null if the item is being deleted. The
Cancel argument can be set to true if you want to cancel the deletion.

Items shown in the ToDo Bar are the normal items with various task
properties added to them. If you use a MAPI viewer such as MFCMAPI or
OutlookSpy (www.redemption.com) you can see which task properties are added
to the items so they show up in the ToDo Bar, which feeds from the hidden
search folder To-Do Search under the store root folder.
 
J

John C

Ken,

thanks for the answer and your book, I have it in front of me now.

I was upgrading an old VB6 addin and still using the MAPIFolder which does
not have the BeforeItemMove. This will fix my problems and remove the need
for my complex Explorer code to catch which items are changed/deleted.

But going back to the original question, out of interest, are there any
"TO-DO" bar specific (appointment) events? ala Exporer.SelectionChange?

In fact can we do anything with the To-Do bar in a addin?

Regards

John
 
K

Ken Slovak - [MVP - Outlook]

Well, any changes to the underlying items that are shown in the ToDo Bar
will fire the appropriate changes in the items themselves (PropertyChange
and so on) of course.

Then, to be sneaky, the hidden search folder that the ToDo Bar relies on is
just another folder to MAPI. If you get a handle to it using the new Store
and Folder objects in Outlook 2007 you can handle any folder event that
would fire in any other folder. The Items collection in the ToDo Bar search
folder will also fire events, as the contents are updated based on the MAPI
search restriction on the folder.

I've used those tricks for years with various search folders using
Redemption, but it works nicely with the new stuff added to the Outlook
object model in Outlook 2007.
 
J

John C

Ken,

thanks again. I will look at this in the morning, its getting late here in
The Netherlands.
Tried to find the hidden folders using MFCMAPI without success...will write
some code in the morning.


Regards

John
 
J

John C

Ken,

Not had time to look at the hidden folders yet due to a problem with the
BeforeItemMove.

It does not fire in the following situation.

1. Start outlook and create an appointment "A" for today and then exit
outlook.

2. Start outlook, with the addin and then, AS THE FIRST ACTION, delete the
appointment "A" in the TO-DO bar, i.e. select it with the mouse and hit the
delete key.
The event does not fire. (In my outlook the explorer starts in the inbox
with the to-do bar visible)

3. Now open your Calendar, create a new appointment "B" for today. It shows
up in the TO-DO bar, select it with the mouse and hit delete. The event now
fires.

The event hook up is in the OnConnection code and I see in debug mode that
this has been executed before I deleted "A"

Any ideas?

Also I see that more people are having (other) problems with this event.
(see http://www.outlookcode.com/threads.aspx?forumid=5&messageid=27927)
 
K

Ken Slovak - [MVP - Outlook]

I'd have to check out that situation, I haven't seen the problem myself.
I'll try to get a chance today to fix up some code to handle that event and
see what happens with it. Or, if your code is short enough and you can post
it here I can sample that as part of a test.
 
J

John C

Ken,

Here is a sample, I just deleted all the non-relevant code from my addin

namespace TODOTest
{
using System;
using Extensibility;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using stdole;
using System.Drawing;
using System.Text;
using System.Diagnostics;


#region Read me for Add-in installation and setup information.

// When run, the Add-in wizard prepared the registry for the Add-in.
// At a later time, if the Add-in becomes unavailable for reasons such as:
// 1) You moved this project to a computer other than which is was
originally created on.
// 2) You chose 'Yes' when presented with a message asking if you wish
to remove the Add-in.
// 3) Registry corruption.
// you will need to re-register the Add-in by building the MyAddin1Setup
project,
// right click the project in the Solution Explorer, then choose install.
//
//
// When using this template make sure to change the AssemblyInfo module
to use your own
// settings and change the addin GUID to a new unique GUID, as well as
changing the
// ProgId for the addin.
//
// Also change the target folder for deployment in the Setup project.
//
//
// This template does not include a shim, recommended for any shared
managed code addin,
// a shim that can be modified for use with this template is included
with the shared
// addins available for download from the Office Web site.

#endregion

/// <summary>
/// The object for implementing an Add-in.
/// </summary>
/// <see also class='IDTExtensibility2' />
[GuidAttribute("162B9E04-2ADB-481D-867E-8D8A4FBAC54F"),
ProgId("TODOTest.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
#region Module_level_declarations
public static string m_ProgID = "";

// start of COM objects

private object applicationObject = null;

public Outlook.Application m_Outlook = null;
public Outlook.NameSpace m_NameSpace = null;

private Office.COMAddIn addInInstance = null;

private Outlook.Folder m_Folder = null;
private Outlook.Items m_Items = null;

// end of COM objects

//Initialization flags
private bool m_Teardown = false;

private bool m_Init = false;

#endregion

/// <summary>
/// Implements the constructor for the Add-in object.
/// Place your initialization code within this method.
/// </summary>
public Connect()
{
}
#region Startup_Shutdown
/// <summary>
/// Implements the OnConnection method of the IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array
custom)
{
Debug.WriteLine("Connect - OnConnection");

applicationObject = application;


try
{
addInInstance = (Office.COMAddIn)addInInst;
}
catch
{
addInInstance = null;
}

if (addInInstance != null)
{
//set module level reference to COMAddIn object
try
{
m_Outlook = (Outlook.Application)application;
m_NameSpace = m_Outlook.GetNamespace("MAPI");

try
{
//put ProgID in a module level variable
m_ProgID = addInInstance.ProgId;

//addInInstance.Object = Me
addInInstance.GetType().InvokeMember("Object",
BindingFlags.Public | BindingFlags.SetProperty, null, addInInst, new object[]
{ this });

m_Teardown = false;

m_Folder =
(Outlook.Folder)m_NameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
m_Folder.BeforeItemMove += new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
else TearDown();
}



/// <summary>
/// Implements the OnDisconnection method of the
IDTExtensibility2 interface.
/// Receives notification that the Add-in is being unloaded.
/// </summary>
/// <param term='disconnectMode'>
/// Describes how the Add-in is being unloaded.
/// </param>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
Debug.WriteLine("Connect - OnDisconnection");
if (m_Teardown == false) TearDown();
}

/// <summary>
/// Implements the OnAddInsUpdate method of the
IDTExtensibility2 interface.
/// Receives notification that the collection of Add-ins has
changed.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref System.Array custom)
{
Debug.WriteLine("Connect - OnAddInsUpdate");
}

/// <summary>
/// Implements the OnStartupComplete method of the
IDTExtensibility2 interface.
/// Receives notification that the host application has
completed loading.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnStartupComplete(ref System.Array custom)
{
Debug.WriteLine("Connect - OnStartupComplete");

}

/// <summary>
/// Implements the OnBeginShutdown method of the
IDTExtensibility2 interface.
/// Receives notification that the host application is being
unloaded.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnBeginShutdown(ref System.Array custom)
{
Debug.WriteLine("Connect - OnBeginShutdown");

}

#endregion

#region utility_procedures
public void InitHandler()
{
Debug.WriteLine("Connect - InitHandler");


//set initialization flag
m_Init = true;
}

private void TearDown()
{
Debug.WriteLine("Connect - TearDown");

if (m_Teardown == false)
{
try
{

if (m_Folder != null)
{
m_Folder.BeforeItemMove -= new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);
m_Folder = null;
}
if (m_NameSpace != null)
{
m_NameSpace = null;
}
if (m_Outlook != null)
{
m_Outlook = null;
}
if (applicationObject != null)
{
applicationObject = null;
}
if (addInInstance != null)
{
addInInstance = null;
}
m_Teardown = true;
m_Init = false;

GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
#endregion

void m_Folder_BeforeItemMove(object Item,
Microsoft.Office.Interop.Outlook.MAPIFolder MoveTo, ref bool Cancel)
{
Debug.WriteLine("Connect - m_Folder_BeforeItemMove");

Outlook.AppointmentItem _apItem = (Outlook.AppointmentItem)Item;

Debug.WriteLine(_apItem.Subject);

_apItem = null;

}
}

}
//END====================================
 
J

John C

Ken,

Just read an answer you gave to another forum question about search folders:-

" 21 Mar 2007 1:24 PMKen Slovak - [MVP - Outlook]
Sorry, that's the way search folders work. Even if you use a MAPI viewer to
examine the search folders under the hidden Finder folder you will only see
those search folders that are active. I don't know of any way to force that."

Could this be part of the problem? i.e. if the search folder is not in some
way active that the event does not fire?

John.


John C said:
Ken,

Here is a sample, I just deleted all the non-relevant code from my addin

namespace TODOTest
{
using System;
using Extensibility;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using stdole;
using System.Drawing;
using System.Text;
using System.Diagnostics;


#region Read me for Add-in installation and setup information.

// When run, the Add-in wizard prepared the registry for the Add-in.
// At a later time, if the Add-in becomes unavailable for reasons such as:
// 1) You moved this project to a computer other than which is was
originally created on.
// 2) You chose 'Yes' when presented with a message asking if you wish
to remove the Add-in.
// 3) Registry corruption.
// you will need to re-register the Add-in by building the MyAddin1Setup
project,
// right click the project in the Solution Explorer, then choose install.
//
//
// When using this template make sure to change the AssemblyInfo module
to use your own
// settings and change the addin GUID to a new unique GUID, as well as
changing the
// ProgId for the addin.
//
// Also change the target folder for deployment in the Setup project.
//
//
// This template does not include a shim, recommended for any shared
managed code addin,
// a shim that can be modified for use with this template is included
with the shared
// addins available for download from the Office Web site.

#endregion

/// <summary>
/// The object for implementing an Add-in.
/// </summary>
/// <see also class='IDTExtensibility2' />
[GuidAttribute("162B9E04-2ADB-481D-867E-8D8A4FBAC54F"),
ProgId("TODOTest.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
#region Module_level_declarations
public static string m_ProgID = "";

// start of COM objects

private object applicationObject = null;

public Outlook.Application m_Outlook = null;
public Outlook.NameSpace m_NameSpace = null;

private Office.COMAddIn addInInstance = null;

private Outlook.Folder m_Folder = null;
private Outlook.Items m_Items = null;

// end of COM objects

//Initialization flags
private bool m_Teardown = false;

private bool m_Init = false;

#endregion

/// <summary>
/// Implements the constructor for the Add-in object.
/// Place your initialization code within this method.
/// </summary>
public Connect()
{
}
#region Startup_Shutdown
/// <summary>
/// Implements the OnConnection method of the IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array
custom)
{
Debug.WriteLine("Connect - OnConnection");

applicationObject = application;


try
{
addInInstance = (Office.COMAddIn)addInInst;
}
catch
{
addInInstance = null;
}

if (addInInstance != null)
{
//set module level reference to COMAddIn object
try
{
m_Outlook = (Outlook.Application)application;
m_NameSpace = m_Outlook.GetNamespace("MAPI");

try
{
//put ProgID in a module level variable
m_ProgID = addInInstance.ProgId;

//addInInstance.Object = Me
addInInstance.GetType().InvokeMember("Object",
BindingFlags.Public | BindingFlags.SetProperty, null, addInInst, new object[]
{ this });

m_Teardown = false;

m_Folder =
(Outlook.Folder)m_NameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
m_Folder.BeforeItemMove += new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
else TearDown();
}



/// <summary>
/// Implements the OnDisconnection method of the
IDTExtensibility2 interface.
/// Receives notification that the Add-in is being unloaded.
/// </summary>
/// <param term='disconnectMode'>
/// Describes how the Add-in is being unloaded.
/// </param>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
Debug.WriteLine("Connect - OnDisconnection");
if (m_Teardown == false) TearDown();
}

/// <summary>
/// Implements the OnAddInsUpdate method of the
IDTExtensibility2 interface.
/// Receives notification that the collection of Add-ins has
changed.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref System.Array custom)
{
Debug.WriteLine("Connect - OnAddInsUpdate");
}

/// <summary>
/// Implements the OnStartupComplete method of the
IDTExtensibility2 interface.
/// Receives notification that the host application has
completed loading.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnStartupComplete(ref System.Array custom)
{
Debug.WriteLine("Connect - OnStartupComplete");

}

/// <summary>
/// Implements the OnBeginShutdown method of the
IDTExtensibility2 interface.
/// Receives notification that the host application is being
unloaded.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnBeginShutdown(ref System.Array custom)
{
Debug.WriteLine("Connect - OnBeginShutdown");

}

#endregion

#region utility_procedures
public void InitHandler()
{
Debug.WriteLine("Connect - InitHandler");


//set initialization flag
m_Init = true;
}

private void TearDown()
{
Debug.WriteLine("Connect - TearDown");

if (m_Teardown == false)
{
try
{

if (m_Folder != null)
{
m_Folder.BeforeItemMove -= new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);
m_Folder = null;
}
if (m_NameSpace != null)
{
m_NameSpace = null;
}
if (m_Outlook != null)
{
m_Outlook = null;
}
if (applicationObject != null)
{
applicationObject = null;
}
if (addInInstance != null)
{
addInInstance = null;
}
m_Teardown = true;
m_Init = false;

GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
#endregion

void m_Folder_BeforeItemMove(object Item,
Microsoft.Office.Interop.Outlook.MAPIFolder MoveTo, ref bool Cancel)
{
Debug.WriteLine("Connect - m_Folder_BeforeItemMove");

Outlook.AppointmentItem _apItem = (Outlook.AppointmentItem)Item;

Debug.WriteLine(_apItem.Subject);

_apItem = null;
 
K

Ken Slovak - [MVP - Outlook]

You're not using that event in a search folder, you're using it in the
default Calendar folder.
 
K

Ken Slovak - [MVP - Outlook]

I ran your test code and replicated your steps 1 & 2. Deleting the
appointment from the ToDo bar didn't fire the BeforeItemMove event in the
calendar. But on step 3 when I deleted appointment B from the ToDo bar it
also did not fire the event. The event only fired when I deleted the
appointments from the calendar folder itself.

I then looked at the contents of the ToDo search folder and the appointments
aren't listed there. I can only assume that in this case the listing of the
appointments is from the instant search and not from the ToDo search folder.

I'll see what I can find out about this behavior and let you know what I
find out.




John C said:
Ken,

Here is a sample, I just deleted all the non-relevant code from my addin

namespace TODOTest
{
using System;
using Extensibility;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using stdole;
using System.Drawing;
using System.Text;
using System.Diagnostics;


#region Read me for Add-in installation and setup information.

// When run, the Add-in wizard prepared the registry for the Add-in.
// At a later time, if the Add-in becomes unavailable for reasons such
as:
// 1) You moved this project to a computer other than which is was
originally created on.
// 2) You chose 'Yes' when presented with a message asking if you
wish
to remove the Add-in.
// 3) Registry corruption.
// you will need to re-register the Add-in by building the
MyAddin1Setup
project,
// right click the project in the Solution Explorer, then choose
install.
//
//
// When using this template make sure to change the AssemblyInfo module
to use your own
// settings and change the addin GUID to a new unique GUID, as well
as
changing the
// ProgId for the addin.
//
// Also change the target folder for deployment in the Setup project.
//
//
// This template does not include a shim, recommended for any shared
managed code addin,
// a shim that can be modified for use with this template is included
with the shared
// addins available for download from the Office Web site.

#endregion

/// <summary>
/// The object for implementing an Add-in.
/// </summary>
/// <see also class='IDTExtensibility2' />
[GuidAttribute("162B9E04-2ADB-481D-867E-8D8A4FBAC54F"),
ProgId("TODOTest.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
#region Module_level_declarations
public static string m_ProgID = "";

// start of COM objects

private object applicationObject = null;

public Outlook.Application m_Outlook = null;
public Outlook.NameSpace m_NameSpace = null;

private Office.COMAddIn addInInstance = null;

private Outlook.Folder m_Folder = null;
private Outlook.Items m_Items = null;

// end of COM objects

//Initialization flags
private bool m_Teardown = false;

private bool m_Init = false;

#endregion

/// <summary>
/// Implements the constructor for the Add-in object.
/// Place your initialization code within this method.
/// </summary>
public Connect()
{
}
#region Startup_Shutdown
/// <summary>
/// Implements the OnConnection method of the
IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref
System.Array
custom)
{
Debug.WriteLine("Connect - OnConnection");

applicationObject = application;


try
{
addInInstance = (Office.COMAddIn)addInInst;
}
catch
{
addInInstance = null;
}

if (addInInstance != null)
{
//set module level reference to COMAddIn object
try
{
m_Outlook = (Outlook.Application)application;
m_NameSpace = m_Outlook.GetNamespace("MAPI");

try
{
//put ProgID in a module level variable
m_ProgID = addInInstance.ProgId;

//addInInstance.Object = Me
addInInstance.GetType().InvokeMember("Object",
BindingFlags.Public | BindingFlags.SetProperty, null, addInInst, new
object[]
{ this });

m_Teardown = false;

m_Folder =
(Outlook.Folder)m_NameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
m_Folder.BeforeItemMove += new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
else TearDown();
}



/// <summary>
/// Implements the OnDisconnection method of the
IDTExtensibility2 interface.
/// Receives notification that the Add-in is being unloaded.
/// </summary>
/// <param term='disconnectMode'>
/// Describes how the Add-in is being unloaded.
/// </param>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
Debug.WriteLine("Connect - OnDisconnection");
if (m_Teardown == false) TearDown();
}

/// <summary>
/// Implements the OnAddInsUpdate method of the
IDTExtensibility2 interface.
/// Receives notification that the collection of Add-ins has
changed.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref System.Array custom)
{
Debug.WriteLine("Connect - OnAddInsUpdate");
}

/// <summary>
/// Implements the OnStartupComplete method of the
IDTExtensibility2 interface.
/// Receives notification that the host application has
completed loading.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnStartupComplete(ref System.Array custom)
{
Debug.WriteLine("Connect - OnStartupComplete");

}

/// <summary>
/// Implements the OnBeginShutdown method of the
IDTExtensibility2 interface.
/// Receives notification that the host application is being
unloaded.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnBeginShutdown(ref System.Array custom)
{
Debug.WriteLine("Connect - OnBeginShutdown");

}

#endregion

#region utility_procedures
public void InitHandler()
{
Debug.WriteLine("Connect - InitHandler");


//set initialization flag
m_Init = true;
}

private void TearDown()
{
Debug.WriteLine("Connect - TearDown");

if (m_Teardown == false)
{
try
{

if (m_Folder != null)
{
m_Folder.BeforeItemMove -= new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);
m_Folder = null;
}
if (m_NameSpace != null)
{
m_NameSpace = null;
}
if (m_Outlook != null)
{
m_Outlook = null;
}
if (applicationObject != null)
{
applicationObject = null;
}
if (addInInstance != null)
{
addInInstance = null;
}
m_Teardown = true;
m_Init = false;

GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
#endregion

void m_Folder_BeforeItemMove(object Item,
Microsoft.Office.Interop.Outlook.MAPIFolder MoveTo, ref bool Cancel)
{
Debug.WriteLine("Connect - m_Folder_BeforeItemMove");

Outlook.AppointmentItem _apItem =
(Outlook.AppointmentItem)Item;

Debug.WriteLine(_apItem.Subject);

_apItem = null;

}
}

}
//END====================================

Ken Slovak - said:
I'd have to check out that situation, I haven't seen the problem myself.
I'll try to get a chance today to fix up some code to handle that event
and
see what happens with it. Or, if your code is short enough and you can
post
it here I can sample that as part of a test.
 
J

John C

Ken,

Thank you I will look forward to what you can find.

If I create an Item and then delete it from the to-do bar the event fires.

Regards

John.

Ken Slovak - said:
I ran your test code and replicated your steps 1 & 2. Deleting the
appointment from the ToDo bar didn't fire the BeforeItemMove event in the
calendar. But on step 3 when I deleted appointment B from the ToDo bar it
also did not fire the event. The event only fired when I deleted the
appointments from the calendar folder itself.

I then looked at the contents of the ToDo search folder and the appointments
aren't listed there. I can only assume that in this case the listing of the
appointments is from the instant search and not from the ToDo search folder.

I'll see what I can find out about this behavior and let you know what I
find out.




John C said:
Ken,

Here is a sample, I just deleted all the non-relevant code from my addin

namespace TODOTest
{
using System;
using Extensibility;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using stdole;
using System.Drawing;
using System.Text;
using System.Diagnostics;


#region Read me for Add-in installation and setup information.

// When run, the Add-in wizard prepared the registry for the Add-in.
// At a later time, if the Add-in becomes unavailable for reasons such
as:
// 1) You moved this project to a computer other than which is was
originally created on.
// 2) You chose 'Yes' when presented with a message asking if you
wish
to remove the Add-in.
// 3) Registry corruption.
// you will need to re-register the Add-in by building the
MyAddin1Setup
project,
// right click the project in the Solution Explorer, then choose
install.
//
//
// When using this template make sure to change the AssemblyInfo module
to use your own
// settings and change the addin GUID to a new unique GUID, as well
as
changing the
// ProgId for the addin.
//
// Also change the target folder for deployment in the Setup project.
//
//
// This template does not include a shim, recommended for any shared
managed code addin,
// a shim that can be modified for use with this template is included
with the shared
// addins available for download from the Office Web site.

#endregion

/// <summary>
/// The object for implementing an Add-in.
/// </summary>
/// <see also class='IDTExtensibility2' />
[GuidAttribute("162B9E04-2ADB-481D-867E-8D8A4FBAC54F"),
ProgId("TODOTest.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
#region Module_level_declarations
public static string m_ProgID = "";

// start of COM objects

private object applicationObject = null;

public Outlook.Application m_Outlook = null;
public Outlook.NameSpace m_NameSpace = null;

private Office.COMAddIn addInInstance = null;

private Outlook.Folder m_Folder = null;
private Outlook.Items m_Items = null;

// end of COM objects

//Initialization flags
private bool m_Teardown = false;

private bool m_Init = false;

#endregion

/// <summary>
/// Implements the constructor for the Add-in object.
/// Place your initialization code within this method.
/// </summary>
public Connect()
{
}
#region Startup_Shutdown
/// <summary>
/// Implements the OnConnection method of the
IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref
System.Array
custom)
{
Debug.WriteLine("Connect - OnConnection");

applicationObject = application;


try
{
addInInstance = (Office.COMAddIn)addInInst;
}
catch
{
addInInstance = null;
}

if (addInInstance != null)
{
//set module level reference to COMAddIn object
try
{
m_Outlook = (Outlook.Application)application;
m_NameSpace = m_Outlook.GetNamespace("MAPI");

try
{
//put ProgID in a module level variable
m_ProgID = addInInstance.ProgId;

//addInInstance.Object = Me
addInInstance.GetType().InvokeMember("Object",
BindingFlags.Public | BindingFlags.SetProperty, null, addInInst, new
object[]
{ this });

m_Teardown = false;

m_Folder =
(Outlook.Folder)m_NameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
m_Folder.BeforeItemMove += new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
else TearDown();
}



/// <summary>
/// Implements the OnDisconnection method of the
IDTExtensibility2 interface.
/// Receives notification that the Add-in is being unloaded.
/// </summary>
/// <param term='disconnectMode'>
/// Describes how the Add-in is being unloaded.
/// </param>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
Debug.WriteLine("Connect - OnDisconnection");
if (m_Teardown == false) TearDown();
}

/// <summary>
/// Implements the OnAddInsUpdate method of the
IDTExtensibility2 interface.
/// Receives notification that the collection of Add-ins has
changed.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref System.Array custom)
{
Debug.WriteLine("Connect - OnAddInsUpdate");
}

/// <summary>
/// Implements the OnStartupComplete method of the
IDTExtensibility2 interface.
/// Receives notification that the host application has
completed loading.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnStartupComplete(ref System.Array custom)
{
Debug.WriteLine("Connect - OnStartupComplete");

}

/// <summary>
/// Implements the OnBeginShutdown method of the
IDTExtensibility2 interface.
/// Receives notification that the host application is being
unloaded.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnBeginShutdown(ref System.Array custom)
{
Debug.WriteLine("Connect - OnBeginShutdown");

}

#endregion

#region utility_procedures
public void InitHandler()
{
Debug.WriteLine("Connect - InitHandler");


//set initialization flag
m_Init = true;
}

private void TearDown()
{
Debug.WriteLine("Connect - TearDown");

if (m_Teardown == false)
{
try
{

if (m_Folder != null)
{
m_Folder.BeforeItemMove -= new
Microsoft.Office.Interop.Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(m_Folder_BeforeItemMove);
m_Folder = null;
}
if (m_NameSpace != null)
{
m_NameSpace = null;
}
if (m_Outlook != null)
{
m_Outlook = null;
}
if (applicationObject != null)
 
K

Ken Slovak - [MVP - Outlook]

I mentioned what's happening with BeforeItemMove to the owner of the Outlook
object on the Outlook product group, and another MVP (Sue Mosher) also
mentioned some reports she's had (I copied her on the email). He replied
that he's had other reports of similar things and will investigate.

So for now let's say that the event cannot be necessarily relied on and hope
that they find the problem and the fix soon enough to get it into Outlook
2007 SP2. If not it would take a hot fix.

Now that this is in the correct hands I don't expect any updates or new
information for a while.
 
J

John C

Thanks for the quick action in bringing this to Outlook groups attention.

The wait begins....

John.
 
S

Shaohua Liu

This is a related question. I am trying to get the selected item in To-Do Bar in my addin. My addin needs to process taskItem when users took action on them, for example, "Mark Complete". I can find out which TaskItem is selected in the "Tasks" list, by registering to the SelectionChange event on the explorer. But this event is not fired when user selects a task in the To-Do bar.

Is there a way for my addin to get the selected item in To-Do bar?

Thanks a lot.

Shaohua
 

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