简单,给你一个控件,自己看着办吧。:)<br>unit MapiControl; <br><br>interface <br><br>uses <br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; <br><br>type <br> { Introducing a new Type of Event to get the Errorcode } <br> TMapiErrEvent = procedure(Sender: TObject; ErrCode: Integer) of object; <br><br> TMapiControl = class(TComponent) <br> constructor Create(AOwner: TComponent); override; <br> destructor Destroy; override; <br> private <br> { Private-Deklarationen } <br> FSubject: string; <br> FMailtext: string; <br> FFromName: string; <br> FFromAdress: string; <br> FTOAdr: TStrings; <br> FCCAdr: TStrings; <br> FBCCAdr: TStrings; <br> FAttachedFileName: TStrings; <br> FDisplayFileName: TStrings; <br> FShowDialog: Boolean; <br> FUseAppHandle: Boolean; <br> { Error Events: } <br> FOnUserAbort: TNotifyEvent; <br> FOnMapiError: TMapiErrEvent; <br> FOnSuccess: TNotifyEvent; <br> { +> Changes by Eugene Mayevski [mailto:Mayevski@eldos.org]} <br> procedure SetToAddr(newValue : TStrings); <br> procedure SetCCAddr(newValue : TStrings); <br> procedure SetBCCAddr(newValue : TStrings); <br> procedure SetAttachedFileName(newValue : TStrings); <br> { +< Changes } <br> protected <br> { Protected-Deklarationen } <br> public <br> { Public-Deklarationen } <br> ApplicationHandle: THandle; <br> procedure Sendmail(); <br> procedure Reset(); <br> published <br> { Published-Deklarationen } <br> property Subject: string read FSubject write FSubject; <br> property Body: string read FMailText write FMailText; <br> property FromName: string read FFromName write FFromName; <br> property FromAdress: string read FFromAdress write FFromAdress; <br> property Recipients: TStrings read FTOAdr write SetTOAddr; <br> property CopyTo: TStrings read FCCAdr write SetCCAddr; <br> property BlindCopyTo: TStrings read FBCCAdr write SetBCCAddr; <br> property AttachedFiles: TStrings read FAttachedFileName write SetAttachedFileName; <br> property DisplayFileName: TStrings read FDisplayFileName; <br> property ShowDialog: Boolean read FShowDialog write FShowDialog; <br> property UseAppHandle: Boolean read FUseAppHandle write FUseAppHandle; <br><br> { Events: } <br> property OnUserAbort: TNotifyEvent read FOnUserAbort write FOnUserAbort; <br> property OnMapiError: TMapiErrEvent read FOnMapiError write FOnMapiError; <br> property OnSuccess: TNotifyEvent read FOnSuccess write FOnSuccess; <br> end; <br><br>procedure Register; <br><br>implementation <br><br>uses Mapi; <br><br>{ Register the component: } <br>procedure Register; <br>begin <br> RegisterComponents('expectIT', [TMapiControl]); <br>end; <br><br>{ TMapiControl } <br><br>constructor TMapiControl.Create(AOwner: TComponent); <br>begin <br> inherited Create(AOwner); <br> FOnUserAbort := nil; <br> FOnMapiError := nil; <br> FOnSuccess := nil; <br> FSubject := ''; <br> FMailtext := ''; <br> FFromName := ''; <br> FFromAdress := ''; <br> FTOAdr := TStringList.Create; <br> FCCAdr := TStringList.Create; <br> FBCCAdr := TStringList.Create; <br> FAttachedFileName := TStringList.Create; <br> FDisplayFileName := TStringList.Create; <br> FShowDialog := False; <br> ApplicationHandle := Application.Handle; <br>end; <br><br>{ +> Changes by Eugene Mayevski [mailto:Mayevski@eldos.org]} <br>procedure TMapiControl.SetToAddr(newValue : TStrings); <br>begin <br> FToAdr.Assign(newValue); <br>end; <br><br>procedure TMapiControl.SetCCAddr(newValue : TStrings); <br>begin <br> FCCAdr.Assign(newValue); <br>end; <br><br>procedure TMapiControl.SetBCCAddr(newValue : TStrings); <br>begin <br> FBCCAdr.Assign(newValue); <br>end; <br><br>procedure TMapiControl.SetAttachedFileName(newValue : TStrings); <br>begin <br> FAttachedFileName.Assign(newValue); <br>end; <br>{ +< Changes } <br><br>destructor TMapiControl.Destroy; <br>begin <br> FTOAdr.Free; <br> FCCAdr.Free; <br> FBCCAdr.Free; <br> FAttachedFileName.Free; <br> FDisplayFileName.Free; <br> inherited destroy; <br>end; <br><br>{ Reset the fields for re-use} <br>procedure TMapiControl.Reset; <br>begin <br> FSubject := ''; <br> FMailtext := ''; <br> FFromName := ''; <br> FFromAdress := ''; <br> FTOAdr.Clear; <br> FCCAdr.Clear; <br> FBCCAdr.Clear; <br> FAttachedFileName.Clear; <br> FDisplayFileName.Clear; <br>end; <br><br>{ Send the Mail via the API, this procedure composes and sends <br> the Email } <br>procedure TMapiControl.Sendmail; <br>var <br> MapiMessage: TMapiMessage; <br> MError: Cardinal; <br> Sender: TMapiRecipDesc; <br> PRecip, Recipients: PMapiRecipDesc; <br> PFiles, Attachments: PMapiFileDesc; <br> i: Integer; <br> AppHandle: THandle; <br>begin <br> { First we store the Application Handle, if not <br> the Component might fail to send the Email or <br> your calling Program gets locked up. } <br> AppHandle := Application.Handle; <br><br> { We need all recipients to alloc the memory } <br> MapiMessage.nRecipCount := FTOAdr.Count + FCCAdr.Count + FBCCAdr.Count; <br> GetMem(Recipients, MapiMessage.nRecipCount * sizeof(TMapiRecipDesc)); <br><br> try <br> with MapiMessage do <br> begin <br> ulReserved := 0; <br> { Setting the Subject: } <br> lpszSubject := PChar(Self.FSubject); <br><br> { ... the Body: } <br> lpszNoteText := PChar(FMailText); <br><br> lpszMessageType := nil; <br> lpszDateReceived := nil; <br> lpszConversationID := nil; <br> flFlags := 0; <br><br> { and the sender: (MAPI_ORIG) } <br> Sender.ulReserved := 0; <br> Sender.ulRecipClass := MAPI_ORIG; <br> Sender.lpszName := PChar(FromName); <br> Sender.lpszAddress := PChar(FromAdress); <br> Sender.ulEIDSize := 0; <br> Sender.lpEntryID := nil; <br> lpOriginator := @Sender; <br><br> PRecip := Recipients; <br><br> { We have multiple recipients: (MAPI_TO) <br> and setting up each: } <br> if nRecipCount > 0 then <br> begin <br> for i := 1 to FTOAdr.Count do <br> begin <br> PRecip^.ulReserved := 0; <br> PRecip^.ulRecipClass := MAPI_TO; <br> { lpszName should carry the Name like in the <br> contacts or the adress book, I will take the <br> email adress to keep it short: } <br> PRecip^.lpszName := PChar(FTOAdr.Strings[i - 1]); <br> { If you use this component with Outlook97 or 2000 <br> and not some of Express versions you will have to set <br> 'SMTP:' in front of each (email-) adress. Otherwise <br> Outlook/Mapi will try to handle the Email on itself. <br> Sounds strange, just erease the 'SMTP:', compile, compose <br> a mail and take a look at the resulting email adresses <br> (right click). <br> } <br> PRecip^.lpszAddress := PChar('SMTP:' + FTOAdr.Strings[i - 1]); <br> PRecip^.ulEIDSize := 0; <br> PRecip^.lpEntryID := nil; <br> Inc(PRecip); <br> end; <br><br> { Same with the carbon copy recipients: (CC, MAPI_CC) } <br> for i := 1 to FCCAdr.Count do <br> begin <br> PRecip^.ulReserved := 0; <br> PRecip^.ulRecipClass := MAPI_CC; <br> PRecip^.lpszName := PChar(FCCAdr.Strings[i - 1]); <br> PRecip^.lpszAddress := PChar('SMTP:' + FCCAdr.Strings[i - 1]); <br> PRecip^.ulEIDSize := 0; <br> PRecip^.lpEntryID := nil; <br> Inc(PRecip); <br> end; <br><br> { ... and the blind copy recipients: (BCC, MAPI_BCC) } <br> for i := 1 to FBCCAdr.Count do <br> begin <br> PRecip^.ulReserved := 0; <br> PRecip^.ulRecipClass := MAPI_BCC; <br> PRecip^.lpszName := PChar(FBCCAdr.Strings[i - 1]); <br> PRecip^.lpszAddress := PChar('SMTP:' + FBCCAdr.Strings[i - 1]); <br> PRecip^.ulEIDSize := 0; <br> PRecip^.lpEntryID := nil; <br> Inc(PRecip); <br> end; <br> end; <br> lpRecips := Recipients; <br><br> { Now we process the attachments: } <br><br> if FAttachedFileName.Count > 0 then <br> begin <br> nFileCount := FAttachedFileName.Count; <br> GetMem(Attachments, MapiMessage.nFileCount * sizeof(TMapiFileDesc)); <br><br> PFiles := Attachments; <br><br> { Fist setting up the display names (without path): } <br> FDisplayFileName.Clear; <br> for i := 0 to FAttachedFileName.Count - 1 do <br> FDisplayFileName.Add(ExtractFileName(FAttachedFileName)); <br><br> if nFileCount > 0 then <br> begin <br> { Now we pass the attached file (their paths) to the <br> structure: } <br> for i := 1 to FAttachedFileName.Count do <br> begin <br> { Setting the complete Path } <br> Attachments^.lpszPathName := PChar(FAttachedFileName.Strings[i - 1]); <br> { ... and the displayname: } <br> Attachments^.lpszFileName := PChar(FDisplayFileName.Strings[i - 1]); <br> Attachments^.ulReserved := 0; <br> Attachments^.flFlags := 0; <br> { Position has to be -1, please see the WinApi Help <br> for details. } <br> Attachments^.nPosition := Cardinal(-1); <br> Attachments^.lpFileType := nil; <br> Inc(Attachments); <br> end; <br> end; <br> lpFiles := PFiles; <br> end <br> else <br> begin <br> nFileCount := 0; <br> lpFiles := nil; <br> end; <br> end; <br><br> { Send the Mail, silent or verbose: <br> Verbose means in Express a Mail is composed and shown as setup. <br> In non-Express versions we show the Login-Dialog for a new <br> session and after we have choosen the profile to use, the <br> composed email is shown before sending <br><br> Silent does currently not work for non-Express version. We have <br> no Session, no Login Dialog so the system refuses to compose a <br> new email. In Express Versions the email is sent in the <br> background. <br> } <br> if FShowDialog then <br> MError := MapiSendMail(0, AppHandle, MapiMessage, MAPI_DIALOG or MAPI_LOGON_UI or MAPI_NEW_SESSION, 0) <br> else <br> MError := MapiSendMail(0, AppHandle, MapiMessage, 0, 0); <br><br> { Now we have to process the error messages. There are some <br> defined in the MAPI unit please take a look at the unit to get <br> familiar with it. <br> I decided to handle USER_ABORT and SUCCESS as special and leave <br> the rest to fire the "new" error event defined at the top (as <br> generic error) <br><br> Not treated as special: <br> MAPI_E_AMBIGUOUS_RECIPIENT, <br> MAPI_E_ATTACHMENT_NOT_FOUND, <br> MAPI_E_ATTACHMENT_OPEN_FAILURE, <br> MAPI_E_BAD_RECIPTYPE, <br> MAPI_E_FAILURE, <br> MAPI_E_INSUFFICIENT_MEMORY, <br> MAPI_E_LOGIN_FAILURE, <br> MAPI_E_TEXT_TOO_LARGE, <br> MAPI_E_TOO_MANY_FILES, <br> MAPI_E_TOO_MANY_RECIPIENTS, <br> MAPI_E_UNKNOWN_RECIPIENT: <br> } <br><br> case MError of <br> MAPI_E_USER_ABORT: <br> begin <br> if Assigned(FOnUserAbort) then <br> FOnUserAbort(Self); <br> end; <br> SUCCESS_SUCCESS: <br> begin <br> if Assigned(FOnSuccess) then <br> FOnSuccess(Self); <br> end <br> else begin <br> if Assigned(FOnMapiError) then <br> FOnMapiError(Self, MError); <br> end; <br><br> end; <br> finally <br> { Finally we do the cleanups, the message should be on its way } <br> FreeMem(Recipients, MapiMessage.nRecipCount * sizeof(TMapiRecipDesc)); <br> end; <br>end; <br><br>{ <br> Please treat this as free. If you improve the component <br> I would be glad to get a copy. <br>} <br><br>end. <br>