home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BUG 4
/
BUGCD1997_05.BIN
/
aplic
/
clip4win
/
clip4win.exe
/
C4W30E.HUF
/
SOURCE
/
CONTRIB
/
MAPI.ZIP
/
MAPI.PRG
< prev
Wrap
Text File
|
1995-10-17
|
11KB
|
379 lines
////////////////////
//
// mapi.prg - Messaging API Sample
//
// Written by: John M. Skelton, 12-Jan-95.
//
// Copyright (C) 1995 Skelton Software, Kendal Cottage, Hillam, Leeds, UK.
// All Rights Reserved.
//
////////////////////
#include "windows.ch"
#include "mapi.ch"
#define NO_C4WCLASS
#include "commands.ch"
#include "dll.ch"
#define GETBUF(n) replicate(chr(0), n)
#ifdef TESTING
static hMAPI
function main_mapi()
local hApp, hWnd, hDLL
hDLL = LoadLibrary("MAPI.DLL")
CREATE APPLICATION hApp WINDOW hWnd TITLE "Clip-4-Win MAPI Test" ;
ON INIT MenuSetup(hWnd) ;
ON EXIT FreeLibrary(hDLL)
if IsWindow(hWnd)
DestroyWindow(hWnd)
endif
return 0
static function DoLogon(hWnd)
local nRet
// Make the user login (sets hMAPI, required in future MAPI calls).
// Note: using 0 instead of hWnd makes the dialog application modal, so
// you might prefer to use 0.
// Also: the MAPI_FORCE_DOWNLOAD is only needed if you want to read mail
// and in date/time order.
if (nRet := MAPILogon(hWnd, "", "", ;
MAPI_LOGON_UI + MAPI_NEW_SESSION, ;
;// MAPI_LOGON_UI + MAPI_FORCE_DOWNLOAD, ;
@hMAPI)) != SUCCESS_SUCCESS
? "Login failed. Error code =", nRet
wait
quit
endif
//? "hMAPI", hMAPI
return nil
static function DoLogoff(hWnd)
MAPILogoff(hMAPI, 0, 0, 0)
return nil
static function DoSend(hWnd, cFilePath)
local cFile := substr(cFilePath, rat("\", cFilePath) + 1)
SendDocs(cFilePath, cFile)
return nil
static function DoReadMail(hWnd)
local nRet, cCurMsgId := GETBUF(256), cMsgId := GETBUF(256)
local aMsg // MAPI Message structure (see MAPI.CH)
//do while (nRet := MAPIFindNext(hMAPI, hWnd, , @cCurMsgId, 0, ;
do while (nRet := MAPIFindNext(hMAPI, 0, "", cCurMsgId, MAPI_GUARANTEE_FIFO,;
0, @cMsgId)) == SUCCESS_SUCCESS
if (nRet := MAPIReadMail(hMAPI, 0, cMsgId, ;
MAPI_PEEK + MAPI_ENVELOPE_ONLY, ;
@aMsg)) == SUCCESS_SUCCESS
// got a msg header
// Process the aMsg...
? "Subject: ", aMsg[MAPI_Subject]
elseif nRet != MAPI_E_NO_MESSAGES
? "nRet =", nRet
endif
cCurMsgId = cMsgId
enddo
//? "nRet =", nRet
return nil
static function MenuSetup(hWnd)
static cFile
MENU IN hWnd
POPUP "&File"
MENUITEM "&Choose..." ACTION cFile := GetOpenFileName(hWnd, "*.*", "Set File Name")
MENUITEM "&Send" ACTION DoSend(hWnd, iif(empty(cFile), "", cFile))
MENUITEM SEPARATOR
MENUITEM "E&xit" ACTION PostQuitMessage(0)
ENDPOPUP
POPUP "&MAPI"
MENUITEM "&Logon" ACTION DoLogon(hWnd)
MENUITEM "&Read Mail" ACTION DoReadMail(hWnd)
MENUITEM "Log&off" ACTION DoLogoff(hWnd)
ENDPOPUP
POPUP "&Help"
MENUITEM "&About" ACTION MessageBox(hWnd, "By John Skelton", "Clip-4-Win MAPI Test")
ENDPOPUP
ENDMENU
return nil
#endif // TESTING
// Convert one MapiRecipDesc array to C structure
function aRecip2cRecip(aRecip, aToFree) // --> cRecip
local a := aclone(aRecip)
local cDesc
a[MAPI_Rsvd] = 0
//a[MAPI_RecipClass] should be ok
a[MAPI_Name] = Str2Ptr(aRecip[MAPI_Name])
a[MAPI_Address] = Str2Ptr(aRecip[MAPI_Address])
//a[MAPI_EIDSize] should be ok
a[MAPI_EntryID] = Bin2Ptr(aRecip[MAPI_EntryID]) // not printable
cDesc = A2Bin(a, MAPI_RECIP_STRUCT_DEF)
aadd(aToFree, a[MAPI_Name])
aadd(aToFree, a[MAPI_Address])
aadd(aToFree, a[MAPI_EntryID])
return cDesc
// Convert array of MapiRecipDesc arrays to C structure
function aaRecip2cRecip(aaRecip, aToFree) // --> cRecip
local cDesc
if valtype(aaRecip) == "A"
if valtype(aaRecip[1]) == "A"
// good - looks like an array of arrays
cDesc = ""
aeval(aaRecip, {|a| cDesc += aRecip2cRecip(a, aToFree)})
else
// not so good - hope it's a single structure
cDesc = aRecip2cRecip(aaRecip, aToFree)
endif
else
// better be nil!
endif
return cDesc
// Convert MapiFileDesc array to C structure
function aFile2cFile(aFile, aToFree) // --> cFile
local a := aclone(aFile)
local cDesc
a[MAPI_Rsvd] = 0
//a[MAPI_FFlags] should be ok
//a[MAPI_Position] should be ok
a[MAPI_PathName] = Str2Ptr(aFile[MAPI_PathName])
a[MAPI_FileName] = Str2Ptr(aFile[MAPI_FileName])
a[MAPI_FileType] = 0
cDesc = A2Bin(a, MAPI_FILE_STRUCT_DEF)
aadd(aToFree, a[MAPI_PathName])
aadd(aToFree, a[MAPI_FileName])
return cDesc
// Convert array of MapiFileDesc arrays to C structure
function aaFile2cFile(aaFile, aToFree) // --> cFile
local cDesc
if valtype(aaFile) == "A"
if valtype(aaFile[1]) == "A"
// good - looks like an array of arrays
cDesc = ""
aeval(aaFile, {|a| cDesc += aFile2cFile(a, aToFree)})
else
// not so good - hope it's a single structure
cDesc = aFile2cFile(aaFile, aToFree)
endif
else
// better be nil!
endif
return cDesc
// Convert MapiMessage array to C structure
function aMsg2cMsg(aMsg, aToFree) // --> cMsg
local a := aclone(aMsg)
local cMsg
a[MAPI_Rsvd] = 0
a[MAPI_Subject] = Str2Ptr(aMsg[MAPI_Subject])
a[MAPI_NoteText] = Str2Ptr(aMsg[MAPI_NoteText])
a[MAPI_MsgType] = Str2Ptr(aMsg[MAPI_MsgType])
a[MAPI_DateRcvd] = Str2Ptr(aMsg[MAPI_DateRcvd])
a[MAPI_ConvId] = Str2Ptr(aMsg[MAPI_ConvId])
//a[MAPI_Flags] should be ok
a[MAPI_Originator] = Str2Ptr(aaRecip2cRecip(aMsg[MAPI_Originator], aToFree))
//a[MAPI_RecipCount] should be ok
a[MAPI_Recips] = Str2Ptr(aaRecip2cRecip(aMsg[MAPI_Recips], aToFree))
//a[MAPI_FileCount] should be ok
a[MAPI_Files] = Str2Ptr(aaFile2cFile(aMsg[MAPI_Files], aToFree))
cMsg = A2Bin(a, MAPI_MSG_STRUCT_DEF)
aadd(aToFree, a[MAPI_Subject])
aadd(aToFree, a[MAPI_NoteText])
aadd(aToFree, a[MAPI_MsgType])
aadd(aToFree, a[MAPI_DateRcvd])
aadd(aToFree, a[MAPI_ConvId])
aadd(aToFree, a[MAPI_Originator])
aadd(aToFree, a[MAPI_Recips])
aadd(aToFree, a[MAPI_Files])
return cMsg
// WARNING: GetProcAddress() understands LPSTR and LPVOID, but not most LP* types
// So use STR or LPVOID or LPSTR if in doubt. (It returns NIL if
// it doesn't like a param.)
// Logon, and return session handle
function MAPILogon(hWnd, cName, cPassword, nFlags, hSession)
local nPtr := Bin2Ptr(GETBUF(4)) // ptr to space for an LHANDLE (ULONG)
local nRet, nReserved := 0
nRet = _MAPILogon(hWnd, cName, cPassword, nFlags, nReserved, nPtr)
if nRet == nil
MessageBox(hWnd, "MAPI.DLL or another DLL not found!", "MAPI")
quit
endif
// bug in 5.2/5.3: if nRet == SUCCESS_SUCCESS fails if nRet is NIL
if (nRet == SUCCESS_SUCCESS)
hSession = C4W_PeekL(nPtr)
endif
FreePtr(nPtr)
return nRet
// This one needs an LPLHANDLE, which needs some effort!
_DLL static function _MAPILogon(hWnd AS ULONG, cName AS LPSTR, ;
cPassword AS LPSTR, nFlags AS ULONG, ;
nReserved AS ULONG, ;
nPtr AS DWORD /*LPVOID*/) ;
AS ULONG Pascal:MAPI.MAPILogon
_DLL function MAPILogoff(hSession AS ULONG, hWnd AS ULONG, ;
nFlags AS ULONG, nReserved AS ULONG) ;
AS ULONG Pascal:MAPI.MAPILogoff
// aMsg[1..MAPI_MsgLength] must be set by the caller...
function MAPISendMail(hSession, hWnd, aMsg, nFlags, nReserved)
local aToFree := {}
local nRet
nRet = _MAPISendMail(hSession, hWnd, aMsg2cMsg(aMsg, aToFree), nFlags, nReserved)
aeval(aToFree, {|nPtr| FreePtr(nPtr)}) // Warning: Don't forget this!
return nRet
// This one needs an lpMapiMessage, which needs some effort!
_DLL static function _MAPISendMail(hSession AS ULONG, hWnd AS ULONG, ;
cMsg AS LPVOID, ;
nFlags AS ULONG, nReserved AS ULONG) ;
AS ULONG Pascal:MAPI.MAPISendMail
// SendDocs() can be called with no file, to just send a note.
//
// cFilePaths is a list of file path names
// e.g. "c:\dir1\dir2\NOTES.TXT;d:\dir3\dir4\MYFILE.DOC"
// cFiles is a list of filenames
// e.g. "NOTES.TXT;MYFILE.DOC"
function SendDocs(cFilePaths, cFiles)
return MAPISendDocuments(0, ";", cFilePaths + chr(0), cFiles + chr(0), 0)
// nUI should be hWnd or 0: (note: hSession isn't needed)
_DLL function MAPISendDocuments(nUI AS ULONG, cDelimChar AS LPSTR, ;
cFilePaths AS LPSTR, cFiles AS LPSTR, ;
nReserved AS ULONG) ;
AS ULONG Pascal:MAPI.MAPISendDocuments
//_DLL function MAPIResolveName(hSession AS ULONG, hWnd AS ULONG, ...) AS ULONG Pascal:MAPI.MAPIResolveName
// nUI should be hWnd or 0:
_DLL function MAPIFindNext(hSession AS ULONG, nUI AS ULONG, ;
cMsgType AS LPSTR, cCurMsgId AS LPSTR, ;
nFlags AS ULONG, ; // MAPI_GUARANTEE_FIFO etc.
nReserved AS ULONG, ; // must be 0
cMsgId REF LPSTR) ; // this is what you want!
AS ULONG Pascal:MAPI.MAPIFindNext
// cleaned-up version of the MAPIReadMail API function
function MAPIReadMail(hSession, ; // MAPI session handle from MAPILogon()
nUI, ; // hWnd or 0
cMsgId, ; // the msg you want
nFlags, ; // MAPI_PEEK etc.
aMsg) // msg returned via this!
local nPtr := Bin2Ptr(GETBUF(4)) // ptr to space for an LPMAPIMESSAGE
local nRet, nPtrMAPIMsg, cMAPIMsg
default nUI to 0
nRet = _MAPIReadMail(hSession, nUI, cMsgId, nFlags, 0, nPtr)
// nPtr is now a pointer to the MAPIMessage structure
nPtrMAPIMsg = C4W_PeekL(nPtr)
cMAPIMsg = C4W_Peek(nPtrMAPIMsg, 4 * 12) // 12 ULONG's
aMsg = Bin2A(cMAPIMsg, MAPI_MSG_STRUCT_DEF)
// now aMsg is 12 ULONG's - not much help!
// convert the ULONG's which are really LPSTR's
//aMsg[MAPI_Rsvd] = 0
aMsg[MAPI_Subject] = C4W_Peek(aMsg[MAPI_Subject])
aMsg[MAPI_NoteText] = C4W_Peek(aMsg[MAPI_NoteText])
aMsg[MAPI_MsgType] = C4W_Peek(aMsg[MAPI_MsgType])
aMsg[MAPI_DateRcvd] = C4W_Peek(aMsg[MAPI_DateRcvd])
aMsg[MAPI_ConvId] = C4W_Peek(aMsg[MAPI_ConvId])
//aMsg[MAPI_Flags] should be ok
// TBD: aMsg[MAPI_Originator]
//aMsg[MAPI_RecipCount] should be ok
// TBD: aMsg[MAPI_Recips]
//aMsg[MAPI_FileCount] should be ok
// TBD: aMsg[MAPI_Files]
FreePtr(nPtrMAPIMsg)
FreePtr(nPtr)
return nRet
// nUI should be hWnd or 0
// Note: nPtr makes this awkward to use from Clipper (see above)...
_DLL function _MAPIReadMail(hSession AS ULONG, nUI AS ULONG, ;
cMsgId AS LPSTR, ; // the msg you want
nFlags AS ULONG, ; // MAPI_PEEK etc.
nReserved AS ULONG, ; // must be 0
nPtr AS DWORD ; // msg returned via this!
) AS ULONG Pascal:MAPI.MAPIReadMail
//_DLL function MAPI(hSession AS ULONG, hWnd AS ULONG, ...) AS ULONG Pascal:MAPI.MAPI