Addons für Outlook entwickeln
-
Hallo!
Ich suche seit längerem ein Tutorial/HowTo/Beispielscript für das Entwickeln von Addons/Plugins für Outlook mit dem Borland C++ Builder. Google hab ich jetzt schon einmal hoch und runter abgesucht, habe dort aber nur ein Delphi script gefunden welches schlecht kommentiert war. Das umschreiben in C++ Code hat dann auch nichts gebracht.
Also, wäre für jede Hilfe dankbar.
Gruß,
Enrico
-
Hallo Enrico,
was genau verstehst du denn unter einem Add-On? Es gibt verschiedene Möglichkeiten wie man Microsoft Produkte ansprechen bzw. sich einklinken kann. Erläutere doch mal, was du machen willst.
Gruß Skay
-
Skay schrieb:
Erläutere doch mal, was du machen willst.
Hallo Skay!
Ein Beispiel für ein Add-In wäre bxAutoZip [1]. Aber für den Anfang würde ich gerne ersmal einen Button z.B. in die Outlookleiste packen der per ShowMessage() den Text "Hello World" ausgibt.
Ich habe versucht das Beispiel [2] für Delphi auf Torry's nachzubauen. Leider bekomme ich das nicht so ganz hin, zumal es die genannten include-Dateien nicht gibt. Und diese Events (OnConnection, ...) hab ich auch nicht so ganz deklarieren können, weil es der Typ ext_ConnectMode nicht definiert ist.
Enrico
[1] http://www.baxbex.de/bxautozip.html
[2] http://www.swissdelphicenter.ch/torry/showcode.php?id=881
-
Also ich habe das von Dir angesprochene Delphi Beispiel auch einmal versucht unter Borland C++ Builder zu compilieren.
Bei mir hat es auch nicht funktioniert.
Ich komme aber auch mit den Erklärungen (Register as COM...) nicht zurecht.
Das Thema würde mich auch sehr interessieren!Hat niemand ein anderes Beispiel, Skript, Tutorial???
Gruß
Freddy
-
Habe das hier als Plugin für Word gefunden:
http://www.codeproject.com/com/adwordaddin.aspVielleicht kann man da die eine oder andere Info rausziehen?!
Gruß
Freddy
-
Vielleicht könnte man bei PGP in den Quelltext schauen.
Ist Open Source und die haben so ein Plugin für Outlook.
Aber keine Ahnung wo es den gibt und ob man sich da zurechtfindet.
-
Also hier ein kleines Update meiner Bemühungen

1. Datei > Neu > weitere > ActiveX > ActiveX-Bibliothek 2. Datei > Neu > weitere > ActiveX > Automatisierungsobjekt 3. Projekt > Typbibliothek importieren > Microsoft Add-In Designer > Unit anlegenDen 3ten Punkt wollte ich auch für Outlook machen, da sagt der aber das die Klasse TOutlookApplication schon existiert. Mal schaun ob ich die irgendwo finde.
Ich halte Euch auf dem laufenden

Enrico
-
Danke für Deine Tipps.
Gemeinsam kommt man doch eher zum Ziel.
Also bei mir hat Dein Schritt 3:
Projekt > Typbibliothek importieren > Microsoft Outlook -> Unit anlegen
auch funktioniert. Er hat also keine Fehlermeldung ausgespuckt.Dann hatte ich allerdings das Eingangs von Dir beschriebene Problem, es gäbe ext_ConnectMode nicht. Nach laaaangem Suchen habe ich den enum ConnectMode gefunden.
Lösung: Binde in der Header Datei (!) folgende Files ein:#include "C:\Programme\Borland\CBuilder5\Imports\AddInDesignerObjects_TLB.h" #include "C:\Programme\Borland\CBuilder5\Imports\Outlook_TLB.h"(Verzeichnisse evnt. anpassen)
Dann findet er auch ext_connectMode und bleibt nicht mehr hängen.
Dann weiter wie in der Delphi Seite beschrieben.
"Start | Register ActiveX Komponente" und den Eintrag in die Registry machen.Läuft alles Problemlos.
Aber wenn ich mein Outlook starte sehe ich keine Änderung. Irgendwie sehe ich da kein Plugin!
Aber ich denke wir sind kurz vor dem Ziel.Hat noch jemand irgendwelche Tipps parat?
Gruß
Freddy!
-
Freddy# schrieb:
Also bei mir hat Dein Schritt 3:
Projekt > Typbibliothek importieren > Microsoft Outlook -> Unit anlegen
auch funktioniert. Er hat also keine Fehlermeldung ausgespuckt.Im BCB6 gibt es bereits eine TOutlookApplication-Klasse, auch für verschiedene Versionen von Windows. Ein #include "outlook_2k_srvr.h" hat geholfen.
Freddy# schrieb:
Dann findet er auch ext_connectMode und bleibt nicht mehr hängen.
Dann weiter wie in der Delphi Seite beschrieben.
"Start | Register ActiveX Komponente" und den Eintrag in die Registry machen.Ich habe die UpdateRegistry-Methode in der AddIn-Klasse wie folgt verändert:
static HRESULT WINAPI UpdateRegistry(BOOL bRegister) { TRegistry *reg = new TRegistry; try { reg->RootKey = HKEY_CURRENT_USER; if (bRegister && reg->OpenKey("Software\\Microsoft\\Office\\Outlook\\Addins\\OutlookBouncer.TAddIn", true)) { reg->WriteString("FriendlyName", GetDescription()); reg->WriteInteger("LoadBehavior", 3); reg->CloseKey(); } else if (!bRegister && reg->KeyExists("Software\\Microsoft\\Office\\Outlook\\Addins\\OutlookBouncer.TAddIn")) { reg->DeleteKey("Software\\Microsoft\\Office\\Outlook\\Addins\\OutlookBouncer.TAddIn"); } } __finally { delete reg; } TTypedComServerRegistrarT<TTAddInImpl> regObj(GetObjectCLSID(), GetProgID(), GetDescription()); return regObj.UpdateRegistry(bRegister); }Der Key-String (OutlookBouncer.TAddIn) kann aber noch durch Methoden optimiert werden - GetProgID() ?? -.
Freddy# schrieb:
Läuft alles Problemlos.
Aber wenn ich mein Outlook starte sehe ich keine Änderung. Irgendwie sehe ich da kein Plugin!Also im Endeffekt wird ja noch kein Button etc. eingebunden wenn Du nur die Klassen deklarierst. Über die Methode OnConnection kommt man dann aber an der Pointer der auf Outlook zeigt und kann dann darüber Buttons hinzufügen.
Da ist jetzt aber das Problem das das AddIn meiner Meinung nach irgendwie von _IDTExtensibility2 oder IDTExtensibility2 abgeleitet werden muss - das wird auch im Beispiel gemacht. Um dann in der AddIn-Klasse die Methoden OnConnection, ... zu überschreiben. Aber wenn ich die AddIn Klasse versuche von _IDTExtensibility2 oder IDTExtensibility2 abzuleiten, bekomme ich folgenden Fehler:
[C++ Fehler] atlcom.h(1877): E2352 Instanz der abstrakten Klasse 'CComObject<TTAddInImpl>' kann nicht erzeugt werden [C++ Fehler] atlcom.h(1877): E2353 Klasse 'CComObject<TTAddInImpl>' ist abstrakt, weil '__stdcall IDispatch::GetTypeInfoCount(unsigned int *) = 0'Meine Vererbung sieht wie folgt aus:
class ATL_NO_VTABLE TTAddInImpl : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<TTAddInImpl, &CLSID_TAddIn>, public IDispatchImpl<ITAddIn, &IID_ITAddIn, &LIBID_OutlookBouncer>, public _IDTExtensibility2 { ... }Vielleicht weis ja jemand wie ich an den Application Pointer in der OnConnection-Methode komme:
public: TOutlookApplication *FOutlookApplication; HRESULT STDMETHODCALLTYPE OnConnection(LPDISPATCH Application, Addindesignerobjects_tlb::ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, LPSAFEARRAY* custom) { //FOutlookApplication = TOutlookApplication::CreateObject(Application); //= TOutlookApplication::Create(Application); } HRESULT STDMETHODCALLTYPE OnDisconnection(Addindesignerobjects_tlb::ext_DisconnectMode RemoveMode, LPSAFEARRAY* custom); HRESULT STDMETHODCALLTYPE OnAddInsUpdate(LPSAFEARRAY* custom); HRESULT STDMETHODCALLTYPE OnStartupComplete(LPSAFEARRAY* custom); HRESULT STDMETHODCALLTYPE OnBeginShutdown(LPSAFEARRAY* custom);Und der nächste

Enrico
-
Also, meine Add-In Klasse funktioniert soweit. Soll heißen, sie lässt sich kompilieren

Die schwarz markierten Teile habe ich hinzugefügt.
[cpp]
class ATL_NO_VTABLE TTAddInImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<TTAddInImpl, &CLSID_TAddIn>,
public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
public IDispatchImpl<ITAddIn, &IID_ITAddIn, &LIBID_OutlookBouncer>
{
public:
TTAddInImpl()
{
}// Bei der Registrierung des Objekts verwendete Daten
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID("OutlookBouncer.TAddIn");
DECLARE_DESCRIPTION("Bounce Add-In for Outlook");// Funktion wurde zum Aus- und Eintragen des Objekts aufgerufen
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
**TRegistry *reg = new TRegistry;try {
reg->RootKey = HKEY_CURRENT_USER;
if (bRegister && reg->OpenKey("Software\\Microsoft\\Office\\Outlook\\Addins\"+(AnsiString)TTAddInImpl::GetProgID(), true)) {
reg->WriteString("FriendlyName", TTAddInImpl::GetDescription());
reg->WriteInteger("LoadBehavior", 3);
reg->CloseKey();
} else if (!bRegister && reg->KeyExists("Software\\Microsoft\\Office\\Outlook\\Addins\"+(AnsiString)TTAddInImpl::GetProgID())) {
reg->DeleteKey("Software\\Microsoft\\Office\\Outlook\\Addins\\OutlookBouncer.TAddIn");
}
} __finally {
delete reg;
}**TTypedComServerRegistrarT<TTAddInImpl>
regObj(GetObjectCLSID(), GetProgID(), GetDescription());
return regObj.UpdateRegistry(bRegister);
}BEGIN_COM_MAP(TTAddInImpl)
COM_INTERFACE_ENTRY(ITAddIn)
COM_INTERFACE_ENTRY2(IDispatch, ITAddIn)
END_COM_MAP()// ITAddIn
public:
*HRESULT STDMETHODCALLTYPE OnConnection(LPDISPATCH Application, Addindesignerobjects_tlb::ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, LPSAFEARRAY custom)
{ HRESULT hr; return hr; }HRESULT STDMETHODCALLTYPE OnDisconnection(Addindesignerobjects_tlb::ext_DisconnectMode RemoveMode, LPSAFEARRAY* custom)
{ HRESULT hr; return hr; }HRESULT STDMETHODCALLTYPE OnAddInsUpdate(LPSAFEARRAY* custom)
{ HRESULT hr; return hr; }HRESULT STDMETHODCALLTYPE OnStartupComplete(LPSAFEARRAY* custom)
{ HRESULT hr; return hr; }HRESULT STDMETHODCALLTYPE OnBeginShutdown(LPSAFEARRAY* custom)
{ HRESULT hr; return hr; }**
};
[/cpp]So jetzt ist die Frage, wie ich in OnConnection an den Outlook-Pointer komme.
Zweite Frage, wieso unter Outlook "Extras > Optionen > Weitere > Erweiterte Optionen > COM-Add-Ins" immer erscheint das mein Add-In wegen eines Lautfzeitfehlers nicht geladen werden konnte und wie ich rausbekomme (vielleicht durchs Ereignislog??) wo der Fehler steht.Enrico
-
Juhu, es geht.
Folgendes
BEGIN_COM_MAP(TTAddInImpl) COM_INTERFACE_ENTRY(ITAddIn) COM_INTERFACE_ENTRY2(IDispatch, ITAddIn) COM_INTERFACE_ENTRY(_IDTExtensibility2) END_COM_MAP()muss in
BEGIN_COM_MAP(TTAddInImpl) COM_INTERFACE_ENTRY(ITAddIn) COM_INTERFACE_ENTRY2(IDispatch, ITAddIn) COM_INTERFACE_ENTRY(_IDTExtensibility2) END_COM_MAP()geändert werden, dann läuft alles.
