Mail viewer sample - demonstrates how to work with mailboxes contents with using Mail Processor API.
Any mail message stored at any mail program has the following properties: From, To, Subject, message Text. If you need to get these properties from MS Outlook, you must use MAPI or EMAPI or direct reading the PST files - it is hard work. Suppose that you want to connect to your application MS Outlook Express, you do the difficult work again.
Mail Processor API Idea that you use the same code for MS Outlook and MS Outlook Express. We intentionally did Mail Processor API is very simple, please download Mail Viewer and see how it source code is easy.
Here is an example of source code. The code prints mail messages fields From, To, and Subject of all MS Outlook Express mail messages. Simply replace 'MSOE' in OpenMailbox to MS Outlook. PST file name and this code will work for MS Outlook.
program MailViewerConsole;
{$APPTYPE CONSOLE}
uses
SysUtils,Windows, Engine.pas;
var
Handle: dword; //Handle of opened mailbox
FolderCount, MailCount: integer; //folders and mails counters
MailProp: TMailProp; //mail message properties
begin
Handle := OpenMailbox('MSOE'); //try open MS Outlook Express default mailbox
if Handle > OMS_NOERROR then //if mailbox is opened
for FolderCount := 0 to GetFolderCount(Handle)-1 do //enumerate all MS Outlook Express folders
for MailCount := 0 to GetMailCount(Handle, FolderCount)-1 do //enumerate all mail messages
if GetMailProp(Handle, FolderCount, MailCount, MailProp) = OMS_OK then //get mail message properties
//print mail message properties on the output device
WriteLn(StrPas(MailProp.SenderName) + #9 + StrPas(MailProp.RecipientNames) + #9 + StrPas(MailProp.Subject));
ReadLn;
end.
The source code would look like getting the same field from MS Outlook using MS Outlook EMAPI. Why waste your time?
function GetMessageProp: dword;
var
hr: dword;
SourceMessage: MapiDefs.IMessage; //message save routine
pMalloc: pointer; //buffer for message save
cbStrSize: dword; //file name size
lpWideCharStr: PWideChar; //file name in widechar
Param: cardinal; //for lpMessage.CopyTo empty value
Storage: IStorage; //for save massages store object
MsgSession: PMSGSESS; //function creates and opens a message session that groups the messages created within it
Tags: pSPropTagArray; //tags for query emapi obects
pMessageProperty: PSPropValue; // message subject (get single properties demo)
_Time, _Time2: FileTime;
SysTime: _SystemTime;
g_sptMsgProps: PSPropTagArray;
pProps: PSPropValue;
cVals: ULONG;
function GetOneMessageProperty(pMessage: MapiDefs.IMessage; PropertyTag: ULONG): string;
var
pMessageProperty: PSPropValue; // message subject (get single properties demo)
begin
result := '';
if HrGetOneProp(pMessage, PropertyTag, pMessageProperty) = S_OK then
begin
result := WideCharToString(PWideChar(pMessageProperty.Value.lpszW));
MAPIFreeBuffer(pMessageProperty);
end;
end;
procedure GetOneMessageString8Property(lpMessage: MapiDefs.IMessage; PropertyTag: ULONG; var Text: string);
begin
if HrGetOneProp(lpMessage, PropertyTag, pMessageProperty) = S_OK then
begin
Text := pMessageProperty.Value.lpszA;
MAPIFreeBuffer(pMessageProperty);
end;
end;
begin
result := OMS_NOT;
InitMAPILibrary; //Load MAPI32.DLL
MAPIInitialize(nil); //Initilize Extendex Messaging API
pMalloc := MAPIGetDefaultMalloc;
cbStrSize := MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, PAnsiChar(MSGFileName), -1, lpWideCharStr, 0);
MAPIAllocateBuffer(cbStrSize * sizeof(WCHAR), pointer(lpWideCharStr));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, PAnsiChar(MSGFileName), -1, lpWideCharStr, cbStrSize);
//try access to EMAPI Storage
hr := StgOpenStorage(lpWideCharStr, nil, STGM_READ or STGM_SHARE_DENY_WRITE, 0, 0, Storage);
if hr = S_OK then
begin //"login" to current session
OpenIMsgSession(IMalloc(pMalloc), 0, MsgSession);
OpenIMsgOnIStg(MsgSession, @MAPIAllocateBuffer, @MAPIAllocateMore, @MAPIFreeBuffer,
IMalloc(pMalloc), nil, Storage, TMSGCALLRELEASE(nil^), 0, 0, SourceMessage);
g_sptMsgProps := SizedSPropTagArray2(1);
g_sptMsgProps.aulPropTag[0] := PR_HASATTACH;
cVals := 0;
pProps := nil;
//get MSG (MS Outlook) mail message interface
SourceMessage.GetProps(g_sptMsgProps, 0, cVals, pProps);
//Get mail message propertis with using EMAPI Tags
//Please out this variables self
Name := GetOneMessageProperty(SourceMessage, PR_SENDER_NAME_W);
Sender.Address := GetOneMessageProperty(SourceMessage, PR_SENDER_EMAIL_ADDRESS_W);
FromName := GetOneMessageProperty(SourceMessage, PR_SENDER_NAME_W);
FromAddress := GetOneMessageProperty(SourceMessage, PR_SENDER_EMAIL_ADDRESS_W);
Recipients.EMailAddresses := GetOneMessageProperty(SourceMessage, PR_DISPLAY_TO_W);
CCList := GetOneMessageProperty(SourceMessage, PR_DISPLAY_CC_W);
BCCList := GetOneMessageProperty(SourceMessage, PR_DISPLAY_BCC_W);
if HrGetOneProp(SourceMessage, PR_CLIENT_SUBMIT_TIME, pMessageProperty) = S_OK then
begin
_Time.dwLowDateTime := pMessageProperty.Value.ft.dwLowDateTime;
_Time.dwHighDateTime := pMessageProperty.Value.ft.dwHighDateTime;
FileTimeToLocalFileTime(_Time, _Time2);
FileTimeToSystemTime(_Time2, SysTime);
MAPIFreeBuffer(pMessageProperty);
end
else
if HrGetOneProp(SourceMessage, PR_CREATION_TIME, pMessageProperty) = S_OK then
begin
_Time.dwLowDateTime := pMessageProperty.Value.ft.dwLowDateTime;
_Time.dwHighDateTime := pMessageProperty.Value.ft.dwHighDateTime;
FileTimeToLocalFileTime(_Time, _Time2);
FileTimeToSystemTime(_Time2, SysTime);
MAPIFreeBuffer(pMessageProperty);
end;
GetOneMessageString8Property(SourceMessage, PR_BODY_HTML_A, HTML_Text);
result := OMS_OK;
end;
end;