I've been using Shell Execute for doing interactive email functions within VFP.
I recently had to find an alternative that gave me the same functionality from an end-user perspective since there is a limitation on the length of the string that can be handled by Shell Execute on Win98. (see MSKB Q182985 - notice it's just Outlook Express OR Windows 98, period.)
Here is the syntax I have been using:
DECLARE INTEGER ShellExecute ;
IN SHELL32.DLL ;
RETURN ShellExecute( 0, "Open", "mailto:" + lcEmail + ;
"?subject=Order Confirmation for Priority No." + ;
STR(tsfile.pr_number,6,0) + "&body=" + lcBody, "", "", 1 )
The 3rd parameter winds up being something like this:
"mailto:[email protected]?subject=Order Confirmation for Priority No.400270&body=Order Confirmation: %0D%0DTo: David%0DCompany: ASK Law Offices%0D%0DFrom: HEIDI%0DCompany: Priority Posting and Publishing %0D%0DPhone: (714) 573-7777 %0DFax: (714) 573-7755 %0D%0DDate: 10/25/2001%0D%0DSale Date: 11/29/2001%0D%0DComments: Thank you for your order!%0D%0DYour T.S. #9999%0DPriority #400270%0D%0DCounty: Los Angeles%0DNewspaper: Los Angeles Daily Journal%0DRun Dates: 10/26/2001, 11/02/2001, 11/09/2001"
You can try this in IE if you have Windows 98 to see what happens (take out the dbl quotes and paste into address bar)
It works perfectly in Windows 2000.
Here is the alternative I came up with using OLEAutomation: (note the use of URL Encoded is no longer necessary in the lcBody string. Just use regular CHR(13) or CR.) Note that this is also only a solution if you are using Outlook as your email client and know that it's installed. That's the biggest limitation I see over using Shell Execute. The msoutlook class is simply an OLE wrapper class I use that handles the GetObject/CreateObject and other stuff for me. You can do the same thing by just doing a CREATEOBJECT("Outlook.Application")
loOutlook = CREATEOBJECT("msoutlook")
* Create a new mail item
loMailItem = loOutlook.Do("CreateItem(0)")
.Subject = "Order Confirmation for Priority No. "+ALLTRIM(STR(tsfile.pr_number,6,0))
.Body = lcBody
* Display Modal
* May throw an error if user sent "Object has been moved"
lcOnError = ON('ERROR')
ON ERROR llSent = .T.
llSent = .Sent
ON ERROR &lcOnError
ENDWITH && loMailItem
loMailItem = .NULL.
loOutlook = .NULL.
* Return normal success code that ShellExecute would return (for now)
* Returned user defined value
The only limitation I am seeing with this is that it sometimes does not bring the email window forward (even though I've made it modal) and it just stays flashing down on the task bar until the user clicks it. If someone has a solution for this, I would appreciate it. I'm thinking it's a Window State or something that can control this.
*//Thanks for the carriage return help I couldn't figure it out. This may be of use.
*// Example xEmail([[email protected]],[[email protected]],[RE: Howdy],[blah blah blah]+CHR(13) + CHR(10) +[hi])
LPARAMETERS sMailto, sCC, sSubject, sBody, sBCC
WAIT WINDOW "Email address is needed." NOWAIT
sMailto = [mailto:] + sMailto + [?]
IF NOT EMPTY(sCC)
sMailto = sMailto + [CC=] + sCC
IF NOT EMPTY(sSubject)
sMailto = sMailto + [&SUBJECT=] + sSubject
IF NOT EMPTY(sBody)
sMailto = sMailto + [&BODY=] + sBody
IF NOT EMPTY(sBCC)
sMailto = sMailto + [&BCC=] + sBCC
DECLARE INTEGER ShellExecute IN "Shell32.dll" ;
INTEGER hwnd, ;
STRING lpVerb, ;
STRING lpFile, ;
STRING lpParameters, ;
STRING lpDirectory, ;
sMailto = STRTRAN(sMailto,[?&],[?])
sMailto = STRTRAN(sMailto,CHR(13),[%0D])
sMailto = STRTRAN(sMailto,CHR(10),)
Using Shell Execute from FPW
(this example opening a .jpg document. Of course long file names work because this is an external function.)
IF !'FOXTOOLS' $ SET('LIBRARY')
SET LIBRARY TO SYS(2004)+'foxtools'
eshellex=regfn('ShellExecute', 'ICCCCI', 'I', 'SHELL.DLL')
=callfn(eshellex, 0, 0, 'c:\tmp\Milky_Way_galaxy_sun05.jpg', 0, 0, 1)
Any idea why I need "shell.dll" rather than "shell32.dll"? I guess it's a FPW 16bit thing but regfn() certainly can't find 'Shell Execute' without that.
Maybe this should be moved to ShellExecuteForEmail?
See Also: Win API, Category Automation Category Code Samples Category Windows API
Contributors: Randy Jean