Share via


Verifying Whether an Outlook Item Has Been Modified but Not Saved

Summary:  This article shows how to determine whether a Microsoft Outlook item, such as a mail item or contact item, has been modified and has not been saved.

Applies to: Office 2007 | Office 2010 | Outlook | Outlook 2007 | Outlook 2010

In this article
Overview
Solution
Code Example
Conclusion
Additional Resources

Published:  January 2011

Provided by:  Angela Chu-Hatoun, Microsoft Corporation

Contents

  • Overview

  • Solution

  • Code Example

  • Conclusion

  • Additional Resources

Overview

Microsoft Outlook supports different types of data records called items. By default, Outlook provides built-in items such as email messages, appointments, contacts, and tasks, and also supports creation of custom items. Outlook provides windows called inspectors that support item-specific forms, allowing users to add, view, and modify Outlook data that is specific to that type of item. For example, you can view and edit the start time and end time of an appointment in an appointment form that is displayed in an inspector.

Upon creating or modifying an Outlook item through the Outlook user interface, users explicitly save their changes before closing the inspectors. Programmatically, a solution can create, open, and modify data for an item. The solution explicitly calls the Save or SaveAs method of that item to save the changes. Because Outlook allows the same item to be accessed through the user interface and through code at the same time, it is common for developers to have to determine whether an Outlook item has been modified and has not yet been saved.

This article shows how to programmatically determine whether an Outlook item has been modified and has not been saved. The solution uses a dispidFDirty dispatch ID and does not require the Outlook object model. You can implement the solution in a managed or unmanaged language. This article shows sample code in C# and Visual Basic. For a C++ version of the code sample, see How to: Determine Whether an Outlook Item Has Been Modified but Not Saved in the Outlook 2010 Auxiliary Reference.

Solution

Outlook supports a dispidFDirty dispatch ID that corresponds to a property in an Outlook item, which specifies whether the item has been modified but has not been saved. To access that property, use the dispidFDirty dispatch ID to invoke that property. In managed code, call the InvokeMember(String, BindingFlags, Binder, Object, []) method, passing the item object and expressing dispidFDirty as a string argument that represents the property to invoke. In C++, call the IDispatch::Invoke method.

Code Example

The code example in this article consists of two methods: IsActiveInspectorModified and IsItemModified. IsActiveInspectorModified obtains the Outlook item in the active inspector, if any item is currently open in an inspector. If there is an active inspector, IsActiveInspectorModified calls IsItemModified, passing the item as an argument. Depending on the result returned by IsItemModified, IsActiveInspectorModified displays an appropriate message about whether the item has any unsaved changes.

IsItemModified accepts the item object, item, as an input parameter. To use the Type.InvokeMember method on the item object, IsItemModified first uses the Object.GetType() method to obtain a System.Type object for the item. Because the Type.InvokeMember method requires a dispatch ID to be expressed as a string argument to the name parameter, IsItemModified constructs the string representation of the dispidFDirty dispatch ID as dispidIsItemModifiedMemberName. IsItemModified then calls the Type.InvokeMember method, specifying the following arguments:

  • The string dispidIsItemModifiedMemberName as the argument for the name parameter.

  • The result of the logical OR operation applied to the flags System.Reflection.BindingFlags.InvokeMethod and System.Reflection.BindingFlags.GetProperty, as the argument for the invokeAttr parameter. For more information about supported flags, see the BindingFlags enumeration.

  • The Outlook item object, item, as the argument for the target parameter.

Finally, IsItemModified casts the return value from Type.InvokeMember as Boolean, and returns the Boolean value (True to indicate that the item has unsaved changes; otherwise, False).

The following is the code example written in two languages, Visual Basic and C#.

If you use Microsoft Visual Studio to test this code example, you must first add a reference to the Microsoft Outlook 14.0 Object Library component and specify the Outlook variable when you import the Microsoft.Office.Interop.Outlook namespace. The Imports or using statement must not occur directly before the functions in the code example but must be added before the public Class declaration. The following lines of code show how to do the import and assignment in Visual Basic and C#.

Imports Outlook = Microsoft.Office.Interop.Outlook
using Outlook = Microsoft.Office.Interop.Outlook;
Sub IsActiveInspectorModified()
Dim itm As Object
If (Application.ActiveInspector() Is Nothing) Then
    MessageBox.Show("ActiveInspector() returned null. You must open an inspector.", _
        "IsActiveInspectorModified", _
        MessageBoxButtons.OK, _
        MessageBoxIcon.Error)
End If
itm = Application.ActiveInspector.CurrentItem
If (IsItemModified(itm)) Then
    MessageBox.Show("Item has been modified", _
        "IsActiveInspectorModified", _
        MessageBoxButtons.OK, _
        MessageBoxIcon.Information)
Else
    MessageBox.Show("Item has not been modified", _
        "IsActiveInspectorModified", _
        MessageBoxButtons.OK, _
        MessageBoxIcon.Information)
    End If
End Sub

Public Function IsItemModified(ByVal item As Object) As Boolean
Dim typeDispatch As Type = item.GetType()
Dim dispidIsItemModifiedMemberName As String = String.Format("[DispID={0}]", _
    &HF024)
Dim retVal As Boolean = False
Try
    retVal = CType(typeDispatch.InvokeMember(dispidIsItemModifiedMemberName, _
        System.Reflection.BindingFlags.InvokeMethod _
        Or System.Reflection.BindingFlags.GetProperty, _
        Nothing, _
        item, _
        Nothing), _
        Boolean)
Catch comEx As System.Runtime.InteropServices.COMException
    Debug.WriteLine(comEx.Message)
End Try
End Function
void IsActiveInspectorModified()
{
    object item;
    if (Application.ActiveInspector() == null)
    {
        MessageBox.Show("ActiveInspector() returned null. You must open an inspector.", 
            "IsActiveInspectorModified", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
    item = Application.ActiveInspector().CurrentItem;
    if (IsItemModified(item))
    {
        MessageBox.Show("Item has been modified", 
            "IsActiveInspectorModified", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Information);
    }
    else
    {
        MessageBox.Show("Item has not been modified", 
            "IsActiveInspectorModified", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Information);
    }
}

public bool IsItemModified(object item)
{
    Type typeDispatch = item.GetType();
    string dispidIsItemModifiedMemberName = String.Format("[DispID={0}]", 0xF024);
    bool retVal = false;

    try
    {
        retVal = (bool)typeDispatch.InvokeMember(dispidIsItemModifiedMemberName,
            System.Reflection.BindingFlags.InvokeMethod |
            System.Reflection.BindingFlags.GetProperty,
            null,
            item,
            null);
    }
    catch (System.Runtime.InteropServices.COMException comEx)
    {
        Debug.WriteLine(comEx.Message);
    }
    return retVal;
}

Conclusion

This article shows a simple technique to invoke a property on an Outlook item, to determine whether the item has unsaved changes. This technique of invoking the property does not require the Outlook object model. You can use this technique in your managed or unmanaged Outlook solutions.

Additional Resources

How to: Determine Whether an Outlook Item Has Been Modified but Not Saved (Outlook 2010 Auxiliary Reference)