Home » Tipps & Tricks » COM/OLE/DDE » Andere Office-Anwendungen » Outlook mit OLE-Automation steuern

Outlook mit OLE-Automation steuern

Wie kann ich Outlook starten?

Sie werden feststellen, dass das einfache Starten der Outlook-Anwendung nicht genug ist, um sie zum laufen zu bekommen – Sie müssen auch den Namespace bekommen und die Logon-Methode aufrufen, etwa so:

NmSpace.Logon('', '', False, False);

Ich habe diese Zeile in den folgenden Code-Stückchen verwendet, beachten Sie aber, dass Sie evtl. unterschiedliche Argumente an diese Methode übergeben müssen, wenn Sie Benutzerprofile auf Ihrem Computer eingerichtet haben. Die Logon-Methode benötigt vier Parameter: Die ersten zwei, Profil und Passwort, sind selbsterklärend. Der dritte, ShowDialog, ermöglicht Ihnen, den Logon-Dialog dem Anwender anzuzeigen. Wenn der vierte, NewSession, auf true gesetzt ist, wird lieber eine neue MAPI-Session gestartet als eine existierende zu verwenden.
Behalten Sie im Hinterkopf, dass Sie Outlook nicht sehen werden, wenn Sie eingeloggt sind – bis Sie einen Ordner anzeigen wie in den folgenden Beispielen gezeigt.

Verwenden der D5-Komponenten:

Setzen Sie eine Outlook-Application-Komponente auf Ihr Formular. Wenn Outlook gestartet werden soll, verwenden Sie seine Connect-Methode:

  var
    NmSpace: NameSpace;
    Folder: MAPIFolder;
  ...
    OutlookApplication1.Connect;
    NmSpace := OutlookApplication1.GetNamespace('MAPI');
    NmSpace.Logon('', '', False, False);
    Folder := NmSpace.GetDefaultFolder(olFolderInbox);
    Folder.Display;

Weil Sie sich in den MAPI-Namespace einloggen müssen, wenn Sie starten, macht es keinen großen Sinn, die AutoConnect-Eigenschaft von OutlookApplication auf true zu setzen. Und die ConnectKind-Eigenschaft auf ckRunningOrNew zu setzen, ist genauso witzlos – wenn Sie Outlook automatisieren, werden Sie immer eine neue Instanz davon bekommen – auch wenn Outlook selbst eine existierende MAPI-Session verwendet, wenn es eine gibt.
Ist Outlook einmal gestartet, können Sie andere Komponenten, wie TMailItem, damit verbinden, indem Sie die ConnectTo-Methode verwenden. Hier ein Beipspiel:

MailItem1.ConnectTo(OutlookApplication1.CreateItem(olMailItem) as MailItem);

Mit der Typbibliothek (frühe Bindung):

Bevor Sie diese Methode verwenden können, müssen Sie die Outlook-Typbibliothek importiert haben (außer Sie haben Delphi 5).
Eine Art, Outlook zu starten, ist den Aufruf von GetActiveObject auszuprobieren (try-Abschnitt), um eine bereits laufende Outlook-Instanz zu erhalten, es sollte aber ein Aufruf von CoApplication.Create im except-Teil stehen. Aber except-Klauseln sind langsam und können bei Leuten, die gerne „Bei Exceptions anhalten“ aktiviert haben, Probleme innerhalb der IDE auslösen. Der folgende Code benötigt keine try-except-Konstruktion, weil die Verwendung von OleCheck bei GetActiveObject im Fall, dass Outlook nicht läuft, vermieden wird.

uses Windows, ComObj, ActiveX,
            Outlook_TLB;  // Outlook8; for D5 users

var
  Outlook: _Application;  // OutlookApplication; for D5 users
  Unknown: IUnknown;
  Result: HResult;
  NmSpace: NameSpace;
  Folder: MAPIFolder;
begin
  {$IFDEF VER120}      // Delphi 4
  Outlook := CoApplication_.Create;
  {$ELSE}              // Delphi 5
  Outlook := CoOutlookApplication.Create;
  {$ENDIF}

  NmSpace := Outlook.GetNamespace('MAPI');
  NmSpace.Logon('', '', False, False);
  Folder := NmSpace.GetDefaultFolder(olFolderInbox);
  Folder.Display;
  ...

Ohne Verwendung der Typbibliothek:

Automation ist sehr viel schneller und einfacher, wenn Typbibliotheken (frühe Bindung) verwendet werden, deshalb sollten Sie es, wenn immer möglich, vermeiden, ohne sie zu arbeiten. Aber wenn es wirklich nicht anders geht, hier, wie vorzugehen ist:

var
  Outlook, NmSpace, Folder: OleVariant;
begin
  Outlook := CreateOleObject('Outlook.Application');
  NmSpace := Outlook.GetNamespace('MAPI');
  NmSpace.Logon(EmptyParam, EmptyParam, False, True);
  Folder := NmSpace.GetDefaultFolder(olFolderInbox);
  Folder.Display;

Wie kann ich Outlook schließen?

Angenommen, Ihre Outlook-Application-Variable heißt Outlook, und die Namespace-Variable, mit der sie eingeloggt sind, heißt NmSpace:

  NmSpace.Logoff;
  Outlook.Quit;
  Outlook.Disconnect;    // Using the D5 components
  { or }
  Outlook := nil;        // Early binding with interfaces
  { or }
  Outlook := Unassigned; // Late binding with variants

Wie kann ich eine E-Mail erstellen?

Bei früher Bindung:

var
  MI: MailItem;
begin
  MI := Outlook.CreateItem(olMailItem) as MailItem;
  MI.Recipients.Add('Debs@djpate.freeserve.co.uk');
  MI.Subject := 'Greetings, O gorgeous one';
  MI.Body := 'Your web pages fill me with delight';
  MI.Attachments.Add('C:CreditCardNo.txt', EmptyParam, EmptyParam, EmptyParam);
  MI.Send;

Bei später Bindung

muss MI eine Variant-Variable sein:

const
  olMailItem = 0;
var
  MI: Variant;
begin
  MI := Outlook.CreateItem(olMailItem);

Der Rest des Codes ist der gleiche wie bei früher Bindung.
In Outlook 98 können Sie auch HTML-formatierte Mails versenden, indem Sie das HTML als String der HTMLBody-Eigenschaft von MailItem zuweisen anstatt der Body-Eigenschaft. Dies ist mit Outlook 97 aber nicht möglich, und deshalb kann es mit den D5-Komponenten auch nicht durchgeführt werden, außer Sie importieren die Typbibliothek von Outlook 98 (MSOutl85.olb).
Unglücklicherweise scheint es keinen Weg zu geben, RTF-formatierte Mails zu versenden.

Wie kann ich E-Mails senden und empfangen?

Dieser Code aktiviert den Tools|Send- und Recieve|All accounts-Menüpunkt.

uses Office_TLB; // Office97 for D5 users
var
  ToolsMenu: CommandBar;
  SendRecMenuItem, AllAccs: CommandBarControl;
begin
  ToolsMenu := (Outlook.ActiveExplorer.CommandBars as CommandBars).Item['Tools'];

  // D5 users can omit the underscore after 'Controls' in the next two lines
  SendRecMenuItem := ToolsMenu.Controls_['Send and Receive'];
  AllAccs := (SendRecMenuItem.Control as CommandBarPopup).Controls_['All Accounts'];
  AllAccs.Execute;

Wenn Sie Outlook 2000 verwenden, müssen Sie ‚Send and Receive‘ evtl. durch ‚Send/Receive‘ ersetzen. (Ich hatte einen Fall, wo es funktionierte, und einen, wo nicht, vielleicht müssen Leerzeichen den ‚/‘ umgeben? Jede Klärung dieser Sache wäre sehr willkommen!)

Wie kann ich auf ungelesene E-Mails prüfen?

var
    Inbox: MAPIFolder;
    NewMail: boolean;
  ...
    Inbox := NmSpace.GetDefaultFolder(olFolderInbox);
    NewMail := (Inbox.UnreadItemCount > 0);
    if NewMail then
      ShowMessage(Format('Unread items in Inbox: %d', [Inbox.UnreadItemCount]));

Die Konstante olFolderInbox ist in Outlook_TLB definiert als $00000006.

Wie kann ich auf nicht versandte E-Mails prüfen?

var
    Outbox: MAPIFolder;
    UnsentMail: integer;
  ...
    Outbox := NmSpace.GetDefaultFolder(olFolderOutbox);
    UnsentMail := Outbox.Items.Count;
    if (UnsentMail > 0) then
      ShowMessage(Format('Unsent items in Outbox: %d', [UnsentMail]));

Die Konstante olFolderOutbox ist in Outlook_TLB definiert als $00000004.