Copyright © 2024 IMIBO. Privacy Statement
Request # 20
How to post/send an item to Microsoft Exchange Public Folder
This example shows how you can post/send an item to public folder, how to find and/or create a public folder, etc..
Code snip:
procedure TfrmMain.CreateOrSendMessage(const Folder: IMAPIFolder; const Recipient, Subject, Body: string; Sent: Boolean; CopyToSentFolder: Boolean; const CopyToAnyFolder: IMAPIFolder; IsPost: Boolean = False); var MAPIMessage: IMessage; PropValues: Array [0 .. 3] Of TSPropValue; AddressEntry: PADRLIST; SentMailEID: TSPropValue; CopyMAPIMessage: IMessage; SentMessage: IMessage; OutBox: IMAPIFolder; ObjType: ULONG; MsgList: TSBinaryArray; EntryID: TSBinary; FlagsUnread: ULONG; bIsPublicFolder: Boolean; MsgClass: string; Const ForCorrect: record cValues: ULONG; aulPropTag: array [0 .. 2] Of ULONG; end = ( cValues: 3; aulPropTag: ( PR_EMAIL_ADDRESS_A, PR_ADDRTYPE_A, PR_DISPLAY_NAME_A); ); begin if not Assigned(Folder) then raise Exception.Create('Error Message'); hr := Folder.CreateMessage(nil, 0, MAPIMessage); if failed(hr) then raise EMAPIError.CreateMAPI(Folder, hr); if IsPost then MsgClass := 'IPM.Post' else MsgClass := 'IPM.Note'; hr := HrMAPISetPropString(MAPIMessage, PR_MESSAGE_CLASS_A, PAnsiChar(AnsiString(MsgClass))); if failed(hr) then raise EMAPIError.CreateMAPI(MAPIMessage, hr); AddressEntry := nil; ZeroMemory(@SentMailEID, SizeOf(TSPropValue)); ZeroMemory(@EntryID, SizeOf(TSBinary)); try if (Trim(Recipient) <> '') and not IsPost then begin ZeroMemory(@PropValues, SizeOf(PropValues)); PropValues[0].ulPropTag := PR_EMAIL_ADDRESS_A; PropValues[0].Value.lpszA := PAnsiChar(AnsiString(Recipient)); PropValues[1].ulPropTag := PR_RECIPIENT_TYPE; PropValues[1].Value.l := MAPI_TO; PropValues[2].ulPropTag := PR_ADDRTYPE_A; PropValues[2].Value.lpszA := PAnsiChar(AnsiString('SMTP')); PropValues[3].ulPropTag := PR_DISPLAY_NAME_A; PropValues[3].Value.lpszA := PAnsiChar(AnsiString(Recipient)); hr := HrMAPICreateAddressList(Length(PropValues), @PropValues, AddressEntry); if failed(hr) then raise EMAPIError.CreateMAPI(nil, hr); hr := FAddrBook.PrepareRecips(0, @ForCorrect, AddressEntry); if failed(hr) then raise EMAPIError.CreateMAPI(FAddrBook, hr); hr := FAddrBook.ResolveName(Self.Handle, MAPI_DIALOG, nil, AddressEntry); if failed(hr) then raise EMAPIError.CreateMAPI(FAddrBook, hr); hr := MAPIMessage.ModifyRecipients(0, AddressEntry); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); end; if Trim(Subject) <> '' then begin hr := HrMAPISetPropString(MAPIMessage, PR_SUBJECT_A, PAnsiChar(AnsiString(Subject))); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); hr := HrMAPISetPropString(MAPIMessage, PR_CONVERSATION_TOPIC_A, PAnsiChar(AnsiString(Subject))); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); end; SetBody(MAPIMessage, Body); // Done! hr := MAPIMessage.SaveChanges(KEEP_OPEN_READWRITE); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); // is @ Public Folder??? hr := HrMAPIGetPropBinary(MAPIMessage, PR_MDB_PROVIDER, EntryID.cb, Pointer(EntryID.lpb)); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); bIsPublicFolder := ((EntryID.cb = SizeOf(TGUID)) and (CompareMem(EntryID.lpb, @pbExchangeProviderPublicGuid, SizeOf(TGUID)))); if Assigned(EntryID.lpb) then MAPIFreeBuffer(EntryID.lpb); if bIsPublicFolder then // clear unread flag begin hr := HrMAPIGetPropLong(MAPIMessage, PR_MESSAGE_FLAGS, FlagsUnread); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); FlagsUnread := FlagsUnread and not MSGFLAG_UNSENT; hr := HrMAPISetPropLong(MAPIMessage, PR_MESSAGE_FLAGS, FlagsUnread); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); hr := MAPIMessage.SaveChanges(KEEP_OPEN_READWRITE); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); end; if CopyToSentFolder then begin GetPrivateMdb; hr := HrMAPIFindSentBox(FPrivateMdb, SentMailEID.Value.bin.cb, PENTRYID(SentMailEID.Value.bin.lpb)); If failed(hr) Then Raise EMAPIError.CreateMAPI(FPrivateMdb, hr); SentMailEID.ulPropTag := PR_SENTMAIL_ENTRYID; hr := HrSetOneProp(MAPIMessage, @SentMailEID); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); hr := MAPIMessage.SaveChanges(KEEP_OPEN_READWRITE); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); end; if Assigned(CopyToAnyFolder) then begin hr := CopyToAnyFolder.CreateMessage(nil, 0, CopyMAPIMessage); if failed(hr) then raise EMAPIError.CreateMAPI(CopyToAnyFolder, hr); hr := CopyMAPIMessage.SaveChanges(KEEP_OPEN_READWRITE); If failed(hr) Then Raise EMAPIError.CreateMAPI(CopyMAPIMessage, hr); hr := MAPIMessage.CopyTo(0, nil, nil, 0, nil, @IID_IMessage, Pointer(CopyMAPIMessage), 0, PSPropProblemArray(nil^)); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); hr := HrMAPIGetPropLong(CopyMAPIMessage, PR_MESSAGE_FLAGS, FlagsUnread); If failed(hr) Then Raise EMAPIError.CreateMAPI(CopyMAPIMessage, hr); FlagsUnread := FlagsUnread and not MSGFLAG_UNSENT; hr := HrMAPISetPropLong(CopyMAPIMessage, PR_MESSAGE_FLAGS, FlagsUnread); If failed(hr) Then Raise EMAPIError.CreateMAPI(CopyMAPIMessage, hr); hr := CopyMAPIMessage.SaveChanges(FORCE_SAVE); If failed(hr) Then Raise EMAPIError.CreateMAPI(CopyMAPIMessage, hr); end; if Sent then begin if Assigned(SentMailEID.Value.bin.lpb) then MAPIFreeBuffer(SentMailEID.Value.bin.lpb); GetPrivateMdb; hr := HrMAPIFindOutbox(FPrivateMdb, SentMailEID.Value.bin.cb, PENTRYID(SentMailEID.Value.bin.lpb)); If failed(hr) Then Raise EMAPIError.CreateMAPI(FPrivateMdb, hr); hr := FPrivateMdb.OpenEntry(SentMailEID.Value.bin.cb, PENTRYID(SentMailEID.Value.bin.lpb), nil, MAPI_BEST_ACCESS or MAPI_NO_CACHE, ObjType, IUnknown(OutBox)); If (MAPI_E_UNKNOWN_FLAGS = hr) or (MAPI_E_FAILONEPROVIDER=hr) then hr := FPrivateMdb.OpenEntry(SentMailEID.Value.bin.cb, PENTRYID(SentMailEID.Value.bin.lpb), nil, MAPI_BEST_ACCESS, ObjType, IUnknown(OutBox)); If failed(hr) Then Raise EMAPIError.CreateMAPI(FPrivateMdb, hr); hr := OutBox.CreateMessage(nil, 0, SentMessage); if failed(hr) then raise EMAPIError.CreateMAPI(OutBox, hr); hr := SentMessage.SaveChanges(KEEP_OPEN_READWRITE); if failed(hr) then raise EMAPIError.CreateMAPI(SentMessage, hr); hr := MAPIMessage.CopyTo(0, nil, nil, 0, nil, @IID_IMessage, Pointer(SentMessage), 0, PSPropProblemArray(nil^)); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); hr := SentMessage.SaveChanges(KEEP_OPEN_READWRITE); If failed(hr) Then Raise EMAPIError.CreateMAPI(SentMessage, hr); hr := SentMessage.SubmitMessage(FORCE_SUBMIT); If failed(hr) Then Raise EMAPIError.CreateMAPI(SentMessage, hr); // Delete Msg from Draft if Assigned(EntryID.lpb) then MAPIFreeBuffer(EntryID.lpb); hr := HrMAPIGetPropBinary(MAPIMessage, PR_ENTRYID, EntryID.cb, Pointer(EntryID.lpb)); If failed(hr) Then Raise EMAPIError.CreateMAPI(MAPIMessage, hr); MsgList.cValues := 1; MsgList.lpbin := @EntryID; hr := Folder.DeleteMessages(PENTRYLIST(@MsgList), Self.Handle, nil, MESSAGE_DIALOG); If failed(hr) Then Raise EMAPIError.CreateMAPI(Folder, hr); end; ShowMessage('Done!'); finally MAPIMessage := nil; CopyMAPIMessage := nil; SentMessage := nil; OutBox := nil; if Assigned(EntryID.lpb) then MAPIFreeBuffer(EntryID.lpb); if Assigned(SentMailEID.Value.bin.lpb) then MAPIFreeBuffer(SentMailEID.Value.bin.lpb); If Assigned(AddressEntry) Then begin FreePadrlist(AddressEntry); AddressEntry := nil; end; end; end;
Download Request #20 as Compiled Application
Download Project (DELPHI 10.4) ZIP file
Source Code: In package