メッセージと共に保存されているユーザー設定フォーム定義を削除する
適用対象: Outlook 2013 | Outlook 2016
このトピックでは、カスタム フォーム定義と共に保存されたメッセージを、フォーム定義なしで通常のメッセージに変換する C++ のコード サンプルを示します。
Microsoft Outlook 2010またはMicrosoft Outlook 2013では、カスタム フォーム ページを含むフォームをフォーム ライブラリに発行するか、対応するフォーム定義をメッセージと共に保存して共有できます。 メッセージと共に保存されたカスタム フォームは、一般に "1 回限りのフォーム" と呼ばれます。フォームは、その特定のメッセージを 1 回限りのインスタンスとして表示するためだけに共有されるためです。 通常、フォームがフォーム ライブラリで発行されていないが、アイテムを開くときに受信者がカスタム フォームを使用する場合にこれを行います。 フォームの [プロパティ] ページの [アイテムチェックでフォーム定義を送信する] ボックスを選択することで、フォームがフォーム Designerで 1 回限りであることを指定できます。
フォーム ページを含むフォームは、Visual Basic Scripting Edition (VBScript) のコードを使用してカスタマイズできます。 フォーム定義と共に保存されるメッセージのサイズは、一般に大きくなります。 セキュリティとストレージの理由から、Outlook 2010 と Outlook 2013 は、アイテムと共に保存されたフォーム定義を無視します。
カスタム フォーム定義で保存されたメッセージを 1 つを含まないメッセージに変換するには、次の 4 つの名前付きプロパティを削除する必要があります。
さらに、そのメッセージと共に保存されたカスタム プロパティの定義を含む PidLidPropertyDefinitionStream 標準プロパティ も削除する必要があります。 このプロパティを削除すると、Outlook 2010 または Outlook 2013 オブジェクト モデルと Outlook 2010 または Outlook 2013 ユーザー インターフェイスは、メッセージに設定されているユーザー プロパティにアクセスできなくなります。 MAPI を使用して、これらのプロパティとその値に引き続きアクセスできます。 このプロパティを削除せず、メッセージが別のフォーム定義で保存されている場合、 PidLidPropertyDefinitionStream 標準プロパティ は新しいデータで部分的に上書きされ、データの整合性は保証されません。
PidLidPropertyDefinitionStream 標準プロパティを削除する場合は、PidLidCustomFlag 標準プロパティからINSP_PROPDEFINITION フラグも削除する必要があります。
次の関数は、 RemoveOneOff
入力パラメーターとして、メッセージへのポインターと PidLidPropertyDefinitionStream 標準プロパティを削除するかどうかを示すインジケーターを受け取ります。 メッセージ ポインターを使用して IMAPIProp::GetIDsFromNames を呼び出して適切なプロパティ識別子を取得し、 IMAPIProp::D eleteProps を呼び出して名前付きプロパティを削除します。 また、 IMAPIProp::GetProps を呼び出して PidLidCustomFlag 標準プロパティ を取得し、 INSP_ONEOFFFLAGS フラグと INSP_PROPDEFINITION フラグをそのプロパティから適宜クリアして、Outlook 2010 と Outlook 2013 が削除された名前付きプロパティを検索しないようにします。
ULONG aulOneOffIDs[] = {dispidFormStorage,
dispidPageDirStream,
dispidFormPropStream,
dispidScriptStream,
dispidPropDefStream, // dispidPropDefStream must remain next to last in list
dispidCustomFlag}; // dispidCustomFlag must remain last in 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(
ulNumOneOffIDs,
rgpnmid,
0,
&lpTags);
if (lpTags)
{
// The last prop is the flag value
// to be updated, don't count it
lpTags->cValues = ulNumOneOffIDs-1;
// If the prop def stream is not to be removed, don't count it
if (!bRemovePropDef)
{
lpTags->cValues = lpTags->cValues-1;
}
hRes = lpMessage->DeleteProps(
lpTags,
0);
if (SUCCEEDED(hRes))
{
SPropTagArray pTag = {0};
ULONG cProp = 0;
LPSPropValue lpCustomFlag = NULL;
// Grab dispidCustomFlag, the last tag in the array
pTag.cValues = 1;
pTag.aulPropTag[0] = CHANGE_PROP_TYPE(
lpTags->aulPropTag[ulNumOneOffIDs-1],
PT_LONG);
hRes = lpMessage->GetProps(
&pTag,
fMapiUnicode,
&cProp,
&lpCustomFlag);
if (SUCCEEDED(hRes) &&
1 == cProp && lpCustomFlag &&
PT_LONG == PROP_TYPE(lpCustomFlag->ulPropTag))
{
// Clear the INSP_ONEOFFFLAGS bits so Outlook
// doesn't look for the props that have been deleted
lpCustomFlag->Value.l =
lpCustomFlag->Value.l & ~(INSP_ONEOFFFLAGS);
if (bRemovePropDef)
{
lpCustomFlag->Value.l =
lpCustomFlag->Value.l & ~(INSP_PROPDEFINITION);
}
hRes = lpMessage->SetProps(
1,
lpCustomFlag,
NULL);
}
hRes = lpMessage->SaveChanges(KEEP_OPEN_READWRITE);
}
}
MAPIFreeBuffer(lpTags);
return hRes;
}