Entwickler-Ecke

Sonstiges (Delphi) - über Outlook E-Mail senden


toms - Mi 23.11.05 23:59
Titel: über Outlook E-Mail senden
Hallo

Moechte eine E-Mail ueber Outlook (2002 od. XP) senden.
Alles funktioniert ausser dass der Absender leer bleibt, obwowhl
dem MAPIMessage.lpOriginator der Absender zugewiesen wird.
Hat jemand was am Code nicht stimmt (oder liegt's am Outlook)?



Delphi-Quelltext
1:
2:
uses 
  MAPI;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
function SendEMail(Handle: THandle; Mail: TStrings): Cardinal;
type
  TAttachAccessArray = array[0..0of TMapiFileDesc;
  PAttachAccessArray = ^TAttachAccessArray;
var
  MapiMessage: TMapiMessage;
  Receip: TMapiRecipDesc;
  Origin: TMapiRecipDesc;
  Attachments: PAttachAccessArray;
  AttachCount: Integer;
  i1: integer;
  FileName: string;
  dwRet: Cardinal;
  MAPI_Session: Cardinal;
  WndList: Pointer;
begin
 // begin a Simple MAPI session
  dwRet := MapiLogon(Handle,
    PChar(''),
    PChar(''),
    MAPI_LOGON_UI or MAPI_NEW_SESSION,
    0, @MAPI_Session);

  if (dwRet <> SUCCESS_SUCCESS) then
  begin
    MessageBox(Handle,
      PChar('Error while trying to send email'),
      PChar('Error'),
      MB_ICONERROR or MB_OK);
  end
  else
  begin
    FillChar(MapiMessage, SizeOf(MapiMessage), #0);
    Attachments := nil;

    // Fill Receip property
    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;

    // Fill Origin(ator) property
    FillChar(Origin, SizeOf(Origin), #0);
    if Mail.Values['from'] <> '' then
    begin
      Origin.ulReserved := 0;
      Origin.ulRecipClass := MAPI_ORIG;
      Origin.lpszName := StrNew(PChar(Mail.Values['from']));
      Origin.lpszAddress := StrNew(PChar('SMTP:' + Mail.Values['from']));
      Origin.ulEIDSize := 0;
      Origin.lpEntryID := nil;
      MAPIMessage.lpOriginator := @Origin;
    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']));

    WndList := DisableTaskWindows(0);
    try
      Result := MapiSendMail(MAPI_Session, Handle,
        MapiMessage, MAPI_DIALOG, 0);
    finally
      EnableTaskWindows(WndList);
    end;

    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);
    if Assigned(Origin.lpszAddress) then
      StrDispose(Origin.lpszAddress);
    if Assigned(Origin.lpszName) then
      StrDispose(Origin.lpszName);
    MapiLogOff(MAPI_Session, Handle, 00);
  end;
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TfrmMain.btnSendClick(Sender: TObject);
var
  mail: TStringList;
  ssubject: string;
begin
  mail := TStringList.Create;
  try
    mail.values['from'] := 'from@xzy.net';
    mail.values['to'] := 'to@xzy.net';
    mail.values['subject'] := 'subject';
    mail.values['body'] := 'body';
    try
      sendEMail(Application.Handle, mail);
    except
    end;
  finally
    mail.Free;
  end;
end;


MSCH - Fr 25.11.05 20:04

sooo kompliziert.

versuchsmal damit, sofern du auf der Server-seite die Outlook Items hast.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TMain.HelpMailClick(Sender: TObject);
var
  TOA:TOutlookApplication;
  MI: MailItem;
begin
    TOA:=  TOutlookApplication.Create(Self);
    TOA.ConnectKind := ckRunningOrNew;
    try
      TOA.Connect;
    except
      TOA.Free;
      MessageDlg('Outlook kann nicht geöffnet werden!',mtError,[mbok],0);
      exit;
    end;
    MI:= TOA.CreateItem(olMailItem) as MailItem;
    MI.Attachments.Add('Dateiname',emptyParam,EmptyParam,EmptyParam); // Attachment
    MI.HTMLBody:='HTML Body'// ersetzen
    MI.Subject:='Subjekt';
    MI.Companies:= 'Your Company';
    MI.Categories:='HelpDesk';
    MI.Recipients.Add('Somewhere@never.go');
    MI.Display(1);
// Achtung hier wird die erzeugt Mail automatisch geöffnet, 
// da Outlook ab 2002 keinem externen Programm mehr gestattet, darüber
// eine Mail zu senden. Der User muß explizit das erlauben
// daher wird diese Mail erstmal angezeigt, der Outlook Warnhinweis entfällt
    TOA.Disconnect;
    TOA.Free;
end;

grez
msch


FFKangoroo - Di 09.05.06 12:14

Halli Hallo
hab mal eine Frage zu dem Ansatz von MSCH.

Ich hab das mal so in mein Programm übernommen(eher gesagt versucht), hab auch die Outlookapplication in meine Form gezogen und es compiliert. Soweit gab es keine Fehler. Wenn ich dann aber die Procedur aufrufe. Stürzt das Programm ab und sagt mir:
"Im Projekt Projekt.exe ist eine Exeption der Klasse EOleSysError aufgetreten. Meldung:'Klasse nicht registriert'. Prozess wurde angehalte. Mit Einzelne Anweisung oder Start fortsetzen."
und das bei der Zeile: "TOA.Connect;"

Warum? und Wie krieg ich es weg? Hab ich villeicht ein Uses nicht eingebunden?

oder was ist mit "Server-Seite" gemeint (hab es einfach nur in der Form.

Danke jetzt schon mal !!!

Das FFKangoroo


Keldorn - Di 09.05.06 20:02

Hallo

hast du auch outlook (nicht outlookexpress!) installiert auf deinem Rechner?

Mfg Frank


FFKangoroo - Mi 10.05.06 17:12

Hehe jop daran lags!
Danke jetzt funktioniert es


Kuh - Sa 25.10.08 18:02

bin ich jetzt blind oder verschickt die procedure von MSCH die email nicht?

bei mir öffnet sich ein Fenster und dort kann ich dann den text usw schreiben. das einzige was ich nicht kann ich absenden.
oder ist speichern = senden???
(was ist für äußert unrealistisch halte)


MSCH - Sa 25.10.08 18:34

Imho sollte das Formular wie es outlook verwendet zum E-Mail schreiben angezeigt werden und die Werte die in der Funktion gesetzt werden (subjekt, etc) bereits enthalten sein.
Das einzige was fehlt sind die Ansender-Mailadressen.

Achtung: das Teil zeigt wirklich das Outlook-Formuar an. Wenn du dort die Buttonleiste ausgeblendet hast,
siehst du auch nicht den Schalter "Senden".
:-)Msch


Nilius - Mi 25.05.11 09:31

user profile iconMSCH hat folgendes geschrieben Zum zitierten Posting springen:
sooo kompliziert.

versuchsmal damit, sofern du auf der Server-seite die Outlook Items hast.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TMain.HelpMailClick(Sender: TObject);
var
  TOA:TOutlookApplication;
  MI: MailItem;
begin
    TOA:=  TOutlookApplication.Create(Self);
    TOA.ConnectKind := ckRunningOrNew;
    try
      TOA.Connect;
    except
      TOA.Free;
      MessageDlg('Outlook kann nicht geöffnet werden!',mtError,[mbok],0);
      exit;
    end;
    MI:= TOA.CreateItem(olMailItem) as MailItem;
    MI.Attachments.Add('Dateiname',emptyParam,EmptyParam,EmptyParam); // Attachment
    MI.HTMLBody:='HTML Body'// ersetzen
    MI.Subject:='Subjekt';
    MI.Companies:= 'Your Company';
    MI.Categories:='HelpDesk';
    MI.Recipients.Add('Somewhere@never.go');
    MI.Display(1);
// Achtung hier wird die erzeugt Mail automatisch geöffnet, 
// da Outlook ab 2002 keinem externen Programm mehr gestattet, darüber
// eine Mail zu senden. Der User muß explizit das erlauben
// daher wird diese Mail erstmal angezeigt, der Outlook Warnhinweis entfällt
    TOA.Disconnect;
    TOA.Free;
end;

grez
msch



Hiho sry fürs Ausgraben der Leiche, aber Suchfunktion halt ;)

Kann mir jmd sagen welche uses ich dafür adden muss? Hab derzeit nur die Standard uses drin die Delphi automatisch reinbackt. Er sagt TOutlookApplication kennt er net und MailItem auch net... Und dazu wüsst ich dann gern noch wofür folgende Dinge stehen:


HTMLBody
Subjekt (Betreff?)
Companies
Categories
Display (Wieviele Mails angezeigt werden?)

Lg
Nilius


jaenicke - Mi 25.05.11 10:47

user profile iconNilius hat folgendes geschrieben Zum zitierten Posting springen:
Kann mir jmd sagen welche uses ich dafür adden muss?
Kleiner Tipp:
Geh einfach zu deinem Delphiverzeichnis und gib in das Suchfeld des Windows Explorers TOutlookApplication ein...

DelphiXESearch

Schon siehst du, dass es die Unit OutlookXP gibt, in der dieser Text vorkommt. ;-)

user profile iconNilius hat folgendes geschrieben Zum zitierten Posting springen:
HTMLBody
Naja, der Quelltext der Mail schätze ich mal. :zwinker:


Nilius - Mi 25.05.11 11:59

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Habe bei mir auf dem Rechner Office 2000 drauf. Finde aufm ganzen PC aber keine Datei für Delphi wo "TOutlookApplication" drin steht. :( Kannst du mir vllt sagen wo ich die herbekommen kann?


jaenicke - Mi 25.05.11 12:17

user profile iconNilius hat folgendes geschrieben Zum zitierten Posting springen:
Habe bei mir auf dem Rechner Office 2000 drauf. Finde aufm ganzen PC aber keine Datei für Delphi wo "TOutlookApplication" drin steht. :(
Wenn dein Office schon so antik ist, ist es vielleicht dein Delphi auch? Die alten Personal Editions hatten diese Komponenten nicht dabei, nur die Kaufversionen und Turbo Delphi (und jetzt natürlich die Starter XE). ;-)

Ich weiß nicht, ob du bei dir zumindest Komponenten importieren kannst. Wenn ja, kannst du nach der von Outlook suchen und die importieren (Komponente --> Komponente importieren... oder ActiveX-Control importieren... oder so). Aber frag mich nicht wie der Eintrag dort bei deinem Office 2000 hieß... zu lange her...


Nilius - Do 26.05.11 12:15

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Delphi is D7 Personal

Hab keine .pas oder .bpl im Office verzeichnis, aber einige .ocx:

ASFCHOP
MSCAL
QUACTRL
FPATL
HTMLMARQ
HTMLMM

Nu hab ich davon absolut keine Ahnung (Hab bisher noch nie zu irgendnem andern Programm verlinkt^^)

Könnte davon dass eine sein oder sind das alles irgendwelcher anderer Krams..?


jaenicke - Do 26.05.11 12:39

Du sollst doch auch gar nicht nach irgendwelchen Dateien suchen sondern in Delphi auf das Menü Komponente klicken. Wenn es dort keinen Befehl zum Importieren gibt, hast du leider Pech, dann geht das mit deiner Delphiversion nicht. Die Personal ist halt eingeschränkt.


Nilius - Do 26.05.11 12:41

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.
Da hast du mich grad missverstanden, Komponente hinzufügen und co hab ich alles da( also die Befehle dafür), ich weiß nur net welche von denen ich jetzt benutzen muss.


jaenicke - Do 26.05.11 14:29

Wenn du da nur Delphikomponenten hinzufügen kannst, dann geht es nicht.

Welche Befehle hast du denn im Menü Komponente?


Nilius - Fr 27.05.11 16:36

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Du sollst doch auch gar nicht nach irgendwelchen Dateien suchen sondern in Delphi auf das Menü Komponente klicken. Wenn es dort keinen Befehl zum Importieren gibt, hast du leider Pech, dann geht das mit deiner Delphiversion nicht. Die Personal ist halt eingeschränkt.


Die oben gelisteten .ocx sind im OFFICE verzeichnis.

Ich hab im Komponente Menü drin:

Neue Komponente...
Komponente installiern...
ActiveX importieren...
Packages installiern
Palette konfiguriern


Dass einzige was nich hinterlegt is is: Komponentenvorlage erzeugen.


jaenicke - Fr 27.05.11 16:50

user profile iconNilius hat folgendes geschrieben Zum zitierten Posting springen:
ActiveX importieren...
Und das hatte ich oben ja erwähnt. Dort musst du nach den Outlook Komponenten suchen. Wenn die dort nicht stehen, wird es wohl nicht gehen. :nixweiss:


Nilius - Fr 27.05.11 16:53

darum fragte ich ob du weißt ob ich die outlookxp.pas irgendwo herkriege internet mäßig...^^


jaenicke - Fr 27.05.11 17:24

Die wird dir nicht viel nutzen, weil du die kaum mit der alten Delphiversion kompilieren können wirst.

Wenn, dann würde die Outlook8 Unit von Delphi 5 oder so helfen, aber da da der Quelltext nicht dabei war, geht auch das nicht. Wenn, dann würde eine mit Delphi 7 Enterprise oder so importierte Version gehen. Aber die darf dir aus Copyright-Gründen evtl. niemand geben (jedenfalls nicht die mitgelieferten), aber keine Ahnung.

Es gibt aber glaube ich auch ein Kommandozeilentool, mit dessen Hilfe man Typbibliotheken damals importieren konnte. Aber das habe ich nie so wirklich benutzt, deshalb weiß ich nicht, ob es dir hier hilft. (Außerdem ist auch das wiederum wohl nicht bei der Personal dabei...)

Du hast nicht zufällig eine Lizenz von Turbo Delphi, oder? Da sind die Komponenten nämlich dabei...
Und bei Delphi XE Starter hast du die natürlich auch dabei, das wäre auch eine Möglichkeit.

Sonst bleibt wohl nur der "umständliche" Weg via CreateOleObject:
http://www.delphipraxis.net/64349-outlook-aufgaben-exportieren.html
Das geht, aber du musst auf jegliche Syntaxergänzung etc. verzichten...


Nilius - Fr 27.05.11 17:34

Habe grade nochmal mit jemandem gesprochen der vor Jahren mal mit Delphi gearbeitet hat. Es geht bei mir nur darum eine Email-Adresse die in einer Edit Box eingegeben ist in die Adresszeile einer Email im Outlook zu kriegen, !!was auf dem PC wo das Programm verwendet wird Standardemailprogramm ist!!, und er meinte wenns Standard ist gibt es bei Delphi sowas ähnliches wie "mailto" bei html. Kannst du mir da eventuell helfen? Das würde mein Problem ja auch lösen^^


Narses - Fr 27.05.11 18:54

Moin!

user profile iconNilius hat folgendes geschrieben Zum zitierten Posting springen:
wenns Standard ist gibt es bei Delphi sowas ähnliches wie "mailto" bei html. Kannst du mir da eventuell helfen? Das würde mein Problem ja auch lösen^^
Such mal nach Suche in: Delphi-Forum, Delphi-Library SHELLEXECUTE MAILTO, sollte sowas hier liefern [http://www.delphi-forum.de/viewtopic.php?p=399994#399994]. :lupe: :les: :think: ;)

cu
Narses


Nilius - Mo 30.05.11 11:05

Danke euch beiden. Soweit funktioniert dass dann jetzt :)