none
Closing inspector window RRS feed

  • Question

  • Hi all,

    This might be considered a stupid thing to do, but here we go. I'm trying to close an appointment item inspector which is associated with a task item and open the task item instead. Thus, if the user clicks on the calendar item, the form region code will load. It will check check the item has a user property associated with it. If it has one, it will locate the correct task item and open it. Afterwards it should close the calendar item. Needless to say, I haven't got it working yet ... All I manage to do is crash Outlook.

    I'm working with Outlook 2010 and Visual Studio 2010.

    So, my question(s):

    • Is this possible?
    • Is there another way of doing this?

    I have tried the following:

    Appointment Item Form Region:

            private void AppointmentRegion_FormRegionShowing(object sender, System.EventArgs e)
            {
    			((Microsoft.Office.Interop.Outlook._AppointmentItem)this.OutlookItem).GetInspector.Deactivate += new InspectorEvents_10_DeactivateEventHandler(GetInspector_Deactivate);		
    		
                TaskItem tmpTaskObj = null;
                // located the task item and instantiate it... 
                tmpTaskObj.Display();                                                          
    			tmpTaskObj.GetInspector.Activate();
    		}
    		
            private void GetInspector_Deactivate()
            {
                ((Microsoft.Office.Interop.Outlook._AppointmentItem)this.OutlookItem).GetInspector.Close(OlInspectorClose.olDiscard);
            }

    This doesn't work, because the task item cannot get the focus, even though I called the Activate method.

    Many thanks in advance!


    GMT + 2:00 South Africa
    Kind Regards
    Richard


    • Edited by RGA Bailey Tuesday, March 6, 2012 3:35 PM Update
    Tuesday, March 6, 2012 3:26 PM

Answers

  • I'd most likely use a timer that's set in the event handler and fires after the handler ends. I'd then synch the timer to the main addin thread context if using a System.Timers.Timer object, or I'd just use a Windows.Form timer where the form was created in the main thread so the timer fires on that thread.
     
    The object model can only be used from the main  thread unless you want to crash or hang Outlook, so the thread contexts are important.

    --
    Ken Slovak
    [MVP - Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    Reminder Manager, Extended Reminders, Attachment Options
    http://www.slovaktech.com/products.htm
     
     
    "RGA Bailey" <=?utf-8?B?UkdBIEJhaWxleQ==?=> wrote in message news:fb370bbc-b0c7-443c-a47f-9c39420b0c6e...

    Hi Ken,

    Also tried the following without any success - still crashes Outlook:

    The Activate event fires as soon as the Display is called. Thus the appointment form region is still open when I call the close. This is obviously causing the crash. I have no idea how to fire an event that fires after the FormShowing ??

        public partial class ThisAddIn
        {        
            private Inspectors _inspectors = null;
            private Inspector _inspector = null;        
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                this._inspectors = this.Application.Inspectors;
                this._inspectors.NewInspector += new InspectorsEvents_NewInspectorEventHandler(NewInspector);
            }
    
            private void NewInspector(Inspector Inspector)
            {
                if (Inspector.CurrentItem is TaskItem)
                {
                    this._inspector = Inspector;
                    ((InspectorEvents_10_Event)this._inspector).Activate += new InspectorEvents_10_ActivateEventHandler(Inspector_Activate);
                }
            }
    
            private void Inspector_Activate()
            {
                if (this._inspector != null)
                {                
                    foreach (var item in this.Application.Inspectors)
                    {
                        if (((Inspector)item).CurrentItem is AppointmentItem)
                        {
                            AppointmentItem tmpAppointItem = ((Inspector)item).CurrentItem;
    
                            if (tmpAppointItem.UserProperties.Count > 0)
                            {
                                UserProperty instanceID = tmpAppointItem.UserProperties.Find("InstanceID", Type.Missing);
                                if (instanceID != null)
                                {
                                    tmpAppointItem.GetInspector.Close(OlInspectorClose.olDiscard);
                                }
                            }
                        }
                    }
                }
            }

    Thanks again!


    GMT + 2:00 South Africa
    Kind Regards
    Richard




    Ken Slovak MVP - Outlook
    Thursday, March 8, 2012 4:23 PM
    Moderator

All replies

  • Will it stop crashing if you comment out closing of inspector in deactivate event?
    Tuesday, March 6, 2012 4:01 PM
  • Handle NewInspector() for the second item and when that fires its first Activate() event close the original item. You can't close an item within its own Deactivate() handler.

    --
    Ken Slovak
    [MVP - Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    Reminder Manager, Extended Reminders, Attachment Options
    http://www.slovaktech.com/products.htm
     
     
    "RGA Bailey" <=?utf-8?B?UkdBIEJhaWxleQ==?=> wrote in message news:f9a349c8-6157-4929-9ff0-5ac07eb05acf...

    Hi all,

    This might be considered a stupid thing to do, but here we go. I'm trying to close an appointment item inspector which is associated with a task item and open the task item instead. Thus, if the user clicks on the calendar item, the form region code will load. It will check check the item has a user property associated with it. If it has one, it will locate the correct task item and open it. Afterwards it should close the calendar item. Needless to say, I haven't got it working yet ... All I manage to do is crash Outlook.

    I'm working with Outlook 2010 and Visual Studio 2010.

    So, my question(s):

    • Is this possible?
    • Is there another way of doing this?

    I have tried the following:

    Appointment Item Form Region:

            private void AppointmentRegion_FormRegionShowing(object sender, System.EventArgs e)
            {
    			((Microsoft.Office.Interop.Outlook._AppointmentItem)this.OutlookItem).GetInspector.Deactivate += new InspectorEvents_10_DeactivateEventHandler(GetInspector_Deactivate);		
    		
                TaskItem tmpTaskObj = null;
                // located the task item and instantiate it... 
                tmpTaskObj.Display();                                                          
    			tmpTaskObj.GetInspector.Activate();
    		}
    		
            private void GetInspector_Deactivate()
            {
                ((Microsoft.Office.Interop.Outlook._AppointmentItem)this.OutlookItem).GetInspector.Close(OlInspectorClose.olDiscard);
            }

    This doesn't work, because the task item cannot get the focus, even though I called the Activate method.

    Many thanks in advance!


    GMT + 2:00 South Africa
    Kind Regards
    Richard



    Ken Slovak MVP - Outlook
    Tuesday, March 6, 2012 4:20 PM
    Moderator
  • Hi, many thanks for the response. No, if you take the code from the deactivate event and place it in the form region showing, then it will crash outlook. If that makes sense... Thanks again.

    GMT + 2:00 South Africa
    Kind Regards
    Richard

    Tuesday, March 6, 2012 4:20 PM
  • Not in FormRegionShowing(), in the Activate() event on that new Inspector. Does that still crash Outlook? You need to make sure you aren't in an event handler for the first item before you close it.

    --
    Ken Slovak
    [MVP - Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    Reminder Manager, Extended Reminders, Attachment Options
    http://www.slovaktech.com/products.htm
     
     
    "RGA Bailey" <=?utf-8?B?UkdBIEJhaWxleQ==?=> wrote in message news:3da15419-38ef-429e-84a2-94590f304b32...
    Hi, many thanks for the response. No, if you take the code from the deactivate event and place it in the form region showing, then it will crash outlook. If that makes sense... Thanks again.

    GMT + 2:00 South Africa
    Kind Regards
    Richard


    Ken Slovak MVP - Outlook
    Tuesday, March 6, 2012 4:32 PM
    Moderator
  • Hi Ken,

    Many thanks for the response.

    I'm a bit confused ... the thing is, I cannot see any activate event on an inspector object. Thus, I have no idea how to handle such an occurrence?!  This is what I have done so far:

    I have two form regions:

    1. Appointment Form Region
    2. Task Form Region

    I execute the following code within the appointment form region:

        partial class AppointmentRegion
        {
            private long _instanceId = long.MinValue;
            private void AppointmentRegion_FormRegionShowing(object sender, System.EventArgs e)
            {
                UserProperty instanceID = ((AppointmentItem)this.OutlookItem).UserProperties.Find("InstanceID", Type.Missing);
                if (qtInstanceID != null)
                {
                    this._instanceId = Convert.ToInt64(instanceID.Value);
                }
    
                NameSpace oNS = (NameSpace)Globals.ThisAddIn.Application.GetNamespace("MAPI");
                MAPIFolder oTasks = oNS.GetDefaultFolder(OlDefaultFolders.olFolderTasks);
                Items oItems = (Items)oTasks.Items;
                TaskItem tmpTaskObj = null;
    
                foreach (var olTaskItem in oItems)
                {
                    tmpTaskObj = (TaskItem)olTaskItem;
    
                    if (tmpTaskObj != null)
                    {
                        if (tmpTaskObj.UserProperties.Count.Equals(0))
                        {
                            continue;
                        }
                        else
                        {
                            if (tmpTaskObj.UserProperties["InstanceID"].Value.ToString().Equals(this._instanceId.ToString()))
                            {
                                tmpTaskObj.Display();
                                tmpTaskObj.GetInspector.Activate();
                                break;
                            }
                        }
                    }
                }
            }

    Within the task form region:

        partial class TaskRegion
        { 
            private void TaskRegion_FormRegionShowing(object sender, System.EventArgs e)
            {
                Inspectors inspectors = ((TaskItem)this.OutlookItem).Application.Inspectors;
    
                foreach (var item in inspectors)
                {
                    if (((Inspector)item).CurrentItem is AppointmentItem)
                    {
                        AppointmentItem tmpAppointItem = ((Inspector)item).CurrentItem;
    
                        if (tmpAppointItem.UserProperties.Count > 0)
                        {
                            UserProperty instanceID = tmpAppointItem.UserProperties.Find("InstanceID", Type.Missing);
                            if (instanceID != null)
                            {
                                if (this._instanceId == Convert.ToInt64(instanceID.Value))
                                {
                                    ((Inspector)item).Close(OlInspectorClose.olDiscard);
                                }
                            }
                        }
                    }
                }
            }
        }

    This still causes Outlook to crash. So it's obvious that I don't exactly understand what your saying, so could you please assist in this matter?

    Many thanks in advance!


    GMT + 2:00 South Africa
    Kind Regards
    Richard

    Wednesday, March 7, 2012 7:39 AM
  • Hi Ken,

    Also tried the following without any success - still crashes Outlook:

    The Activate event fires as soon as the Display is called. Thus the appointment form region is still open when I call the close. This is obviously causing the crash. I have no idea how to fire an event that fires after the FormShowing ??

        public partial class ThisAddIn
        {        
            private Inspectors _inspectors = null;
            private Inspector _inspector = null;        
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                this._inspectors = this.Application.Inspectors;
                this._inspectors.NewInspector += new InspectorsEvents_NewInspectorEventHandler(NewInspector);
            }
    
            private void NewInspector(Inspector Inspector)
            {
                if (Inspector.CurrentItem is TaskItem)
                {
                    this._inspector = Inspector;
                    ((InspectorEvents_10_Event)this._inspector).Activate += new InspectorEvents_10_ActivateEventHandler(Inspector_Activate);
                }
            }
    
            private void Inspector_Activate()
            {
                if (this._inspector != null)
                {                
                    foreach (var item in this.Application.Inspectors)
                    {
                        if (((Inspector)item).CurrentItem is AppointmentItem)
                        {
                            AppointmentItem tmpAppointItem = ((Inspector)item).CurrentItem;
    
                            if (tmpAppointItem.UserProperties.Count > 0)
                            {
                                UserProperty instanceID = tmpAppointItem.UserProperties.Find("InstanceID", Type.Missing);
                                if (instanceID != null)
                                {
                                    tmpAppointItem.GetInspector.Close(OlInspectorClose.olDiscard);
                                }
                            }
                        }
                    }
                }
            }

    Thanks again!


    GMT + 2:00 South Africa
    Kind Regards
    Richard



    • Edited by RGA Bailey Wednesday, March 7, 2012 8:01 AM Update
    Wednesday, March 7, 2012 7:56 AM
  • I'd most likely use a timer that's set in the event handler and fires after the handler ends. I'd then synch the timer to the main addin thread context if using a System.Timers.Timer object, or I'd just use a Windows.Form timer where the form was created in the main thread so the timer fires on that thread.
     
    The object model can only be used from the main  thread unless you want to crash or hang Outlook, so the thread contexts are important.

    --
    Ken Slovak
    [MVP - Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    Reminder Manager, Extended Reminders, Attachment Options
    http://www.slovaktech.com/products.htm
     
     
    "RGA Bailey" <=?utf-8?B?UkdBIEJhaWxleQ==?=> wrote in message news:fb370bbc-b0c7-443c-a47f-9c39420b0c6e...

    Hi Ken,

    Also tried the following without any success - still crashes Outlook:

    The Activate event fires as soon as the Display is called. Thus the appointment form region is still open when I call the close. This is obviously causing the crash. I have no idea how to fire an event that fires after the FormShowing ??

        public partial class ThisAddIn
        {        
            private Inspectors _inspectors = null;
            private Inspector _inspector = null;        
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                this._inspectors = this.Application.Inspectors;
                this._inspectors.NewInspector += new InspectorsEvents_NewInspectorEventHandler(NewInspector);
            }
    
            private void NewInspector(Inspector Inspector)
            {
                if (Inspector.CurrentItem is TaskItem)
                {
                    this._inspector = Inspector;
                    ((InspectorEvents_10_Event)this._inspector).Activate += new InspectorEvents_10_ActivateEventHandler(Inspector_Activate);
                }
            }
    
            private void Inspector_Activate()
            {
                if (this._inspector != null)
                {                
                    foreach (var item in this.Application.Inspectors)
                    {
                        if (((Inspector)item).CurrentItem is AppointmentItem)
                        {
                            AppointmentItem tmpAppointItem = ((Inspector)item).CurrentItem;
    
                            if (tmpAppointItem.UserProperties.Count > 0)
                            {
                                UserProperty instanceID = tmpAppointItem.UserProperties.Find("InstanceID", Type.Missing);
                                if (instanceID != null)
                                {
                                    tmpAppointItem.GetInspector.Close(OlInspectorClose.olDiscard);
                                }
                            }
                        }
                    }
                }
            }

    Thanks again!


    GMT + 2:00 South Africa
    Kind Regards
    Richard




    Ken Slovak MVP - Outlook
    Thursday, March 8, 2012 4:23 PM
    Moderator