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

