INFO : Enregistrer le message dans le fichier composé MSG
Résumé
Cet article contient du code qui montre comment enregistrer un message dans un document composé, en particulier un fichier .msg lisible par n’importe quel client qui prend en charge le format de fichier .msg.
Informations supplémentaires
La fonction ci-dessous prend un objet message valide en tant que paramètre in et utilise ses propriétés pour créer un doublon du message et l’enregistrer dans un fichier composé à l’aide du format .msg. La ligne d’objet du message est utilisée comme nom de fichier du nouveau fichier.
Remarque
Les caractères spéciaux dans la ligne d’objet du paramètre in de cette fonction peuvent entraîner des résultats inattendus. Bien que le code puisse être écrit pour éviter les caractères spéciaux dans la ligne d’objet, il n’est pas lié à la rubrique et ce code est intentionnellement exclu.
#define INITGUID
#include <objbase.h>
#define USES_IID_IMessage
#include <mapix.h>
#include <mapitags.h>
#include <mapidefs.h>
#include <mapiutil.h>
#include <mapiguid.h>
#include <imessage.h>
// {00020D0B-0000-0000-C000-000000000046}
DEFINE_GUID(CLSID_MailMessage,
0x00020D0B,
0x0000, 0x0000, 0xC0, 0x00, 0x0, 0x00, 0x0, 0x00, 0x00, 0x46);
HRESULT SaveToMSG ( LPMESSAGE pMessage )
{
HRESULT hRes = S_OK;
LPSPropValue pSubject = NULL;
LPSTORAGE pStorage = NULL;
LPMSGSESS pMsgSession = NULL;
LPMESSAGE pIMsg = NULL;
SizedSPropTagArray ( 7, excludeTags );
char szPath[_MAX_PATH];
char strAttachmentFile[_MAX_PATH];
LPWSTR lpWideCharStr = NULL;
ULONG cbStrSize = 0L;
// create the file name in the directory where "TMP" is defined
// with subject as the filename and ".msg" extension.
// get temp file directory
GetTempPath(_MAX_PATH, szPath);
// get subject line of message to copy. This will be used as the
// new file name.
HrGetOneProp( pMessage, PR_SUBJECT, &pSubject );
// fuse path, subject, and suffix into one string
strcpy ( strAttachmentFile, szPath );
strcat ( strAttachmentFile, pSubject->Value.lpszA );
strcat ( strAttachmentFile, ".msg");
// get memory allocation function
LPMALLOC pMalloc = MAPIGetDefaultMalloc();
// Convert new file name to WideChar
cbStrSize = MultiByteToWideChar (CP_ACP,
MB_PRECOMPOSED,
strAttachmentFile,
-1, lpWideCharStr, 0);
MAPIAllocateBuffer ( cbStrSize * sizeof(WCHAR),
(LPVOID *)&lpWideCharStr );
MultiByteToWideChar (CP_ACP,
MB_PRECOMPOSED,
strAttachmentFile,
-1, lpWideCharStr, cbStrSize );
// create compound file
hRes = ::StgCreateDocfile(lpWideCharStr,
STGM_READWRITE |
STGM_TRANSACTED |
STGM_CREATE, 0, &pStorage);
// Open an IMessage session.
hRes = ::OpenIMsgSession(pMalloc, 0, &pMsgSession);
// Open an IMessage interface on an IStorage object
hRes = ::OpenIMsgOnIStg(pMsgSession,
MAPIAllocateBuffer,
MAPIAllocateMore,
MAPIFreeBuffer,
pMalloc,
NULL,
pStorage,
NULL, 0, 0, &pIMsg);
// write the CLSID to the IStorage instance - pStorage. This will
// only work with clients that support this compound document type
// as the storage medium. If the client does not support
// CLSID_MailMessage as the compound document, you will have to use
// the CLSID that it does support.
hRes = WriteClassStg(pStorage, CLSID_MailMessage );
// Specify properties to exclude in the copy operation. These are
// the properties that Exchange excludes to save bits and time.
// Should not be necessary to exclude these, but speeds the process
// when a lot of messages are being copied.
excludeTags.cValues = 7;
excludeTags.aulPropTag[0] = PR_ACCESS;
excludeTags.aulPropTag[1] = PR_BODY;
excludeTags.aulPropTag[2] = PR_RTF_SYNC_BODY_COUNT;
excludeTags.aulPropTag[3] = PR_RTF_SYNC_BODY_CRC;
excludeTags.aulPropTag[4] = PR_RTF_SYNC_BODY_TAG;
excludeTags.aulPropTag[5] = PR_RTF_SYNC_PREFIX_COUNT;
excludeTags.aulPropTag[6] = PR_RTF_SYNC_TRAILING_COUNT;
// copy message properties to IMessage object opened on top of
// IStorage.
hRes = pMessage->CopyTo(0, NULL,
(LPSPropTagArray)&excludeTags,
NULL, NULL,
(LPIID)&IID_IMessage,
pIMsg, 0, NULL );
// save changes to IMessage object.
pIMsg -> SaveChanges ( KEEP_OPEN_READWRITE );
// save changes in storage of new doc file
hRes = pStorage -> Commit(STGC_DEFAULT);
// free objects and clean up memory
MAPIFreeBuffer ( lpWideCharStr );
pStorage->Release();
pIMsg->Release();
CloseIMsgSession ( pMsgSession );
pStorage = NULL;
pIMsg = NULL;
pMsgSession = NULL;
lpWideCharStr = NULL;
return hRes;
}
Toutes les versions d’Outlook et du client Exchange prennent en charge CLSID_MailMessage en tant que document composé. La seule raison d’utiliser un CLSID différent est de prendre en charge d’autres clients qui utilisent un AUTRE CLISD lorsque vous écrivez des messages dans un stockage structuré.
Lors de l’enregistrement de messages contenant un grand nombre de destinataires ou de pièces jointes, il est possible que l’opération CopyTo échoue avec MAPI_E_NOT_ENOUGH_MEMORY. Cela est dû à un problème connu avec le stockage structuré et les flux. Chaque fois qu’une nouvelle pièce jointe ou un nouveau destinataire est ajouté au message en cours d’enregistrement dans le stockage structuré, un nouveau fichier de stockage racine est ouvert. Ces fichiers ne sont pas fermés tant que la transaction n’est pas terminée. Étant donné que le système d’exploitation impose une limite au nombre de fichiers de stockage racine ouverts simultanément, il n’existe aucune solution de contournement connue.
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour