Świat lubi być SKOMPLIKOWANY. A Twórcy Outlooka chcieli go jeszcze bardziej SKOMPLIKOWAĆ. Szczerze, im dłużej pracuję z outlook tym mój kod przypomina papkę nie powiem czego. To jest jak z językiem polskim, wyjątek na wyjątku.

Tym razem sprawa dość oczywista…. By się wydawało. W outlook do wersji 2010 odpowiadanie na maila było proste. Klikało się reply i w nowym oknie pisaliśmy odpowiedź. Mogliśmy to zapisać, zamknąć, otworzyć ponownie z folderu draft. Praca nad mailem była przyjemna. Osoby piszące kod po Outlook musiały jedynie głowić się pomiędzy formatami:

  • Plain text
  • HTML
  • RTF/Word

Potem to się zmieniło i tak naprawdę należy się martwić o formaty Plain text i Word. Niby możemy przekonwertować plain text na word i całą edycję robić tak jak z word, ale to potem nie zawsze fajnie się konwertuje do plain text. Więc kiedy piszemy kod to mamy trzy opcje dostępu do treści maila:

// mail -> _MailItem
mail.Body
mail.HTMLBody

// Word = Micorosoft.Office.Interop.Word
Word.Document document = mail.GetInspector.WordEditor as Word.Document;

No ta trzecia opcja nie była jakaś taka… łatwa/domyślna. Ale ogólnie mając obiekt _MailItem byliśmy wstanie zrobić wszystko.

Potem nastały czasy Outlook 2013…………. dalej jestem wkurzony więc może trochę emocjonalnie do tego mogę podchodzić. Outlook 2013 wprowadził tak zwany inline response czyli klikamy reply i zamiast okna piszemy nasz mail w reading pane.

Inline Response Outlook 2016
Inline Response Outlook 2016

Opcja fajna. Przydatna i przyjemna. Tylko, że… w tej opcji kod:

Word.Document document = mail.GetInspector.WordEditor as Word.Document;

Zadziała nie tak jak byśmy tego chcieli. Umożliwi nam on edycję maila, na który chcemy odpowiadać ;) Czyli COŚ JEST WIELEKIE NIE HALO!

I macie RACJĘ, jest nie halo i to jak nie halo…. W tym wypadku nie możemy wykorzystać z WordEditor od Inspector, ale musimy taki uzyskać od _Explorer. Oj, co to _Explorer? No właśnie, jest to okno w którym wyświetla się foldery/pliki. Więc teraz jak się do tego możemy dobrać? Jest tylko jedna droga i wiedzie ona przez aplikację (obiekt aplikacji Outlook):

var explorer = Application.ActiveExplorer();

Czyli teraz, jeżeli jakoś opakowaliśmy nasz kod to musimy do niego albo przekazać Explorer albo Application byśmy mogli pobawić się w edycję treści maila. Jak już mamy nasz obiekt _Explorer to co dalej?

No teraz mamy dwie wartości:

  • ActiveInlineResponse
  • ActiveInlineResponseWordEditor

Jedna daje nam _MailItem który aktualnie jest wyświetlony w inline response – jeżeli jakiś. Jeżeli nie ma, to wartość jest null lub może rzucić wyjątkiem. To też jest JEDYNY SPOSÓB by dowiedzieć się czy jesteśmy w inline response mode – ale tylko i wyłącznie po tym jak zdarzenie zdarzenie InlineResponse zostanie wywołane. Próba sprawdzenia wcześniej nie powiedzie się.

Druga ActiveInlineResponseWordEditor zwróci nam edytor, w którym możemy modyfikować nasz mail.

Ale…. Jeżeli piszemy plugin który ma wspierać officy od 2007 wzwyż to NIE MAMY TYCH PROPERTIES :D Na szczęście reflection przychodzi nam z pomocą:

var explorer = Application.ActiveExplorer();
var document = explorer.GetType()
.InvokeMember("ActiveInlineResponseWordEditor"
, System.Reflection.BindingFlags.GetProperty
| System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.Public
, null
, explorer
, null) as Word.Document;

Ale oczywiście wykonujemy to jak wiemy, że jesteśmy w inline response mode.

Podsumowanie

Ja tego po prostu nie rozumiem. CZEMU oni tak komplikują te sprawy. A do tego komplikują i to ma bardzo duże znaczenie. To czy wykorzystamy edytor z poziomu _Inspector czy _Explorer oznacza czy nasza aplikacja zadziała czy nie zadziała.

ZOSTAW KOMENTARZ