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

ShellExecute command for opening mail client with attached file?

2,321 views
Skip to first unread message

Xavier Pacheco (TeamB)

unread,
Jan 6, 2000, 3:00:00 AM1/6/00
to
I forget where I got this but it works with a single attaintment. I've
got to debug it to determine why it errors with multiple attachments.
Nevertheless, it's a starting point. -- x

implementation
uses Mapi;

{$R *.DFM}

function SendEMail(Handle :THandle;Mail :TStrings) :Cardinal;
type
TAttachAccessArray = array [0..0] of TMapiFileDesc;
PAttachAccessArray = ^TAttachAccessArray;
var
MapiMessage : TMapiMessage;
Receip : TMapiRecipDesc;
Attachments : PAttachAccessArray;
AttachCount : Integer;
i1 : integer;
FileName : String;

begin
fillChar(MapiMessage,SizeOf(MapiMessage),#0);
Attachments := nil;
fillChar(Receip,SizeOf(Receip), #0);

if Mail.Values['to'] <> '' then
begin
Receip.ulReserved := 0;
Receip.ulRecipClass := MAPI_TO;
Receip.lpszName := StrNew(PChar(Mail.Values['to']));
Receip.lpszAddress := StrNew(PChar('SMTP:' +
Mail.Values['to']));
Receip.ulEIDSize := 0;
MapiMessage.nRecipCount := 1;
MapiMessage.lpRecips := @Receip;
end;

AttachCount := 0;

for i1 := 0 to MaxInt do
begin
if Mail.Values['attachment'+inttostr(i1)] = '' then
break;
inc(AttachCount);
end;

if AttachCount > 0 then
begin

GetMem(Attachments, SizeOf(TMapiFileDesc) * AttachCount);

for i1 := 0 to AttachCount -1 do
begin
FileName := Mail.Values['attachment'+inttostr(i1)];
Attachments[i1].ulReserved := 0;
Attachments[i1].flFlags := 0;
Attachments[i1].nPosition := ULONG($FFFFFFFF);
Attachments[i1].lpszPathName := StrNew(PChar(FileName));
Attachments[i1].lpszFileName :=
StrNew(PChar(ExtractFileName(FileName)));
Attachments[i1].lpFileType := nil;
end;
MapiMessage.nFileCount := AttachCount;
MapiMessage.lpFiles := @Attachments^;
end;

if Mail.Values['subject'] <> '' then
MapiMessage.lpszSubject := StrNew(PChar(Mail.Values['subject']));
if Mail.Values['body'] <> '' then
MapiMessage.lpszNoteText := StrNew(PChar(Mail.Values['body']));

Result := MapiSendMail(0, Handle,
MapiMessage,MAPI_DIALOG*Ord(Handle<>0) or
MAPI_LOGON_UI or MAPI_NEW_SESSION, 0);

for i1 := 0 to AttachCount-1 do
begin
strDispose(Attachments[i1].lpszPathName);
strDispose(Attachments[i1].lpszFileName);
end;

if assigned(MapiMessage.lpszSubject) then
strDispose(MapiMessage.lpszSubject);
if assigned(MapiMessage.lpszNoteText) then
strDispose(MapiMessage.lpszNoteText);
if assigned(Receip.lpszAddress) then
strDispose(Receip.lpszAddress);
if assigned(Receip.lpszName) then
strDispose(Receip.lpszName);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
mail: TStringList;
begin
mail:=tstringlist.create;
try
mail.values['to']:='xav...@xapware.com';
mail.values['subject']:='Hello x';
mail.values['body']:='blah';
mail.values['body']:='blah';
mail.values['attachment0']:='c:\winnt\winnt256.bmp';
// mail.values['attachment1']:='c:\winnt\winnt.bmp';
sendEMail(application.handle,mail);
finally
mail.free;
end;

end;

==============================
Xavier Pacheco (TeamB)
xav...@xapware.com

Sorry but TeamB cannot answer support
questions received via email.

Jonas Nyström

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
Hi!

I know it's possible to create a mail in the default client this way...

var
x: string;
begin
x := 'mailto:' + MAddress + '?Subject=' + MSubject + '&cc=' + MCc +
'&bcc=' + MBcc + '&body=' + MMessage;
ShellExecute(0, nil, PChar(x), nil, nil, SW_SHOWDEFAULT);
end;

...but is there a parameter for adding information about attached files
aswell?

Regards / Jonas Nyström

Pietro Bianchessi

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
Jonas,
the unique standard possibility is to use MAPI.
I've discovered that in Outlook Express you can, using the parameter
"&att:filename <my filename>".

Regards,
Pietro Bianchessi

Jonas Nyström <daniela...@ornskoldsvik.mail.telia.com> wrote in message
851kov$pp...@bornews.borland.com...

Stefan Johansson

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
Doesn't work for me!
Can you give me an example!

--
Stefan Johansson
ste...@programduon.se

Pietro Bianchessi

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
Hi,
I'm sorry. Here is:

procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(Handle, 'open',
'mailto:Some...@Somewhere.com Somebo...@SomewhereElse.com ' +
'?att:filename="c:\MyFile.txt"' +
'&body=This is the body%0d%0aSecond line%0d%0aThird line%0d%0a' +
'&Subject=This is the subject', nil, nil, sw_Normal);
end;


Stefan Johansson <ste...@programduon.se> wrote in message
854eg7$r8...@bornews.borland.com...

Ziqing Cong

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
Mr Bianchessi
Dosen't work for me,too!
Can you give me an example again!
Thank you!

Pietro Bianchessi

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
Did you installed OE 5 and it is your default e-mail client?
I don't know how can help you: on my computer it works!

Regards,
Pietro

Ziqing Cong <dq...@ppp.dq.hl.cn> wrote in message
854nff$re...@bornews.borland.com...

Berend Veldkamp

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
&att is not supported by all mail clients, I think
Berend

Ziqing Cong wrote:

> Mr Bianchessi
> Dosen't work for me,too!
> Can you give me an example again!
> Thank you!

--

Stefan Johansson

unread,
Jan 7, 2000, 3:00:00 AM1/7/00
to
This line work perfectly with Outlook 98 and Outlook 2000 but NOT with
Outlook Express 5.0:
mailto:som...@somewhere.se?body=Message&subject=Subject&CC=copyto@somewhere
.com&BCC=secre...@somewhere.com&att:filename="c:\afile.txt"

The only time that an attachment is enclosed (using OE5) is when the "body"
keyword is used. And then the "body"-text is included in the attachment NOT
the actual attachment!?!

- By the way, does anybody know if it's possible to send the message
directly instead of displaying first?
- Also I wonder if it's possible to include more than one attachment, by
using this technique?

--
Stefan Johansson
ste...@programduon.se

Ziqing Cong

unread,
Jan 8, 2000, 3:00:00 AM1/8/00
to
Mr Johansson
My default mail client is Outlook Express 4.72. It doesn't work on my
computer if use your method.But I can click a file using right key,then
select "sent to recipients" menu.It will work. How do Windows does it?
Thank you very much for your answer.

Next is my program.I modified Delphi standard unit MAPI into OutLookMAPI.
The variable MAPIDLL="MAPI32.DLL" in unit MAPI,and MAPIDLL="MSOEMAPI.DLL"
in unit OutLookMAPI. msoemapi.dll is belong to OutLook Express,it provides
some simple MAPI function. The program will work when Exchange be installed
in my computer. It will not work after I uninstalled exchange.

-------------------------------------------------------------------------
unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
dlgOpenFile: TOpenDialog;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses OutLookMAPI;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var strFileName:String;
strFullPath:String;
hMAPISession:LHANDLE;
msg:string;
rel:Cardinal;
begin
if not dlgOpenFile.Execute then Exit;
strFullPath:=dlgOpenFile.FileName;
strFileName:=ExtractFileName(strFullPath);
rel:=MAPILogon(self.Handle,nil,nil,MAPI_NEW_SESSION or
MAPI_LOGON_UI,0,PLHANDLE(@hMAPISession));
// Test return value
case rel of
MAPI_E_FAILURE: msg:='MAPI_E_FAILURE';
MAPI_E_INSUFFICIENT_MEMORY: msg:='MAPI_E_INSUFFICIENT_MEMORY';
MAPI_E_LOGIN_FAILURE: msg:='MAPI_E_LOGIN_FAILURE';
MAPI_E_TOO_MANY_SESSIONS: msg:='MAPI_E_TOO_MANY_SESSIONS';
MAPI_E_USER_ABORT: msg:='MAPI_E_USER_ABORT';
SUCCESS_SUCCESS: msg:='Logon success!';
end;
msg:='Logon:'+msg;
ShowMessage(msg);
if rel<>SUCCESS_SUCCESS then Exit;


rel:=MAPISendDocuments(self.Handle,';',PChar(strFullPath),PChar(strFileName)
,0);
// Test return value
case rel of
MAPI_E_ATTACHMENT_OPEN_FAILURE: msg:='MAPI_E_ATTACHMENT_OPEN_FAILURE';
MAPI_E_ATTACHMENT_WRITE_FAILURE:
msg:='MAPI_E_ATTACHMENT_WRITE_FAILURE';
MAPI_E_FAILURE: msg:='MAPI_E_FAILURE';
MAPI_E_INSUFFICIENT_MEMORY: msg:='MAPI_E_INSUFFICIENT_MEMORY';
MAPI_E_LOGIN_FAILURE: msg:='MAPI_E_LOGIN_FAILURE';
MAPI_E_USER_ABORT: msg:='MAPI_E_USER_ABORT';
SUCCESS_SUCCESS: msg:='Send Documents Success';
end;
msg:='Send Documents:'+msg;
ShowMessage(msg);
if rel<>SUCCESS_SUCCESS then Exit;
MAPILogoff(hMapiSession,self.Handle,0,0);
end;

end.

Stephen Brown

unread,
Jan 12, 2000, 3:00:00 AM1/12/00
to
Stefan Johansson <ste...@programduon.se> wrote in message
news:8555ph$rm...@bornews.borland.com...

> - By the way, does anybody know if it's possible to send the message
> directly instead of displaying first?
> - Also I wonder if it's possible to include more than one attachment, by
> using this technique?

The answer to both questions is to use MAPI, assuming it's installed on the
target machine(s). See MAPISendDocuments, MAPISendMail, etc in the Windows
MAPI help file.

--
Stephen Brown

0 new messages