Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MAPI is not dead...

412 views
Skip to first unread message

Arne Ortlinghaus

unread,
Nov 29, 2012, 12:29:13 PM11/29/12
to
There are sometimes customer PCs where I cannot get to work sending emails
via Outlook objects and SMTP is not configured.

I have now searched in the Internet and I was quite suprised about the
results.
- Microsoft supports MAPI more than some years ago. Outlook 2013 on Windows
8 should work for example according to the MS documentation. There are only
some restrictions for example that Simple MAPI is limited to only one
function MAPISendMail for certain Outlook versions. C++ examples can now
directly be found as the first choice for MAPI and are not hidden under lots
of dot.net code!

What I did not understand until now that it is possible to access to
different MAPI implementations on one computer apart from loading the
standard system32\MAPI32.dll. I have changed now my Simple MAPI
implementation that the user can choose the desired dll what may be also
Thunderbird MAPI or so. Of course MAPI is limited but it is at least another
possibility that can be used where other possibilities do not exist or will
not be paid.

Below is the source code I use. I do not reach adding an attachment. If
someone needs the source or some explanations to functions not in the source
please send me an email.

Arne Ortlinghaus
ACS Data Systems

struct MAPIFileDesc align 4

member ulReserved as dword
member flFlags as dword
member nPosition as dword
member lpszPathName as psz
member lpszFileName as psz
member lpFileType as ptr
/*
MapiFileDesc (Simple MAPI)
A MapiFileDesc structure contains information about a file containing a
message attachment stored as a temporary file. That file can contain a
static OLE object, an embedded OLE object, an embedded message, and other
types of files.

Quick Info
Header file: MAPI.H


typedef struct {
ULONG ulReserved;
ULONG flFlags;
ULONG nPosition;
LPTSTR lpszPathName;
LPTSTR lpszFileName;
LPVOID lpFileType;
} MapiFileDesc, FAR *lpMapiFileDesc;

Members
ulReserved
Reserved; must be zero.
flFlags
Bitmask of attachment flags. The following flags can be set:
MAPI_OLE
The attachment is an OLE object. If MAPI_OLE_STATIC is also set, the
attachment is a static OLE object. If MAPI_OLE_STATIC is not set, the
attachment is an embedded OLE object.
MAPI_OLE_STATIC
The attachment is a static OLE object.
If neither flag is set, the attachment is treated as a data file.

nPosition
An integer used to indicate where in the message text to render the
attachment.
Attachments replace the character found at a certain position in the message
text.
That is, attachments replace the character in the MapiMessage structure
field NoteText[nPosition]. A value of - 1 (0xFFFFFFFF) means the attachment
position
is not indicated;
the client application will have to provide a way for the user to access the
attachment.
lpszPathName
Pointer to the fully qualified path of the attached file. This path should
include the disk drive letter and directory name.
lpszFileName
Pointer to the attachment filename seen by the recipient, which may differ
from the filename in the lpszPathName member if temporary files are being
used. If the lpszFileName member is empty or NULL, the filename from
lpszPathName is used.
lpFileType
Pointer to the attachment file type, which can be represented with a
MapiFileTagExt structure. A value of NULL indicates an unknown file type or
a file type determined by the operating system.
Remarks
Simple MAPI works with three kinds of embedded attachments:

Data file attachments
Editable OLE object file attachments
Static OLE object file attachments
Data file attachments are simply data files. OLE object file attachments are
OLE objects that are displayed in the message text. If the OLE attachment is
editable, the recipient can double-click it and its source application will
be started to handle the edit session. If the OLE attachment is static, the
object cannot be edited. The flag set in the flFlags member of the
MapiFileDesc structure determines the kind of a particular attachment.
Embedded messages can be identified by a .MSG extension in the lpszFileName
member.

OLE object files are file representations of OLE object streams. The client
application can recreate an OLE object from the file by calling the OLE
function OleLoadFromStream with an OLESTREAM object that reads the file
contents. If an OLE file attachment is included in an outbound message, the
OLE object stream should be written directly to the file used as the
attachment.

When using the MapiFileDesc member nPosition, the client application should
not place two attachments in the same location. Client applications might
not display file attachments at positions beyond the end of the message
text.


*/
struct MAPIRecipDesc align 4

member ulReserved as dword
member ulRecipClass as dword
member lpszName as psz
member lpszAddress as psz
member ulEIDSize as dword
member lpEntryID as ptr

/*

MapiRecipDesc (Simple MAPI)
A MapiRecipDesc structure contains information about a message sender or
recipient.

Quick Info
Header file: MAPI.H


typedef struct {
ULONG ulReserved
ULONG ulRecipClass;
LPTSTR lpszName;
LPTSTR lpszAddress;
ULONG ulEIDSize;
LPVOID lpEntryID;
} MapiRecipDesc, FAR *lpMapiRecipDesc;

Members
ulReserved
Reserved; must be zero.
ulRecipClass
Contains a numeric value that indicates the type of recipient. Possible
values are: Value Constant Meaning
0 MAPI_ORIG Indicates the original sender of the message.
1 MAPI_TO Indicates a primary message recipient.
2 MAPI_CC Indicates a recipient of a message copy.
3 MAPI_BCC Indicates a recipient of a blind copy.


lpszName
Pointer to the display name of the message recipient or sender.
lpszAddress
Optional pointer to the recipient or sender's address; this address is
provider-specific message delivery data. Generally, the messaging system
provides such addresses for inbound messages. For outbound messages, the
lpszAddress member can point to an address entered by the user for a
recipient not in an address book (that is, a custom recipient).
The format of an address pointed to by the lpszAddress member is [address
type][e-mail address]. Examples of valid addresses are FAX:206-555-1212 and
SMTP:M...@X.COM.

ulEIDSize
The size, in bytes, of the entry identifier pointed to by the lpEntryID
member.
lpEntryID
Pointer to an opaque entry identifier used by a messaging system service
provider to identify the message recipient. Entry identifiers have meaning
only for the service provider; client applications will not be able to
decipher them. The messaging system uses this member to return valid entry
identifiers for all recipients or senders listed in the address book.

*/
STRUCT MAPIMessage ALIGN 4

MEMBER ulReserved as DWORD
MEMBER lpszSubject as psz
MEMBER lpszNoteText as psz
MEMBER lpszMessageType as psz
MEMBER lpszDateReceived as psz
MEMBER lpszConversationID as psz
MEMBER flFlags as DWORD
MEMBER lpOriginator as MAPIRecipDesc ptr
MEMBER nRecipCount as DWORD
MEMBER lpRecips as MAPIRecipDesc ptr
MEMBER nFileCount as DWORD
MEMBER lpFiles as MAPIFileDesc ptr
/*
MapiMessage (Simple MAPI)
A MapiMessage structure contains information about a message.

Quick Info
Header file: MAPI.H


typedef struct {
ULONG ulReserved;
LPTSTR lpszSubject;
LPTSTR lpszNoteText;
LPTSTR lpszMessageType;
LPTSTR lpszDateReceived;
LPTSTR lpszConversationID;
FLAGS flFlags;
lpMapiRecipDesc lpOriginator;
ULONG nRecipCount;
lpMapiRecipDesc lpRecips;
ULONG nFileCount;
lpMapiFileDesc lpFiles;
} MapiMessage, FAR *lpMapiMessage;

Members
ulReserved
Reserved; must be zero.
lpszSubject
Pointer to the text string describing the message subject, typically limited
to 256 characters or less. If this member is empty or NULL, the user has not
entered subject text.
lpszNoteText
Pointer to a string containing the message text. If this member is empty or
NULL, there is no message text.
lpszMessageType
Pointer to a string indicating a non-IPM type of message.
Client applications can select message types for their non-IPM messages.
Clients that only support IPM messages can ignore the lpszMessageType
member when reading messages and set it to empty or NULL when sending
messages.
lpszDateReceived
Pointer to a string indicating the date when the message was received. The
format is YYYY/MM/DD HH:MM, using a 24-hour clock.
lpszConversationID
Pointer to a string identifying the conversation thread to which the message
belongs. Some messaging systems can ignore and not return this member.
flFlags
Bitmask of message status flags. The following flags can be set:
MAPI_RECEIPT_REQUESTED
A receipt notification is requested. Client applications set this flag when
sending a message.
MAPI_SENT
The message has been sent.
MAPI_UNREAD
The message has not been read.
lpOriginator
Pointer to a MapiRecipDesc structure containing information about the sender
of the message.
nRecipCount
The number of message recipient structures in the array pointed to by the
lpRecips member. A value of zero indicates no recipients are included.
lpRecips
Pointer to an array of MapiRecipDesc structures, each containing information
about a message recipient.
nFileCount
The number of structures describing file attachments in the array pointed to
by the lpFiles member. A value of zero indicates no file attachments are
included.
lpFiles
Pointer to an array of MapiFileDesc structures, each containing information
about a file attachment.

*/
class clsMessageMAPIHelper
protect sMessage as MAPIMessage
protect nRecips as dword
protect nfiles as dword
protect _cmapidllprev, _cmapidll as string
protect _lmapidllloaded as logic
protect _pmapiDll as ptr
protect _spProcMapiSendMail as MAPISendMailclsMessageMAPIHelper ptr
declare method messageaddfiles, MessageFree, MessageAlloc, sendemail,
Messageaddrecips
declare method checkloaddll, GetErrortext, SetError, GetPossibleMapiDlls,
SelectPossibleMapiDll
method messageaddfiles(aFiles as array) as logic pascal class
clsMessageMAPIHelper
local lok as logic
local i as dword
local ptrFile, ptrFiletmp as MAPIFileDesc ptr
LOCAL psFile as MAPIFileDesc

lok := true
nfiles := ALen(aFiles)
for i := 1 upto nfiles
if !Empty (aFiles[i])
if FExist (aFiles[i])
//_oMessage:AddFile (oFile)
else
lok := false
nfiles := 0
self:SetError (Msg(ID_DATEINICHTGEFUNDEN)+" (Attachment): " + aFiles[i])
exit
endif
endif
next

if lok .and. nfiles > 0
ptrFile := MemAlloc( _sizeof( MAPIFileDesc ) * nfiles)
ptrFiletmp := ptrFile
for i := 1 to nfiles
psFile := ptrFiletmp
psFile.ulReserved := 0
psFile.flFlags := 0
psFile.nPosition := 0xFFFFFFFF //= -1
psFile.lpszPathName := StringAlloc( aFiles[i] )
psFile.lpszFileName := StringAlloc( FGetFileNameandExt(aFiles[i]) )
psFile.lpFileType := null_ptr
++ptrFiletmp
next
sMessage.nFileCount := nfiles
sMessage.lpFiles := ptrFile
endif
return lok
method SetError(cErrorMessage as string) as void pascal class
clsMessageMAPIHelper

MsgError (cErrorMessage+CRLF+"MAPI Email functions (" + _cmapidll+")")
return
define MAPI_OLE := 0x00000001
define MAPI_OLE_STATIC := 0x00000002
define MAPI_UNREAD := 0x00000001
define MAPI_RECEIPT_REQUESTED := 0x00000002
define MAPI_SENT := 0x00000004
define MAPI_BODY_AS_FILE := 0x00000200
define MAPI_E_FAILURE := 2
define MAPI_E_LOGIN_FAILURE := 3
define MAPI_E_DISK_FULL := 4
define MAPI_E_INSUFFICIENT_MEMORY := 5
define MAPI_E_ACCESS_DENIED := 6
define MAPI_E_TOO_MANY_SESSIONS := 8
define MAPI_E_TOO_MANY_FILES := 9
define MAPI_E_TOO_MANY_RECIPIENTS := 10
define MAPI_E_ATTACHMENT_NOT_FOUND := 11
define MAPI_E_ATTACHMENT_OPEN_FAILURE := 12
define MAPI_E_ATTACHMENT_WRITE_FAILURE := 13
define MAPI_E_UNKNOWN_RECIPIENT := 14
define MAPI_E_BAD_RECIPTYPE := 15
define MAPI_E_NO_MESSAGES := 16
define MAPI_E_INVALID_MESSAGE := 17
define MAPI_E_TEXT_TOO_LARGE := 18
define MAPI_E_INVALID_SESSION := 19
define MAPI_E_TYPE_NOT_SUPPORTED := 20
define MAPI_E_AMBIGUOUS_RECIPIENT := 21
define MAPI_E_MESSAGE_IN_USE := 22
define MAPI_E_NETWORK_FAILURE := 23
define MAPI_E_INVALID_EDITFIELDS := 24
define MAPI_E_INVALID_RECIPS := 25
define MAPI_E_NOT_SUPPORTED := 26
define MAPI_AB_NOMODIFY := 0x00000400
define MAPI_BCC := 3
define MAPI_CC := 2
define MAPI_DIALOG := 0x00000008
define MAPI_ENVELOPE_ONLY := 0x00000040
define MAPI_GUARANTEE_FIFO := 0x00000100
define MAPI_LOGON_UI := 0x00000001
define MAPI_NEW_SESSION := 0x00000002
define MAPI_ORIG := 0
define MAPI_PEEK := 0x00000080
define MAPI_SUPPRESS_ATTACH := 0x00000800
define MAPI_TO := 1
define MAPI_UNREAD_ONLY := 0x00000020
define MAPI_ALLOW_OTHERS := 0x00000008
define MAPI_E_LOGON_FAILURE := 3
define MAPI_E_USER_ABORT := 1
define MAPI_USER_ABORT := 1
define MAPI_EXPLICIT_PROFILE := 0x00000010
define MAPI_EXTENDED := 0x00000020
define MAPI_USE_DEFAULT := 0x00000040
define MAPI_FORCE_DOWNLOAD := 0x00001000
define MAPI_LONG_MSGID := 0x00004000
define MAPI_LOGOFF_SHARED := 0x00000001
define MAPI_LOGOFF_UI := 0x00000002
define MAPI_PASSWORD_UI := 0x00020000
define MAPI_E_AMBIG_RECIP := 21
define MAPI_SIMPLE_DEFAULT := MAPI_LOGON_UI + MAPI_FORCE_DOWNLOAD +
MAPI_ALLOW_OTHERS
define MAPI_SIMPLE_EXPLICIT := MAPI_NEW_SESSION + MAPI_FORCE_DOWNLOAD +
MAPI_EXPLICIT_PROFILE
method MessageFree () as void pascal class clsMessageMAPIHelper
local pszNoteText, pszSubject as psz
local ptrRecip as ptr
local ptrReciptmp as MAPIRecipDesc ptr
local psRecip as MAPIRecipDesc
local ptrFile, ptrFiletmp as MAPIFileDesc ptr
LOCAL psFile as MAPIFileDesc

local i as dword
pszSubject := sMessage.lpszSubject
MemFree( pszSubject )
pszNoteText := sMessage.lpszNoteText
MemFree( pszNoteText )

ptrRecip := sMessage.lpRecips
ptrReciptmp := ptrRecip
for i := 1 to nRecips
psRecip := ptrReciptmp
MemFree( psRecip.lpszName )
MemFree( psRecip.lpszAddress )
++ptrReciptmp
next
if nRecips > 0
MemFree (ptrRecip)
endif

// Dateien
if nfiles > 0
ptrFile := sMessage.lpFiles
ptrFiletmp := ptrFile
for i := 1 to nfiles
psFile := ptrFiletmp
MemFree( psFile.lpszPathName )
MemFree( psFile.lpszFileName )
++ptrFiletmp
next
MemFree (ptrFile)
endif


MemFree( sMessage )

return
method MessageAlloc (lShowDialog as logic, cRecipients as string, cCC as
string, cSubject as string, cNote as string, aFiles as array) as logic
pascal class clsMessageMAPIHelper
local pszSubject as psz
local pszNoteText as psz
sMessage := MemAlloc( _sizeof( MAPIMessage ) )

MemSet( sMessage , 0 , _sizeof( MAPIMessage ) )

//irgendwie muß etwas drinstehen in den Notes bei Dateiübertragungen, sonst:
Fehler 2
//und darf auch nicht zu lang sein
if !Empty(aFiles)
if Empty(cNote)
cNote := "."
endif
endif

pszSubject := StringAlloc( cSubject )
pszNoteText := StringAlloc( cNote )
//aszMessageType := StringAlloc( cMsgType )

sMessage.ulReserved := 0
sMessage.lpszSubject := pszSubject
sMessage.lpszNoteText := pszNoteText
//pMessage.lpszMessageType := pszMessageType

sMessage.lpszDateReceived := null_ptr
sMessage.lpszConversationID := null_ptr
sMessage.flFlags := 0

nfiles := 0
nRecips := 0


return true
method Messageaddrecips (cRecipients as string) as logic pascal class
clsMessageMAPIHelper
local ptrRecip, ptrReciptmp as MAPIRecipDesc ptr
local psRecip as MAPIRecipDesc
local crecip as string
local i as dword
local arecipients as array
arecipients := String2Array(cRecipients, ";")


//Testausgabe mit MapiResolvename:
// "Arne Ortlinghaus",
"EX:/o=ACSDATASYSTEMS/ou=ACS/cn=Recipients/cn=Software/cn=ArneO"
// "ortiz...@conmail.it", "SMTP:ortiz...@conmail.it"

for i := ALen(arecipients) downto 1
if Empty(arecipients[i])
AAUS (arecipients, i)
endif
next
nRecips := ALen(arecipients)
if nRecips > 0
ptrRecip := MemAlloc( _sizeof( MAPIRecipDesc ) * nRecips)
MemSet(ptrRecip, 0,_sizeof( MAPIRecipDesc ) * nRecips)
else
ptrRecip := null_ptr
endif
ptrReciptmp := ptrRecip
for i := 1 to nRecips
crecip := arecipients[i]
psRecip := ptrReciptmp
psRecip.ulReserved := 0
psRecip.ulRecipClass := MAPI_TO
psRecip.lpszName := StringAlloc( crecip )
if !Instr("[", crecip)
crecip := "SMTP:"+crecip
endif
psRecip.lpszAddress := StringAlloc( crecip ) // als Ersatz für
MAPIRESOLVENAME
// psRecip.lpszAddress := StringAlloc( arecipients[i] ) // als Ersatz für
MAPIRESOLVENAME
psRecip.ulEIDSize := 0
psRecip.lpEntryID := null_ptr
++ptrReciptmp
next



sMessage.nRecipCount := nRecips
sMessage.lpRecips := ptrRecip
sMessage.lpOriginator := null_ptr

return true
FUNC MAPISendMailclsMessageMAPIHelper( lhSession as DWORD , ulUIParam as
DWORD , lpMessage as ptr , flFlags as DWORD , ulReserved as DWORD ) as DWORD
PASCAL
return 0
method Init() class clsMessageMAPIHelper
_cmapidllprev := "???"
return self
method CheckLoadDll() as logic pascal class clsMessageMAPIHelper
local cactual, cProcname as string

cactual := GetMessageHandler():cMapidll
if !(cactual==_cmapidllprev)
_lmapidllloaded := false
endif

if !_lmapidllloaded
_cmapidllprev := cactual
if Empty(cactual) .or. cactual == "Standard"
_cmapidll := FGetSystemDir()+"MAPI32.dll"
else
_cmapidll := cactual
endif
if !FExist (_cmapidll)
self:SetError ("Dll not found")
return false
endif
_pmapiDll := LoadLibrary (String2Psz(_cmapidll))
if Empty (_pmapiDll)
self:SetError (Msg(ID_LADENBIBLIOTHEKEN)+crlf;
+LastWindowsErrorAsText())
return false
endif

cProcname := "MAPISendMail"
_spProcMapiSendMail := GetProcAddress (_pmapiDll, String2Psz(cProcname))
if _spProcMapiSendMail == null_ptr
self:SetError ("ProcAddress not found"+ " " +cProcname)
return false
endif
_lmapidllloaded := true
endif
return _lmapidllloaded

method Sendemail(lShowDialog as logic, cRecipients as string, cCC as string,
cSubject as string, cNote as string, aFiles as array) as logic pascal class
clsMessageMAPIHelper

local lok as logic
local lhSession as DWORD
local uFlags, ulUIParam as DWORD
local nresult as dword
local cErrorMessage as string
local cOldPath as string //Mapifunktionen setzen Verzeichnis um...
lok := true
cOldPath := FGetCurrentDir ()//aktuelles Verzeichnis

if !self:CheckLoadDll()
lok := false
endif


self:MessageAlloc (lShowDialog, cRecipients, cCC, cSubject , cNote ,
aFiles )
if lok
self:Messageaddrecips(cRecipients)
endif
// cCC nicht ausprogrammiert
if lok
self:messageaddfiles(aFiles)
endif

if lok
if lShowDialog
uFlags := MAPI_DIALOG
else
uFlags := 0
endif
lhSession := 0
nresult := PCall (_spProcMapiSendMail, lhSession, ulUIParam, sMessage,
uFlags, 0)
if nresult <> 0
cErrorMessage := self:GetErrortext(nresult)
self:SetError (cErrorMessage)
endif
endif

self:MessageFree()
FChangeCurrentDir (cOldPath)
return lok
method GetErrortext(uResult as dword) as string pascal class
clsMessageMAPIHelper
local cErrorMessage as string
if uResult == MAPI_E_FAILURE
cErrorMessage := Msg(ID_MAPI_E_FAILURE)
elseif uResult == MAPI_E_INSUFFICIENT_MEMORY
cErrorMessage := Msg(ID_MAPI_E_INSUFFICIENT_MEMORY)
elseif uResult == MAPI_E_LOGIN_FAILURE
cErrorMessage := Msg(ID_MAPI_E_LOGIN_FAILURE)
elseif uResult == MAPI_E_TOO_MANY_SESSIONS
cErrorMessage := Msg(ID_MAPI_E_TOO_MANY_SESSIONS)
elseif uResult == MAPI_E_USER_ABORT
cErrorMessage := Msg(ID_MAPI_E_USER_ABORT)
elseif uResult == MAPI_E_AMBIGUOUS_RECIPIENT
cErrorMessage := Msg(ID_MAPI_E_AMBIGUOUS_RECIPIENT)
elseif uResult == MAPI_E_ATTACHMENT_NOT_FOUND
cErrorMessage := Msg(ID_MAPI_E_ATTACHMENT_NOT_FOUND)
elseif uResult == MAPI_E_ATTACHMENT_OPEN_FAILURE
cErrorMessage := Msg(ID_MAPI_E_ATTACHMENT_OPEN_FAILURE)
elseif uResult == MAPI_E_BAD_RECIPTYPE
cErrorMessage := Msg(ID_MAPI_E_BAD_RECIPTYPE)
elseif uResult == MAPI_E_INVALID_RECIPS
cErrorMessage := Msg(ID_MAPI_E_INVALID_RECIPS)
elseif uResult == MAPI_E_TEXT_TOO_LARGE
cErrorMessage := Msg(ID_MAPI_E_TEXT_TOO_LARGE)
elseif uResult == MAPI_E_TOO_MANY_FILES
cErrorMessage := Msg(ID_MAPI_E_TOO_MANY_FILES)
elseif uResult == MAPI_E_TOO_MANY_RECIPIENTS
cErrorMessage := Msg(ID_MAPI_E_TOO_MANY_RECIPIENTS)
elseif uResult == MAPI_E_UNKNOWN_RECIPIENT
cErrorMessage := Msg(ID_MAPI_E_UNKNOWN_RECIPIENT)
else
cErrorMessage := "Undefined error " + AsString(uResult)
endif
cErrorMessage += CRLF+"(Return code: "+NTrim(uResult)+")"

return cErrorMessage
method GetPossibleMapiDlls() as array pascal class clsMessageMAPIHelper
local a, adlls as array
local i as dword
local creg, cvaltype, csub, C as string
adlls :={}
AAdd(adlls,{"Standard", "Standard"})

creg := "SOFTWARE\CLIENTS\MAIL"
a := QueryRegMacro("LOCAL", creg, nil,{})
for i := 1 upto ALen(a)
cvaltype := ValType(a[i])
if cvaltype == "C" // Arrays können auch zurückkommen
csub := a[i]
C := QueryRegMacro("LOCAL", creg +"\" +csub, "DLLPath","")
if !Empty(C) .and. !(Upper(C) == "MAPI32.DLL")
if FExist(C)
AAdd(adlls,{csub + " ("+C+")", C})
endif
endif
C := QueryRegMacro("LOCAL", creg +"\" +csub, "DLLPathEx","")
if !Empty(C)
if FExist(C)
AAdd(adlls,{csub +" (Extended)" + " ("+C+")" , C})
endif
endif
endif
next
return adlls
method SelectPossibleMapiDll(oOwner as object) as string pascal class
clsMessageMAPIHelper
local aOptions as array
local cCaption, cDescription as string
local u as usual
aOptions :=self:GetPossibleMapiDlls()
cCaption := "E-Mail clients on this computer"
cDescription := "Please select the desired email client on this computer
"+SGetComputerName()
u := aOptions[1][2]
u := InputOptionEx(GetShell(), cDescription, cCaption, aOptions, u, true,
false, nil)
if !Empty(u)
return u
else
return ""
endif

Willie Moore

unread,
Nov 29, 2012, 4:02:28 PM11/29/12
to
Arne,

Thanks for sharing!

Regards,
Willie
Vulcan VIP


Wolfgang Riedmann

unread,
Nov 30, 2012, 2:59:15 AM11/30/12
to
Hi Arne,

MAPI is the most important interface to email in Windows, so it cannot
be dead.

I wasn't able to make MAPI work with 64 bit Outlook, so I have
implemented an OLE interface to Outlook for these cases.

I have also a Thunderbird interface.

If you need this, please let me know.

Wolfgang

Karl Faller

unread,
Nov 30, 2012, 10:24:18 AM11/30/12
to
Wolfgang,
>I have also a Thunderbird interface.
sounds interesting, as i'm about to switch my mailer to TB.
TIA
Karl

Wolfgang Riedmann

unread,
Nov 30, 2012, 11:35:01 AM11/30/12
to
Hi Karl,

> > I have also a Thunderbird interface.
> sounds interesting, as i'm about to switch my mailer to TB.

it's very easy: a commandline.


Here is this fraction of code:

cCmdLine := ' -compose "attachment=' + "'" + cFileName + "'"
if ! Empty( _cEmail )
cCmdLine := cCmdLine + ",to='" + _cEmail + "'"
endif
if ! Empty( cEmailSubject )
cCmdLine := cCmdLine + ",subject='" + cEmailSubject + "'"
endif
if ! Empty( cEmailText )
cCmdLine := cCmdLine + ",body='" + cEmailText + "'"
endif
cCmdLine := cCmdLine + '"'
debOut( "executing " + cCmdLine )
ShellExecute( null_ptr, psz( "open" ), psz( cThunderbirdPath ), psz(
cCmdLine ), psz( GetPathFromFileName( cThunderbirdPath ) ), 0 )



Thunderbird will work also with MAPI most of the time, but the portable
version of Thunderbird will not.

Wolfgang
0 new messages