Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Send email - Mapi by Don Dickinson

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Send email - Mapi by Don Dickinson

    Comments at:
    https://forum.powerbasic.com/forum/u...-don-dickinson
    Code:
    #INCLUDE "win32api.inc"
    '%TEST_MAPI_WITH_PBCC = 0
    '
    '  ddoc_map.bas
    '
    '  Microsoft MAPI declarations and wrapper functions for 32-bit PowerBASIC
    '  PB/DLL 5 and PB/CC
    '
    '  Written by Don Dickinson - [email protected]
    '
    '  HISTORY
    '  --------------------------------------------------------
    '  July, 1998        Initial release, has support only for
    '                    the MAPISendDocuments Wrapper ...
    '                    > mapiInit
    '                    > mapiCleanup
    '                    > mapiMailFile
    '
    '  Dec, 1998         Added Simple MAPI Wrappers ...
    '                    > smapiLogon
    '                    > smapiLogoff
    '                    > smapiSendMail
    '
    '  --------------------------------------------------------
    '
    '  Hereby Public Domain. Deemed reliable, but use at your own risk, etc.
    '  Do with it as you will, provided you hold the author harmless
    '  from all effects and side-effects of using this code.
    '
    '=============================================================================
    
    '
    '  Debug Constants
    '=============================================================================
    %DEBUG_MAPI_PBCC        = 0
    '%TEST_MAPI_WITH_PBCC    = 0
    
    '
    '  MAPI Constants
    '=============================================================================
    %MAPI_LOGON_UI          = &H1
    %MAPI_NEW_SESSION       = &H2
    %MAPI_DIALOG            = &H8
    %MAPI_UNREAD_ONLY       = &H20
    %MAPI_ENVELOPE_ONLY     = &H40
    %MAPI_PEEK              = &H80
    %MAPI_GUARANTEE_FIFO    = &H100
    %MAPI_BODY_AS_FILE      = &H200
    %MAPI_AB_NOMODIFY       = &H400
    %MAPI_SUPPRESS_ATTACH   = &H800
    %MAPI_FORCE_DOWNLOAD    = &H1000
    
    %MAPI_USE_DEFAULT       = &H40
    
    %MAPI_ORIG  = 0
    %MAPI_TO    = 1
    %MAPI_CC    = 2
    %MAPI_BCC   = 3
    
    %MAPI_OLE         = &H1
    %MAPI_OLE_STATIC  = &H2
    
    '
    '  MAPI Structures
    '=============================================================================
    TYPE MAPIRECIP
       iReserved AS LONG
       iRecipClass AS LONG
       lpszName AS ASCIIZ PTR
       lpszAddress AS ASCIIZ PTR
       iEIDSize AS LONG
       lpEntryID AS DWORD
    END TYPE
    
    TYPE MAPIFILEDESC
       iReserved AS LONG
       iFlags AS LONG
       iPosition AS LONG
       lpszPathName AS ASCIIZ PTR
       lpszFileName AS ASCIIZ PTR
       lpFileType AS DWORD
    END TYPE
    
    TYPE MAPIMESSAGE
       iReserved AS LONG
       lpszSubject AS ASCIIZ PTR
       lpszNoteText AS ASCIIZ PTR
       lpszMessageType AS ASCIIZ PTR
       lpszDateReceived AS ASCIIZ PTR
       lpszConversationID AS ASCIIZ PTR
       iFlags AS LONG
       lpOriginator AS MAPIRECIP PTR
       iRecipCount AS LONG
       lpRecips AS MAPIRECIP PTR
       iFileCount AS LONG
       lpFiles AS MAPIFILEDESC PTR
    END TYPE
    
    '
    '  Globals
    '=============================================================================
    GLOBAL gMAPILib AS LONG
    GLOBAL gFiles() AS MAPIFILEDESC
    GLOBAL gRecip() AS MAPIRECIP
    
    '
    '  Function Prototypes
    '=============================================================================
    DECLARE SUB testmapi()
    DECLARE SUB mapiCleanup()
    DECLARE FUNCTION mapiInit() AS LONG
    DECLARE FUNCTION mapiMailFile(sFileNames AS STRING, sFilePaths AS STRING) AS LONG
    DECLARE FUNCTION smapiLogon(sAccount AS STRING, sPassword AS STRING) AS LONG
    DECLARE SUB smapiLogoff(iSession AS LONG)
    DECLARE FUNCTION smapiSendMail( iSession AS LONG, Subject$, Note$, _
                            Addresses$, Names$, Files$, iShowDialog AS LONG) AS LONG
    
    
    
    '- The template declaration is necessary to tell power basic how
    '  to call the function since the dll is loaded into memory at run-time.
    '  Here is the actual api declaration ...
    '
    '  Declare Function MAPISendDocuments lib "mapi32.dll" _
    '         Alias "MAPISendDocuments" (ByVal ulParam As Dword, _
    '         zDelimChar As Asciiz, zFilePaths As Asciiz, zFileNames As Asciiz, _
    '         ByVal ulReserved As Dword ) As Dword
    '
    DECLARE FUNCTION mapiTemplate_MAPISendDocuments(  BYVAL hWnd AS LONG, _
                                        zDelim AS ASCIIZ, _
                                        zFilePaths AS ASCIIZ, _
                                        zFileNames AS ASCIIZ, _
                                        BYVAL dwReserved AS DWORD ) AS DWORD
    
    DECLARE FUNCTION mapiTemplate_MAPISendMail(  BYVAL iSession AS LONG, _
                                        BYVAL iParam AS DWORD, _
                                        lpMapiMessage AS ANY, _
                                        BYVAL iFlags AS LONG, _
                                        BYVAL iReserved AS LONG ) AS LONG
    
    DECLARE FUNCTION mapiTemplate_MAPILogon(  BYVAL iParam AS LONG, _
                                        zName AS ASCIIZ, zPW AS ASCIIZ, _
                                        BYVAL iFlags AS LONG, _
                                        BYVAL iReserved AS LONG, _
                                        iSession AS LONG ) AS LONG
    
    DECLARE FUNCTION mapiTemplate_MAPILogoff( BYVAL iSession AS LONG, _
                                        BYVAL iParam AS LONG, _
                                        BYVAL iFlags AS LONG, _
                                        BYVAL iReserved AS LONG )  AS LONG
    
    
    #IF 0
    
    '$IF %TEST_MAPI_WITH_PBCC
    '$INCLUDE "win32api.inc"
    '
    '  testmapi
    '============================================================================
    
    SUB testmapi()
    
       DIM hSession AS LONG
       DIM iReturn AS LONG
       DIM Names$, Addresses$, Files$
    
       mapiInit
    
       '- To use smapiSendMail, we must first get a
       '  session handle. When done, we log off
       '  the session with smapiLogoff. If you pass
       '  "", "" MS Mail will prompt you for the
       '  mail profile to use.
       '
       '     e.g.
       '     hSession = smapiLogon("", "")
       '
       'hSession = smapiLogon("Microsoft Outlook", "")
    
       IF hSession THEN
    
          ? "Session handle =" + STR$(hSession)
    
          '- Provide the list of names, addresses, and attachents
          '  Note that addresses are OPTIONAL, If you are part of an MS Mail
          '  post office, you can send mail to others in that post office,
          '  or to people already in your address book, by simply referring
          '  to them by name. For example, if I want to send Dave, Troy, and Tim
          '  interoffice, MS Mail email, I can do this ...
          '  Addresses$ = ""
          '  Names$ = "Dave;Troy;Tim"
          '
          '  If you're sending to someone whose alias is not in your address book,
          '  you need to specify both Names and Addresses. If the address is
          '  an internet address, you also need to indicate the transport for
          '  the email by putting it in front of the address and following it
          '  with a semi-colon. E.G. I have the internet mail service installed,
          '  so I precede addresses with SMTP: to tell ms mail to deliver via the
          '  internet.
          '
          Names$ = "Don's Fax at the Office"
          Addresses$ = "FAX:Don's [email protected]"
    
          '  Files are optional. If you want to attach things to the email,
          '  then list the files separated by ;'s. If you don't want
          '  files, just pass ""
          '
          'Files$ = "c:\code\winsock\test.txt;c:\code\winsock\test.bas;c:\code\winsock\test.fil"
          Files$ = "c:\code\ddoc\sample.ddc"
    
          '- Send the mail
          iReturn = smapiSendMail( hSession, "Test Email2", "This is a test mapi email", _
                                   Addresses$, Names$, Files$, %True)
    
    
          IF iReturn = 0 THEN
             ? "Message Sent"
          ELSE
             ? "smapiSendMail failure error =" + STR$(iReturn)
          END IF
    
          smapiLogoff hSession
       ELSE
    
          '- This can happen if you specify an invalid account name or
          '  the user hits the cancel button when prompted for
          '  a mail profile.
          '
          ? "Unable to obtain mapi session handle"
       END IF
       mapiCleanup
    
    END SUB
    #ENDIF
    
    '
    '  mapiMailFile
    '
    '  Sends a file or list of files. Prompts the user for futher inforamtion
    '  via a common mapi send mail interface. This always displays a dialog.
    '  It also logs on and off for you, so you don't need to call the logon
    '  or initialization functions. If you want to send mail without the
    '  logon screen, you should use smapiSendMail instead.
    '=============================================================================
    FUNCTION mapiMailFile(sFileNames AS STRING, sFilePaths AS STRING) AS LONG
    
       DIM iLoadedMAPIHere AS INTEGER
       DIM zFileNames AS ASCIIZ * 1024
       DIM zFilePaths AS ASCIIZ * 1024
       DIM ptrMAPISendDocs AS DWORD
    
    
       zFileNames = sFileNames
       zFilePaths = sFilePaths
    
       '- If mapi wasn't loaded initially, we load it
       '  in this routine. If it's loaded in this routine,
       '  then we will also unload it before returning. This
       '  allows the programmer to initialize the mapi dll
       '  themselves and it will stay in memory until manually
       '  removing it with mapiCleanup. Otherwise, this function
       '  can also be self contained and initialize and cleanup
       '  after itself automatically.
       '
       iLoadedMAPIHere = %False
       IF gMAPILib = 0 THEN
          iLoadedMAPIHere = %True
          mapiInit
       END IF
    
       IF gMAPILib THEN
          ptrMAPISendDocs = GetProcAddress(gMAPILib, "MAPISendDocuments")
          IF ptrMAPISendDocs THEN
             CALL DWORD ptrMAPISendDocs USING mapiTemplate_MAPISendDocuments(0, ";", zFilePaths, zFileNames, 0)
          END IF
    
          IF iLoadedMAPIHere THEN
             mapiCleanup
          END IF
       ELSE
          ? "Couldn't find MAPI function"
       END IF
    
    END FUNCTION
    
    '
    '  mapiInit
    '
    '  Call to load the mapi dll into memory. Returns
    '  %True if successful, %False if it fails. It also
    '  sets the Global gMAPIInit variable to be %True
    '  on success.
    '=============================================================================
    FUNCTION mapiInit() AS LONG
    
       IF gMAPILib = 0 THEN
          gMAPILib = LoadLibrary("mapi32.dll")
          IF gMAPILib = 0 THEN
             FUNCTION = %False
          ELSE
             FUNCTION = %True
          END IF
       ELSE
          FUNCTION = %True
       END IF
    
    END FUNCTION
    
    '
    '  mapiCleanup
    '
    '  Call to release the mapi dll's
    '=============================================================================
    SUB mapiCleanup()
    
       IF gMAPILib THEN
          FreeLibrary gMAPILib
          gMAPILib = 0
       END IF
    
    END SUB
    
    '
    '  smapiLogon()
    '
    '  Simple Mapi Logon Wrapper Function
    '  Returns a Session ID or Zero on failure
    '  If you pass a blank account, it will prompt you for
    '  mapi logon. If you pass it a valid MAPI user id / password, it
    '  will logon without a login box.
    '=============================================================================
    FUNCTION smapiLogon(sAccount AS STRING, sPassword AS STRING) AS LONG
    
       DIM hSession AS LONG
       DIM ptrMAPILogon AS DWORD
       DIM zAccount AS ASCIIZ * 200
       DIM zPW AS ASCIIZ * 200
    
       zAccount = TRIM$(sAccount)
       zPW = TRIM$(sPassword)
    
       '- Get MAPI DLL in memory if not already there. It is up to the programmer
       '  to call mapiCleanup to free the stuff loaded by mapiInit. I suggest
       '  calling mapiInit yourself when your program starts and then mapiCleanup
       '  when it exits.
       '
       IF mapiInit() = %True THEN
    
          '- Get the procedure's address
          ptrMAPILogon = GetProcAddress(gMAPILib, "MAPILogon")
          IF ptrMAPILogon THEN
    
             '- Now that stuff is done, we logon to obtain a mapi session.
             CALL DWORD ptrMAPILogon USING mapiTemplate_MAPILogon( 0, zAccount, zPW, %MAPI_LOGON_UI, 0, hSession )
             FUNCTION = hSession
          ELSE
    
             '- Couldn't find the procedure's address. Put error handling code here.
             ? "Couldn't get address"
             FUNCTION = 0
          END IF
       ELSE
    
          '- Couldn't get the dll (mapi32.dll) in memory. Put error handling code here.
          FUNCTION = 0
          ? "Couldn't Load mapi32.dll"
       END IF
    
    END FUNCTION
    
    '
    '  smapiLogoff
    '
    '  Simple MAPI Logoff Function Wrapper
    '  Takes a session ID and logs off of mapi
    '=============================================================================
    SUB smapiLogoff(iSession AS LONG)
    
       DIM ptrMAPILogoff AS DWORD
    
       IF gMAPILib <> 0 THEN
          ptrMAPILogoff = GetProcAddress(gMAPILib, "MAPILogoff")
          IF ptrMAPILogoff THEN
             CALL DWORD ptrMAPILogoff USING mapiTemplate_MAPILogoff( iSession, 0, 0, 0 )
          END IF
       END IF
    
    END SUB
    
    '
    '  smapiSendMail
    '
    '  This function sends mail without a dialog to the given list of recipients
    '  and attaches the given list of files.
    '
    '  The parameters are many, so I'll describe them ...
    '
    '  iSession    =  the session id as returned by smapiLogon
    '  Subject$    =  subject of the email
    '  Note$       =  email text
    '  Addresses$  =  A list of email addresses separated by ;'s Make sure to
    '                 put in the message type preceded by a : if it's not
    '                 being delivered to an MS Mail post office. For example, if
    '                 you're sending mail out to the internet via MS Mail, the
    '                 mail type is SMTP. You will need to preceed the address
    '                 with SMTP:
    '                    e.g. "SMTP:[email protected];SMTP:[email protected]"
    '  Names$      =  A list of ; delimited names that correspond to the addresses above.
    '                    e.g. "Don on US Internet; Don's Compuserve Account"
    '  Files$      =  A list of ; delimited file names (full drive letter, file
    '                 path and file name must be included). If the file doesn't exist
    '                 (Dir$(FileName) = "") then it will be ignored.
    '
    '=============================================================================
    FUNCTION smapiSendMail( iSession AS LONG, Subject$, Note$, _
                            Addresses$, Names$, Files$, iShowDialog AS LONG) AS LONG
    
       DIM i AS LONG, iReturn AS LONG
       DIM iNumFiles AS LONG, iNum AS LONG
       DIM iNumRecips AS LONG
       DIM ptrMAPISendMail AS DWORD
       DIM rMessage AS MAPIMESSAGE
       DIM zSubject AS ASCIIZ * 1000
       DIM zNote AS ASCIIZ * 32768
       DIM zTimeStamp AS ASCIIZ * 50
       DIM zFiles() AS ASCIIZ * 300
       DIM zAddr() AS ASCIIZ * 300
       DIM zNames() AS ASCIIZ * 300
    
       zSubject = TRIM$(Subject$)
       zNote = TRIM$(Note$) + CHR$(13) + CHR$(10) + SPACE$(iNumFiles)
       zTimeStamp = DATE$ + " " + TIME$
    
       ptrMAPISendMail = GetProcAddress(gMAPILib, "MAPISendMail")
       IF ptrMAPISendMail THEN
    
          '- Create array of addresses
          IF TRIM$(Names$) = "" THEN
             iNumRecips = 0
          ELSE
             iNumRecips = PARSECOUNT(Names$, ";")
          END IF
    
          REDIM zAddr(0 TO iNumRecips) AS ASCIIZ * 300
          REDIM zNames(0 TO iNumRecips) AS ASCIIZ * 300
          REDIM gRecip(0 TO iNumRecips)
    
          '- Fill the address information
          $IF %DEBUG_MAPI_PBCC
          ? FORMAT$(iNumRecips) + " recipients"
          $ENDIF
          IF iNumRecips > 0 THEN
             FOR i = 1 TO iNumRecips
                zNames(i) = PARSE$(Names$, ";", i)
                zAddr(i) = PARSE$(Addresses$, ";", i)
                $IF %DEBUG_MAPI_PBCC
                ? zNames(i), zAddr(i)
                $ENDIF
                gRecip(i).iReserved = 0
                gRecip(i).iRecipClass = %MAPI_TO
                gRecip(i).lpszName = VARPTR(zNames(i))
                gRecip(i).lpszAddress = VARPTR(zAddr(i))
                gRecip(i).iEIDSize = 0
                gRecip(i).lpEntryID = 0
             NEXT i
          END IF
    
          '- Create the array of files
          IF TRIM$(Files$) = "" THEN
             iNumFiles = 0
          ELSE
             iNumFiles = PARSECOUNT(Files$, ";")
          END IF
          REDIM zFiles(0 TO iNumFiles) AS ASCIIZ * 300
    
          '- Fill in the file information
          $IF %DEBUG_MAPI_PBCC
          ?
          ? FORMAT$(iNumFiles) + " attachments"
          $ENDIF
          REDIM gFiles(0 TO iNumFiles)
          i = 0
          iNum = 0
          FOR i = 1 TO iNumFiles
             zFiles(i) = PARSE$(Files$, ";", i)
             $IF %DEBUG_MAPI_PBCC
             ? zFiles(i)
             $ENDIF
    
             IF DIR$(zFiles(i)) <> "" THEN
               iNum = iNum + 1
               gFiles(iNum).iReserved = 0
               gFiles(iNum).iFlags = 0
               gFiles(iNum).iPosition = LEN(zNote) - 1 - (iNumFiles - i)
               gFiles(iNum).lpszPathName = VARPTR(zFiles(i))
               gFiles(iNum).lpszFileName = 0
               gFiles(iNum).lpFileType = 0
             END IF
    
          NEXT i
          iNumFiles = iNum
    
          '- Fill the message structure for passing to the MAPI call.
          rMessage.iReserved = 0
          rMessage.lpszSubject = VARPTR(zSubject)
          rMessage.lpszNoteText = VARPTR(zNote)
          rMessage.lpszMessageType = 0
          rMessage.lpszDateReceived = VARPTR(zTimeStamp)
          rMessage.lpszConversationID = 0
          rMessage.iFlags = 0
          rMessage.lpOriginator = 0
          rMessage.iRecipCount = iNumRecips
          IF iNumRecips > 0 THEN
             rMessage.lpRecips = VARPTR(gRecip(1))
          ELSE
             rMessage.lpRecips = 0
          END IF
    
          rMessage.iFileCount = iNumFiles
          IF iNumFiles > 0 THEN
             rMessage.lpFiles = VARPTR(gFiles(1))
          ELSE
             rMessage.lpFiles = 0
          END IF
    
          '- Make the call.
          IF iShowDialog THEN
             CALL DWORD ptrMAPISendMail USING mapiTemplate_MAPISendMail( iSession, 0 , rMessage, %MAPI_LOGON_UI OR %MAPI_DIALOG, 0 ) TO iReturn
          ELSE
             CALL DWORD ptrMAPISendMail USING mapiTemplate_MAPISendMail( iSession, 0 , rMessage, %MAPI_LOGON_UI, 0 ) TO iReturn
          END IF
    
       END IF
    
       FUNCTION = iReturn
    
    END FUNCTION
    
    FUNCTION PBMAIN AS LONG
      LOCAL hSession,iShowDialog,result,loops,x,milliseconds AS LONG
      LOCAL sSubject,sBody,sAddresses,sNames,sFiles AS STRING
    
    
      MapiInit
      Loops = 3           'test sending multiple times
      milliseconds = 4000 'delay between sending each email
      iShowDialog = 0     'or use 1 to view and click send
    
      FOR x = 1 TO Loops 'PLEASE DRIVE RESPONSIBLY
       sSubject    = "Subject" + STR$(x)
       sBody       = "How now brown cow" + STR$(x)
       sAddresses  = "SMTP:[email protected];SMTP:[email protected]"  '<-- your email address while testing
       sNames      = "heidi;jan"   'name for each address
       sFiles      = ""
       result = smapiSendMail(hSession,sSubject, sBody,sAddresses,sNames,sFiles, iShowDialog)
       IF Loops > 1 THEN SLEEP Milliseconds
      NEXT
      smapiLogoff hSession
      mapiCleanup
    
    END FUNCTION
Working...
X