Microsoft KB Archive/928908

From BetaArchive Wiki

Article ID: 928908

Article Last Modified on 1/11/2007


  • Microsoft Office Outlook 2003


This article describes how to delete the one-off properties from a message in Microsoft Office Outlook 2003 by using Extended MAPI or by using Microsoft Collaboration Data Objects (CDO) 1.21. A message that is marked as a one-off message has a custom form definition that is saved together with the message. In certain scenarios, it is appropriate to save a custom form definition together with a message. However, the one-off functionality typically occurs unexpectedly. Therefore, you may want to delete the one-off properties from a message.

For more information about how a message is marked as a one-off message and about the negative side effects of this functionality, click the following article number to view the article in the Microsoft Knowledge Base:

207896 Working with form definitions and one-off forms

Note The methods that this article describes apply to Microsoft Office Outlook 2003 Service Pack 2 (SP2) and to later Outlook 2003 service packs.


How to delete the one-off properties from a message

You can restore a one-off message to a regular message by deleting a set of named properties and by deleting a flag from another named property. To do this, you can use Extended MAPI or CDO 1.21.

First, you must delete the following properties from the message:

  • dispidFormStorage
  • dispidPageDirStream
  • dispidFormPropStream
  • dispidScriptStream

These properties are in the PSETID_Common namespace.

Then, you must modify the dispidCustomFlag property for the message by deleting the INSP_ONEOFFFLAGS flag. This property is also in the PSETID_Common namespace.

Additionally, you can delete the dispidPropDefStream property from the message. This property is in the PSETID_Common namespace. If you delete the dispidPropDefStream property, also delete the INSP_PROPDEFINITION flag from the dispidCustomFlag property. When you delete the dispidPropDefStream property, the Microsoft Outlook object model and the Outlook user interface can no longer access the user properties that are set for the message. However, you can still use Extended MAPI to access these user properties and the values for these user properties.

Note If you do not delete the dispidPropDefStream property and if the message is marked as a one-off message again, new data may overwrite the dispidPropDefStream property.


The following code example shows the definitions for the one-off properties and for the flags.

#define dispidFormStorage    0x850F
#define dispidPageDirStream  0x8513
#define dispidFormPropStream 0x851B
#define dispidPropDefStream  0x8540
#define dispidScriptStream   0x8541
#define dispidCustomFlag     0x8542

#define INSP_ONEOFFFLAGS     0xD000000
#define INSP_PROPDEFINITION  0x2000000

DEFINE_OLEGUID(PSETID_Common, MAKELONG(0x2000+(8),0x0006),0,0);


Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure. However, they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

The following code example demonstrates how to delete the one-off properties from a message by using Extended MAPI.

ULONG aulOneOffIDs[] = {dispidFormStorage, 
dispidPropDefStream, // dispidPropDefStream must remain next to last in the list.
dispidCustomFlag}; // dispidCustomFlag must remain last in the list.

#define ulNumOneOffIDs (sizeof(aulOneOffIDs)/sizeof(aulOneOffIDs[0]))

HRESULT RemoveOneOff(LPMESSAGE lpMessage, BOOL bRemovePropDef)
  if (!lpMessage) return MAPI_E_INVALID_PARAMETER;

  HRESULT hRes = S_OK;
  MAPINAMEID  rgnmid[ulNumOneOffIDs];
  LPMAPINAMEID rgpnmid[ulNumOneOffIDs];
  LPSPropTagArray lpTags = NULL;

  ULONG i = 0;
  for (i = 0 ; i < ulNumOneOffIDs ; i++)
    rgnmid[i].lpguid = (LPGUID)&PSETID_Common;
    rgnmid[i].ulKind = MNID_ID;
    rgnmid[i].Kind.lID = aulOneOffIDs[i];
    rgpnmid[i] = &rgnmid[i];
  hRes = lpMessage->GetIDsFromNames(
  if (lpTags)
    // The last property is the flag value 
    // we will be updating. Therefore, do not count it.
    lpTags->cValues = ulNumOneOffIDs-1;

    // If we are not removing the propdef stream, do not count it.
    if (!bRemovePropDef)
      lpTags->cValues = lpTags->cValues-1;

    hRes = lpMessage->DeleteProps(
    if (SUCCEEDED(hRes))
      SPropTagArray  pTag = {0};
      ULONG      cProp = 0;
      LPSPropValue  lpCustomFlag = NULL;

      // Get dispidCustomFlag. It is the last tag in the array.
      pTag.cValues = 1;
      pTag.aulPropTag[0] = CHANGE_PROP_TYPE(

      hRes = lpMessage->GetProps(
      if (SUCCEEDED(hRes) && 
        1 == cProp && lpCustomFlag && 
        PT_LONG == PROP_TYPE(lpCustomFlag->ulPropTag))
        // Clear the INSP_ONEOFFFLAGS bits so that Outlook 
        // does not look for the properties that were deleted.
        lpCustomFlag->Value.l = 
        if (bRemovePropDef)
          lpCustomFlag->Value.l = 
        hRes = lpMessage->SetProps(

      hRes = lpMessage->SaveChanges(KEEP_OPEN_READWRITE);

  return hRes;

The following Microsoft Visual Basic code example demonstrates how to delete the one-off properties from a message by using CDO 1.21.

Sub DeleteFormDefinitionWithCDO(MessageEID As String, bDeletePropDef As Boolean)
  Const strPSetCommonGUID = "0820060000000000C000000000000046" ' PSETID_Common

  Dim objSession As MAPI.Session
  Dim oFolderCDO As MAPI.Folder
  Dim oMessages As MAPI.Messages
  Dim oMessage As MAPI.Message
  Dim myFields As MAPI.Fields

  Set objSession = New MAPI.Session
  objSession.Logon , , True, False
  Set oMessage = objSession.GetMessage(MessageEID)
  Set myFields = oMessage.Fields
  On Error Resume Next
  myFields.Item("{" & strPSetCommonGUID & "}0x850F").Delete ' dispidFormStorage
  myFields.Item("{" & strPSetCommonGUID & "}0x8513").Delete ' dispidPageDirStream
  myFields.Item("{" & strPSetCommonGUID & "}0x851B").Delete ' dispidFormPropStream
  myFields.Item("{" & strPSetCommonGUID & "}0x8541").Delete ' dispidScriptStream
  ' Update dispidCustomFlag
  myFields.Item("{" & strPSetCommonGUID & "}0x8542") = _
    myFields.Item("{" & strPSetCommonGUID & "}0x8542") And Not &HD000000 ' INSP_ONEOFFFLAGS

  If bDeletePropDef Then
    myFields.Item("{" & strPSetCommonGUID & "}0x8540").Delete ' dispidPropDefStream
    myFields.Item("{" & strPSetCommonGUID & "}0x8542") = _
      myFields.Item("{" & strPSetCommonGUID & "}0x8542") And Not &H2000000 ' INSP_PROPDEFINITION
  End If

  Set objSession = Nothing
End Sub

Keywords: kbexpertiseinter kbcode kbhowto kbinfo KB928908