I have been using the MAPI send mail functions I got at http://www.powerbasic.com/support/fo...ML/001025.html (0ld forum reference)
I have been able to rework that to do everything I wanted to do except one thing: override the "From" email address.
It always comes up with my 'index zero' sending address, [email protected], even though the "from" I enter is another valid address on my system, [email protected]
Does anyone know how I can override the 'from' name and address?
I have tried both "[email protected]" and "SMTP:[email protected]" as the "from."
I am using Outlook Express 6.00.2900.2180
MCM
Ok, you want the code being used. It's not up to my regular "demo" standards but it should be good enough (it works here)..
I suppose you'll want this, too...
Well, I'm in this deep I may as well give you the demo program code, too..
I have been able to rework that to do everything I wanted to do except one thing: override the "From" email address.
It always comes up with my 'index zero' sending address, [email protected], even though the "from" I enter is another valid address on my system, [email protected]
Does anyone know how I can override the 'from' name and address?
I have tried both "[email protected]" and "SMTP:[email protected]" as the "from."
I am using Outlook Express 6.00.2900.2180
MCM
Ok, you want the code being used. It's not up to my regular "demo" standards but it should be good enough (it works here)..
Code:
' FILE: MapiSendEmail.INC ' 7/24/08 New Include file containing exactly one function ' and all required support ' FUNCTION DEFINITION ' iRet = MapiSendEmail (szfrom, szTo, szCC, szAttach, szSubject, szText, SzErrMsg, BYVAL cbERRMsg ) ' Where: ' szFrom = NTS string with the 'from' email address. Required ' szTo = NTS string containing one or more "to" addresses. When multiple should be semi-colon delimited. ' Required. ' szCCTo = NTS string containing one or more "CC" addresses. When multiple should be semi-colon delimited. ' Optional; pass BYVAL NULL if none ' szAttach NTS string containing one or more file names to be attached. When multiple should be semi-colon delimited. ' Optional; pass BYVAL NULL if none' ' szSubject NTS string containing text to be used for the message subject. Required. (Not MAPI required) ' szTExt NTS string containing text to be used for the message body. Required. (Not MAPI required) ' szErrMsg address and size of buffer into which an error message will be placed. ' cbErrMes ' Returns: On Sucess returns 0 (%MAPI_SUCCESS) and szErrMsg = "NO ERROR" ' Else returns error code and szErrMsg = Error text. If text too long it's truncated. ' ------------------------------------ ' REQUIRED SUPPORT MATERIALS ' ------------------------------------ #IF NOT %DEF(%WINAPI) #INCLUDE "win32api.inc" #ENDIF #IF NOT %DEF(%MAPI_INC) #INCLUDE "MAPI.INC" #ENDIF '==================================================================== ' Send one email, to, from, ccs , attachments . '==================================================================== ' FUNCTION MapiSendEmail ALIAS "TSMapiSendEmail" _ (szFrom AS ASCIIZ, szTO AS ASCIIZ, szCCTO AS ASCIIZ, szAttach AS ASCIIZ, _ szSubject AS ASCIIZ, szBody AS ASCIIZ, szErrMsg AS ASCIIZ, BYVAL cchErrMsg AS LONG) AS LONG ' Attempt to load the MAPI library ' 6/8/08 why am I loading this dynamically instead of DECLARING with ALIAS? LOCAL szLib AS ASCIIZ * %MAX_PATH, szProc AS ASCIIZ * 64, dwProc AS DWORD LOCAL hLib AS LONG, iRet AS LONG LOCAL nTo AS LONG, nCC AS LONG, nAttach AS LONG LOCAL iRecip AS LONG, iAttach AS LONG LOCAL Z AS LONG LOCAL w AS STRING LOCAL sTo() AS STRING, sCC() AS STRING, sAttach() AS STRING, sAttachUser() AS STRING LOCAL MapiSession AS DWORD LOCAL mRECIP() AS MAPIRECIP LOCAL mATTACH() AS MAPIFILEDESC LOCAL mMessage AS MAPIMESSAGE LOCAL iSendMailFlags AS LONG ' not currently used (7/24/08) LOCAL szProfile AS ASCIIZ * 128, szPassword AS ASCIIZ * 128 LOCAL lpProfile AS DWORD, lpPassword AS DWORD LOCAL iMapiFlags AS LONG, hWnd AS LONG, Reserved AS LONG LOCAL szTimeStamp AS ASCIIZ * 32 ' required(?) '----------------------------------------------------- ' BEGIN CODE ' ----------------------------------------------------- szErrMsg = "SUCCESS" ' default szLib = $LIB_MAPI ' constant in MAPI.INC hLib = LoadLibrary("MAPI32.DLL") IF ISFALSE hLib THEN szErrMsg = USING$("Could not load MAPI library '&'", szLib) FUNCTION = %TRUE ' error EXIT FUNCTION END IF ' These I will enhance at some point; ' will VARPTR(szProfile or szPassWord) at that time lpprofile = %NULL lpPassword = %NULL ' ----------------------------------- ' LOGON AND ESTABLISH A MAPI SESSION ' ----------------------------------- iMapiFlags = %MAPI_NEW_SESSION ' force a new session ' %MAPI_LOGON_UI flag ==> forces user to enter user Id and PW via a dialog ' I may want to have that as an option, too. hWnd = GetDesktopWindow() szProc = $PROC_MapiLogon dwProc = getProcAddress (hLib, szProc) IF ISFALSE dwProc THEN szErrMsg = USING$("Could not find procedure '&' in '&'", szProc, szLib) FreeLibrary hLib FUNCTION = %TRUE ' error EXIT FUNCTION ELSE CALL DWORD dwProc _ USING U_MapiLogon _ ( hWnd, _ BYVAL lpProfile, _ BYVAL lpPassword,_ iMapiFlags, _ Reserved, _ MapiSession) _ TO iRet IF iRet <> %MAPI_SUCCESS THEN FreeLibrary hlib szErrMsg = USING$("Could not establish MAPI session; logon failed with return code #", iRet) FUNCTION = %TRUE ' error EXIT FUNCTION END IF END IF ' -------------------------------------------- ' IF we get here, we established MapiSession ' ------------------------------------------- ' WE now need to build the MAPIMESSAGE stucture describing the message ' We WILL have pointers to arrays of Recipients, CC (both type MAPIRECIP) ' and may or may not have an array of files to attach (TYPE MAPIFILEDESC) ' get counts of number of recipients so we can size the recipient ' array. W = szTO ' dynamic string to work with nTo = PARSECOUNT(W, ";") REDIM sTo (nTo-1) PARSE W, sTo(),";" IF ISTRUE VARPTR (szCCTO) THEN W = szCCTo nCC = PARSECOUNT(W,";") REDIM sCC (nCC-1) PARSE W, sCC(), ";" ELSE nCC = 0 END IF ' Create an array of mRecips for sender, toaddresses and copies to: REDIM mRecip (nTo + nCC) ' the extra one will be the sender ' make Mrecip(0) = the sender (originator) iRecip = 0 mRecip(iRecip).iRecipClass = %MAPI_ORIG mRecip(iRecip).lpszAddress = VARPTR(szFrom) ' ---------------------------------------------------- ' now get the details and build the recipient arrays ' ---------------------------------------------------- W = szTO FOR Z = 0 TO nTO-1 INCR iRecip mRecip(iRecip).iRecipClass = %MAPI_TO mRecip(iRecip).lpszAddress = STRPTR(sTO(Z)) NEXT Z IF nCC THEN FOR Z = 0 TO nCC -1 INCR iRecip mRecip(iRecip).iRecipClass = %MAPI_CC mRecip(iRecip).lpszAddress = STRPTR(sCC(Z)) NEXT Z END IF ' Get count of and build the attachments (if any) IF VARPTR (szAttach) THEN W = szAttach nAttach = PARSECOUNT (w, ";") REDIM sAttach (nAttach -1) PARSE W, sAttach(), ";" ' build a 'user file name' for each attachment ' will usually be 'file part' of full path name REDIM sAttachUser (nAttach-1) FOR Z = 0 TO nAttach -1 IF DIR$(sAttach(Z)) = "" THEN MSGBOX USING$("Cant find file # '&'", Z, sAttach(Z)) END IF sAttachUser(Z) = USING$ ("File###", Z) NEXT Z REDIM mAttach (nAttach-1) FOR Z = 0 TO nAttach-1 mAttach(Z).iPosition = -1& ' -1 means 'as attachment' mAttach(Z).lpszPathName = STRPTR(sAttach(Z)) ' pathname is fully qualified name of file as seen ' by MAPI; ' lpszFilename is name of file as seen by recipient ' so... I want to show only the filepart here 'mAttach(Z).lpszFileName = STRPTR(sAttachUser(Z)) ' send as' works perfectly, when used ' if not used it is sent as 'filepart' of lpszpathename NEXT ELSE nAttach = 0 END IF ' Since we have the sender, recipients and attachments ' set up we can now build the message itself RESET mMessage mMessage.lpszSubject = VARPTR (szSubject) mMessage.lpszNoteText = VARPTR (szBody) mMessage.lpszMessageType = %NULL CALL MapiCurrentTimeStamp () TO szTimeStamp mMessage.lpszDateReceived = VARPTR (szTimeStamp) mMessage.lpszConversationID = %NULL mMessage.iFlags = %MAPI_NEW_SESSION mMessage.lpOriginator = VARPTR (mRecip(0)) ' sender is at 0 mMessage.iRecipCount = nTO + nCC mMessage.lpRecips = VARPTR (mRecip(1)) ' to and CC start at subscript 1 mMessage.iFileCount = nAttach mMessage.lpFiles = IIF&(nAttach, VARPTR(mAttach(0)), %NULL) ' ------------------------------------------- ' WE CAN NOW CALL MAPI TO SEND THE MESSAGE ' ------------------------------------------- szProc = $PROC_MAPISendMail dwProc = GetProcAddress(hLib, szProc) iSendMailFlags = %MAPI_NEW_SESSION ' valid flags here: none, MAPI_DIALOG, %MAPI_NEW_SESSION, %MAPI_LOGON_UI CALL DWORD dwProc _ USING U_MapiSendMail _ (MapiSession, _ HWnd, _ mMessage, _ iSendMailFlags, _ Reserved) _ TO iRet IF iRet <> %MAPI_SUCCESS THEN szErrMsg = USING$ ("MapiSendMail Failed with code #", iRet) END IF szProc = $PROC_MapiLogoff dwPRoc = GetProcAddress(hLib, szPRoc) CALL DWORD dwProc USING U_MapiLogoff(MapiSession, 0, 0, 0) ' no I do not want the return value here ' Free the Library and exit FreeLibrary hLib FUNCTION = iRet END FUNCTION '-------------------------------------------------------------------- ' Required "The format is YYYY/MM/DD HH:MM, using a 24-hour clock." FUNCTION MapiCurrentTimeStamp () PRIVATE AS STRING LOCAL st AS SYSTEMTIME LOCAL szDF AS ASCIIZ * 48, szDate AS ASCIIZ * 48 LOCAL szTF AS ASCIIZ * 48, szTime AS ASCIIZ * 48 GetLocalTime st szDf = "yyyy'/'MM'/'dd" GetDateFormat BYVAL %NULL, BYVAL %NULL ,st, szDf, szDate, SIZEOF (szDate) szTF = "HH':'mm" GettimeFormat BYVAL %NULL, BYVAL %NULL ,st, szTF, szTime, SIZEOF (szTime) FUNCTION = szDate & $SPC & szTime END FUNCTION ' ** END OF FILE ***
Code:
' FILE: MAPI.INC ' Created by MCM to use in INCLUDE folder (when working). ' A PB conversion of Windows "mapi.h" file is not provided by PowerBASIC inc with the compilers. ' I wonder if someone has done this and I can just go get it? I got don d's and may use ' NOTE: This version does not use MAPI32.DLL ' compiled OK 7/24/08 ' ----------------- ' #INCLUDE CONTROL ' ------------------ #IF NOT %DEF (%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #IF NOT %DEF (%MAPI_INC) %MAPI_INC = 1 ' ------------------------------------------------------------- ' MAPI constants; source: MAPI.H (not provided by PB compiler) ' ------------------------------------------------------------- %MAPI_LOGON_UI = 1 %MAPI_NEW_SESSION = 2 %MAPI_DIALOG = 8 ' Recipient Class values: %MAPI_ORIG = 0 %MAPI_TO = 1 %MAPI_CC = 2 ' /* Recipient is a copy recipient */ %MAPI_BCC = 3 ' /* Recipient is blind copy recipient */ ' 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 ' ---------------------------------------------- ' MAPI function templates for CALL DWORD USING ' ---------------------------------------------- ' MCM note to self: why these functions do not use the "LIB ALIAS" format is ' a mystery to me. However, I will go along with this ' -------------------------------------------------- ' LIBRARY AND PROCEDURE NAMES FOR CALL-BY_ADDRESS ' --------------------------------------------------- $LIB_MAPI= "MAPI32.DLL" $PROC_MapiLogon = "MAPILogon" $PROC_MapiLogoff = "MAPILogoff" $PROC_MapiSendMail = "MAPISendMail" DECLARE FUNCTION U_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 U_MapiLogoff(BYVAL iSession AS LONG, _ BYVAL iParam AS LONG, _ BYVAL iFlags AS LONG, _ BYVAL iReserved AS LONG) AS LONG DECLARE FUNCTION U_MapiSendMail(BYVAL iSession AS LONG, _ BYVAL iParam AS DWORD, _ lpMapiMessage AS MAPIMESSAGE, _ BYVAL iFlags AS LONG, _ BYVAL iReserved AS LONG) AS LONG ' ------------------------------------- ' MAPI ERROR CODES FROM mapi.h ' ------------------------------------ %SUCCESS_SUCCESS = 0 %MAPI_SUCCESS = %SUCCESS_SUCCESS ' MCM equate only %MAPI_USER_ABORT = 1 %MAPI_E_USER_ABORT = %MAPI_USER_ABORT %MAPI_E_FAILURE = 2 %MAPI_E_LOGON_FAILURE = 3 %MAPI_E_LOGIN_FAILURE = %MAPI_E_LOGON_FAILURE %MAPI_E_DISK_FULL = 4 %MAPI_E_INSUFFICIENT_MEMORY = 5 %MAPI_E_ACCESS_DENIED = 6 %MAPI_E_TOO_MANY_SESSIONS = 8 %MAPI_E_TOO_MANY_FILES = 9 %MAPI_E_TOO_MANY_RECIPIENTS = 10 %MAPI_E_ATTACHMENT_NOT_FOUND = 11 %MAPI_E_ATTACHMENT_OPEN_FAILURE = 12 %MAPI_E_ATTACHMENT_WRITE_FAILURE= 13 %MAPI_E_UNKNOWN_RECIPIENT = 14 %MAPI_E_BAD_RECIPTYPE = 15 %MAPI_E_NO_MESSAGES = 16 %MAPI_E_INVALID_MESSAGE = 17 %MAPI_E_TEXT_TOO_LARGE = 18 %MAPI_E_INVALID_SESSION = 19 %MAPI_E_TYPE_NOT_SUPPORTED = 20 %MAPI_E_AMBIGUOUS_RECIPIENT = 21 %MAPI_E_AMBIG_RECIP = %MAPI_E_AMBIGUOUS_RECIPIENT %MAPI_E_MESSAGE_IN_USE = 22 %MAPI_E_NETWORK_FAILURE = 23 %MAPI_E_INVALID_EDITFIELDS = 24 %MAPI_E_INVALID_RECIPS = 25 %MAPI_E_NOT_SUPPORTED = 26 #ENDIF ' if not %DEF (%MAPI_INC)
Code:
' TEST_INCLUDE FILES ' INCLUDE FILE WORKING PERFECTLY AS OF ' 7-24-08. ' Except: if invalid path name specified in attachment, ' send fails with error two. ' ergo, the send function must filter out (or error out) ' if it cannot find one or more of the files. ' Onlyissues: ' I still cannot seem to send with 'from' anything ' other than my default address of [email protected] #COMPILE EXE #DEBUG ERROR ON #REGISTER NONE #DIM ALL #TOOLS OFF '=====[Windows API Header Files] ============================ ' If you don't need all of the functionality supported by these APIs ' (and who does?), you can selectively turn off various modules by putting ' the following constants in your program BEFORE you #include "win32api.inc": ' ' %NOGDI = 1 ' no GDI (Graphics Device Interface) functions ' %NOMMIDS = 1 ' no Multimedia ID definitions %NOMMIDS = 1 #INCLUDE "WIN32API.INC" '==[End Windows API Header Files]============================ #IF NOT %DEF (%INVALID_HANDLE_VALUE_LONG) %INVALID_HANDLE_VALUE_LONG = -1& #ENDIF ' --------------------- ' Include Mapi functions ' in new #INCLUDE file #INCLUDE "MapiSendEmail.INC" FUNCTION WINMAIN (BYVAL hInstance AS LONG, _ BYVAL hPrevInstance AS LONG, _ BYVAL lpCmdLine AS ASCIIZ PTR, _ BYVAL iCmdShow AS LONG) AS LONG CALL TestSendMail END FUNCTION ' --------------------------- ' Test new function 7/24/08 ' --------------------------- FUNCTION TestSendMail () AS LONG LOCAL szFrom AS ASCIIZ * 128 LOCAL sTo AS STRING, sCC AS STRING LOCAL sAttach AS STRING LOCAL lpTo AS LONG, lpCC AS LONG, lpAttach AS LONG LOCAL szSubject AS ASCIIZ * %MAX_PATH, szBody AS ASCIIZ * %MAX_PATH LOCAL szErrMsg AS ASCIIZ * %MAX_PATH LOCAL cbErrMsg AS LONG LOCAL iRet AS LONG cbErrMsg = SIZEOF(szErrMsg) -1 ' This is good testing for me; the mail will go into my outbox ' because that is the way my Outlook Express is set up ' I can change that to test 'actual' sending when ' this is ready for final testing. szSubject = "This is the subject" szBody = "This is the body" szFrom = "[email protected]" ' not my default address ' **** [email protected] is not a valid address on my system!*** ' but [email protected] is and that still does not work! ' it still sends as from [email protected] ' ------------------------------------------------- ' both "to" and "CC" may be semi-colon delimited ' addresses. test first with one of each ' ------------------------------------------------- sTo = "[email protected];[email protected]" sCC = "[email protected];[email protected]" sAttach = "D:\Software_development\Projects\Email June 2008\mapi.inc" sAttach = sAttach & ";" & "D:\Software_development\Projects\Email June 2008\mapi.bak" sAttach = sAttach & ";" & "D:\Software_development\Projects\Email June 2008\Test_Include_files.exe" lpTO = IIF( LEN(sTo) > 0 ,STRPTR(sTo), %NULL) lpCC = IIF(LEN(sCC), STRPTR(sCC), %NULL) lpAttach = IIF(LEN(sAttach), STRPTR(sAttach), %NULL) ' I have an error in the attachments resuluting ' in error 2 (MAPI_E_FAILURE) iRet = MapiSendEmail _ (szFrom,_ BYVAL lpTo, _ BYVAL lpCC, _ BYVAL lpAttach, _ szSubject, _ szBody, _ szErrMsg, _ cbErrMsg) MSGBOX USING$ ("iRet # &", iRet, szErrMsg),,"Test MAPI Mail" END FUNCTION ' END OF FILE
Comment