====== Outlook-COM-Schnittstelle ======
Die Outlook-Abstraktion (''OutlookSync.Outlook.pas'') kapselt alle COM-Aufrufe gegen Microsoft Outlook.
===== COM-Wrapper-Klassen =====
^ Klasse ^ COM-Objekt ^ Zweck ^
| ''TOutlookApplication'' | ''Outlook.Application'' | Haupteinstiegspunkt, Store- und Ordner-Navigation |
| ''TOutlookContactItem'' | ''ContactItem'' | Lesen/Schreiben einzelner Kontaktfelder |
===== Verbindungsablauf =====
- **''GetActiveOleObject('Outlook.Application')''** — Verbindet sich mit laufender Outlook-Instanz
- **Store-Enumeration** — Iteriert über ''Session.Stores'' (Accounts + freigegebene Postfächer)
- **Ordner-Navigation** — Löst ''outlookFolderPath'' relativ zum gewählten Store auf
- **Kontakt-Iteration** — ''Items''-Collection des Ordners
Die Anwendung startet Outlook **nicht** automatisch (kein ''CreateOleObject''). Ein automatischer COM-Start würde den UI-Thread blockieren.
===== ContactItem-Felder =====
Outlook stellt 52 Standard-Kontaktfelder als Properties des ''ContactItem''-COM-Objekts bereit:
==== Lesen ====
{ Direct property access via OLE automation }
Value := ContactItem.OlePropertyGet('FirstName');
Value := ContactItem.OlePropertyGet('Email1Address');
Value := ContactItem.OlePropertyGet('BusinessTelephoneNumber');
==== Schreiben ====
{ Direct property set via OLE automation }
ContactItem.OlePropertySet('FirstName', AValue);
ContactItem.OleProcedure('Save');
==== Spezialfälle ====
^ Feld ^ Besonderheit ^
| ''Birthday'', ''Anniversary'' | Sentinel-Datum ''01.01.4501'' = "nicht gesetzt" → wird als leerer String behandelt |
| ''Email1DisplayName'' | Read-only — wird automatisch aus E-Mail-Adresse und Name generiert |
| ''Body'' | Kann RTF oder Plaintext enthalten — nur Plaintext wird synchronisiert |
| ''Categories'' | Semikolon-getrennte Liste (z.B. ''"Kunde;VIP"'') |
----
===== UserProperties-API =====
Benutzerdefinierte Felder werden über die ''UserProperties''-Collection des ''ContactItem'' verwaltet.
==== Lesen ====
{ Find existing UserProperty }
Prop := ContactItem.OlePropertyGet('UserProperties').OleFunction('Find', AFieldName);
if not VarIsNull(Prop) then
Value := Prop.OlePropertyGet('Value');
==== Schreiben ====
{ Add or update UserProperty }
Prop := ContactItem.OlePropertyGet('UserProperties').OleFunction('Find', AFieldName);
if VarIsNull(Prop) then
Prop := ContactItem.OlePropertyGet('UserProperties').OleFunction('Add', AFieldName, olText);
Prop.OlePropertySet('Value', AValue);
==== Typ-Konstanten ====
^ Konstante ^ Wert ^ Outlook-Typ ^
| ''olText'' | 1 | String |
| ''olNumber'' | 3 | Double |
| ''olDateTime'' | 5 | DateTime |
| ''olYesNo'' | 6 | Boolean |
----
===== Fehlerbehandlung =====
COM-Aufrufe können ''EOleException'' oder ''EOleSysError'' auslösen. Typische Szenarien:
^ Exception ^ Ursache ^ Behandlung ^
| ''EOleException'' "RPC server unavailable" | Outlook wurde geschlossen | Benutzer informieren, Reconnect anbieten |
| ''EOleException'' "The operation failed" | Kontakt von anderem Prozess gesperrt | Warnung im Log, Kontakt überspringen |
| ''EOleSysError'' "Class not registered" | Outlook nicht installiert | Fehlermeldung mit Installationshinweis |
Alle COM-Exceptions werden gefangen und im MessageLog protokolliert — die Anwendung stürzt nie wegen eines COM-Fehlers ab.
----
===== Freigegebene Postfächer =====
Stores ohne direkte Outlook-Account-Zuordnung (freigegebene Postfächer, PST-Dateien) werden erkannt und mit dem Suffix ''(Shared)'' in der Kontenliste angezeigt.
Die Erkennung erfolgt über den Vergleich von ''Store.DisplayName'' mit ''Account.SmtpAddress'' — Stores ohne zugeordnetes Account werden als "Shared" klassifiziert.
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. — Outlook Sync//
{{tag>outlooksync entwickler outlook com automation userproperties}}