MSDN Blogs
  • Office Development is more than VBA

    Happy Holidays

    • 0 Comments

    Ich wünsche allen regelmäßigen und sporadischen Besuchern dieses Blogs

    Fröhliche Weihnachten und ein erfolgreiches Jahr 2007

     

  • Office Development is more than VBA

    Wieviel Anpassbarkeit braucht der (Office-) Mensch?

    • 0 Comments

    Wenn wir über Erweiterbarkeit des Ribbon UI reden, kommen schnell auch die Power User zu Wort, welche sich die Menüs und Toolbars extensiv angepaßt hatten. Für diese ist die Welt nicht mehr so in Ordnung, wie sie mal war zu Zeiten von Office 2003. Die einzige Anpaßbarkeit, die Office 2007 bietet, ist die QAT, die Quick Access Toolbar. Und die ist relativ unflexibel, können doch die darin enthaltenen Befehle (immerhin ist eine Auswahl aus allen Befehlen möglich) nur über [ALT]+[Zugriffscode] angesprochen werden, sofern man nicht die Maus verwendet.

    Es können ganze Gruppen in die QAT gehängt werden, wie z.B. Alignment

    Und die Anordnung ist auch limitiert - über oder unter dem Ribbon. Das hat Ursachen: Schwebende Toolbars, die von Dokumenten verdeckt werden oder gar Dokumente verdecken haben sich als kontraproduktiv für die Mehrzahl der Anwender herausgestellt. Power User, die mit dem System problemlos klar kommen, stehen im Regen. Oder ist die Veränderung der eigenen Arbeitsweise von Zeit zu Zeit gar nicht so schlecht?

    Für den Hersteller bedeutet es nämlich jede Menge Arbeit und Supportaufwand, wenn alles in jeder Art und Weise anpaßbar ist. Wenn es viele nutzen würden, kein Problem. Aber Umfragen zufolge nutzt nur ein ganz geringer Teil aller Anwender (<2%) angepaßte Toolbars und von denen sind es wiederum nur 15%, die 4 oder mehr Befehle angepaßt hatten. (Source). Bei 450 Mio MS Office Anwendern sind das immerhin noch 1,35 Mio.

    Es gibt z.B. den Ribbon Customizer vom Patrick Schmid (Office MVP), mit dem die dem Programmierer verfügbaren Anpaßmöglichkeiten auch dem Anwender zur Verfügung stehen. Werden solche Tools benötigt? Sind sie gar sinnvoll?

    Mich würde interessieren, wie Sie darüber denken. Schreiben Sie einen Kommentar dazu, wie Sie zur Anpaßbarkeit des UI stehen. Aus der Sicht des Anwenders wohlgemerkt, also keine Programmierung.

     

  • Office Development is more than VBA

    2007 Microsoft Office System - RibbonExtensibility (Teil 2)

    • 2 Comments

    (Ein Update auf Basis VSTO 2005 SE - Fortsetzung von Teil 1

    Ändern bestehender Ribbon Elemente

     

    Bisher hatten wir lediglich neue Tabs und darin neue Gruppen erzeugt. Können wir uns auch in bestehende Tabs bzw. Gruppen von Office 2007 „einmischen“? Ja, wir können bestehende Tabs verwenden, um eigene Gruppen hinzuzufügen. Nein, wir können bestehende Gruppen nicht verändern. Das würde das Konzept der Ribbons torpedieren. Schließlich gibt es ja Tabs, die kontextabhängig Ihren Inhalt preisgeben und das sollte auch nur solcher Inhalt sein, der gerade Sinn macht.

    Um uns in bestehende Tabs zu integrieren, benötigen wir die ganz am Anfang einmal erwähnte idMso und den Namen der zu verändernden Tabs. Des Weiteren kommt uns bei der Platzierung der neuen Gruppe das insertAfterMso Attribut zugute. Genau nach der angegebenen eingebauten Gruppe wird unsere neue angeordnet. Eine Liste der Bezeichnungen eingebauter Elemente finden Sie hier. Im folgenden Beispiel wird im Tab View eine Gruppe „My View / Hide“ erzeugt, und zwar nach einer vorhandenen Gruppe mit der id GroupViewShowHide. Wichtig ist auch hier: die Begriffe sind case-sensitiv, also besser nicht verschreiben.

     

    <tab idMso="TabView">

      <group id="MyViewHide" label="My View / Hide" insertAfterMso="GroupViewShowHide" >

        <toggleButton id="tgViewHideProps"

                      size="large"

                      imageMso="FileProperties"

                      label="View / Hide Property Panel"

                      onAction="OnViewHideProps"/>

      </group>

    </tab>

     

    Über das Globals-Objekt kann auf das Objektmodell der Hostanwendung zugegriffen werden:

     

    public void OnViewHideProps(Office.IRibbonControl control, bool pressed)

    {

      Globals.ThisAddIn.Application.DisplayDocumentInformationPanel = pressed;

    }

     

     

    Verwenden von eingebauter Funktionalität

     

    Brauchen Sie Funktionalität, die in die Hostanwendung schon eingebaut ist, allerdings an anderer Stelle? Auch kein Problem. Mit Hilfe der Ids der eingebauten Controls können wir diese dort plazieren, wo wir wollen, z.B. in einer eigenen Gruppe:

     

    <group id="BuiltInControlGroup" label="Group of built-in Controls">

      <comboBox idMso="Font"/>

      <comboBox idMso="FontSize"/>

      <separator id="sep3"/>

      <buttonGroup id="BuiltInControls">

        <splitButton idMso="BordersGallery"/>

        <gallery idMso="CellFillColorPicker"/>

        <gallery idMso="FontColorPicker"/>

      </buttonGroup>

      <buttonGroup id="BuiltInSimpleControls">

        <toggleButton idMso="Bold" />

        <toggleButton idMso="Italic" />

        <toggleButton idMso="Underline" />

      </buttonGroup>

    </group>

     

    Sogar ganze Gruppen können einfach in eigene Tabs übernommen werden :

     

    <group idMso="GroupViewShowHide">

    </group>

     

    <group idMso="GroupFont">

    </group>

     

    Sie brauchen auch keine Callback Handler zu deklarieren, da die Funktionalität schon an den Controls hängt. Wenn Sie also der (Toggle) Button für Fettschrift in einen Word Ribbon einbauen, dann können Sie damit markierte Bereiche mit dem Stil Fettschrift versehen.

    Repurposing von eingebauten Befehlen

     

    Für das Überschreiben von eingebauten Befehlen mit eigener Logik gab es in Microsoft Office verschiedene Wege. So wurde der Speichern-Befehl überschrieben, wenn wir ein VBA Makro mit dem Namen FileSave() angelegt haben. Wir konnten auch die OnAction Property des Buttons auf eine eigene Routine setzen (und dann feststellen, dass [Ctrl]+[s] immer noch den originalen Befehl ausführt) oder auf den Click Event des Save Buttons lauschen und im Event Handler CancelDefault auf true setzen, damit die eingebaute Aktion nicht ausgeführt wird.

    Mit Ribbons in Office 2007 können wir unser Ribbon XML File hernehmen und die Änderung hier durchführen. Es existiert eine <commands> Sektion (außerhalb der Tabs), die genau dafür gedacht ist. Hier können wir einen neuen onAction Callback Handler verdrahten und ebenfalls – sozusagen in einem Atemzug – auch noch steuern, ob der Befehl überhaupt zur Verfügung stehen soll.

     

    <commands>

      <command idMso="Save" onAction="mySave" getEnabled="getEnabled"/>

    </commands>

     

    Ganz wichtig: dies muss im Ribbon XML File ganz zu Beginn, also noch vor der Ribbon-Deklaration stehen.

    Natürlich haben wir auch hier im Callback Handler das von anderen Methoden bekannte CancelDefault Flag, mit dem die originale Aktion deaktiviert werden kann.

     

    public void MySave(Office.IRibbonControl control, out bool CancelDefault)

    {

      MessageBox.Show("My new Save Function");

      CancelDefault = true;

    }

     

    Normalerweise würden Sie jetzt in Anhängigkeit vom Programmfluß oder den Aktionen, die der Benutzer schon durchgeführt hat, die Verfügbarkeit bestimmter Befehle steuern. Hier im Beispiel soll es anhand eines ToggleButtons geschehen:

     

    <group id="DisableFunktions" label="Disable Functionality">

      <toggleButton id="btnEnableButton"

                    size="large"

                    getImage="getEDFImage"

                    getLabel="getLabel"

                    onAction="OnToggleAvailability"/>

    </group>

     

    Hier wird gleich noch gezeigt, wie Sie zur Laufzeit das Aussehen des Buttons selbst verändern, sprich ihm wird ein neuer Titel und ein neues Icon zugewiesen (getLabel bzw. getImage Callback). Auf dem Flag ButtonsEnabled wird der Status gespeichert, getEnabled liefert diesen einfach zurück. Im Callback Handler des Buttons OnToggleAvailability schalten wir die Verfügbarkeit ein oder aus. Ribbon.Invalidate() zeichnet das UserInterface der Hostanwendung neu. Wenn Sie nur ein oder wenige Controls neu zeichnen müssen, so können Sie auch InvalidateControl(ControlID) aufrufen.

     

    private bool ButtonsEnabled = true;

     

    public bool getEnabled(Office.IRibbonControl control)

    {

      return ButtonsEnabled;

    }

     

    public void OnToggleAvailability(Office.IRibbonControl control, bool pressed)

    {

      ButtonsEnabled = !pressed;

      this.ribbon.Invalidate();

    }

     

    public string getLabel(Office.IRibbonControl control)

    {

      if (ButtonsEnabled)

        return "Disable Save";

      else

        return "Enable Save";

    }

     

    public stdole.IPictureDisp getEDFImage(Office.IRibbonControl control)

    {

      if (ButtonsEnabled)

        return ImageConverter.IconToPictureDisp(Properties.Resources.Disable);

      else

        return ImageConverter.IconToPictureDisp(Properties.Resources.Enable);

    }

     

    Starten wir das Projekt direkt aus Visual Studio heraus – hatte ich schon erwähnt, dass wir auch hier wie gewohnt BreakPoints setzen und debuggen können? – wird der Office Client gestartet und unser Add-In geladen. Es sollte der Tab MyTab sichtbar sein und durch einen Klick darauf bekommen wir unser Ribbon Tab zu sehen. Deaktivieren wir den Speichern-Befehl über unseren Button „Disable Save“, so sehen wir, dass wirklich sowohl im Menü als auch in der Quick Access Toolbar Speichern nicht mehr möglich ist. In Word und Powerpoint wird ebenfalls [Ctrl]+[s] abgefangen, in Excel leider zum derzeitigen Stand nicht.

     

     

    Weg mit allem, ich mach’s selbst

     

    Besonders Excel wurde von Entwicklern nicht selten derart umgestaltet, dass auf den ersten Blick nicht mehr zu erkennen war, das es sich um Microsoft Excel handelt. Es wurden Menüs und Toolbars entfernt und durch eigene ersetzt. Selbst Tastaturkürzel wurden entfernt, so dass nichts mehr auf Excel hinwies bis auf die eigentliche Tabelle. Die Idee, Excel’s eingebaute Funktionalität zu verwenden und ein neues Outfit darum herum zu bauen., ist also nicht so neu. Doch wie viel Aufwand bedeutete es, das alles zu verstecken?

    Office 2007 und speziell IRibbonExtensibility kennt Ribbon Attribut StartFromScratch. Setzen wir dieses auf true, so verschwindet magischerweise die inzwischen vertraute Benutzeroberfläche. Was bleibt ist das, was wir selbst erzeugt haben. Excel’s Ribbon und Quick Access Bar sind leer und das Office Menü wurde auf die Basiseinträge reduziert.

     

     

    Deployment

     

    Echtes ClickOnce Deployment gibt es ab dieser Version von Visual Studio Tools für Office. Wir nutzen also den ClickOnce Download Cache und nicht mehr den des Internet Explorers, um die Updates lokal zu speichern. Apropos Updates: die kann der Administrator zentral bereit stellen - die Clients holen sie sich, wenn sie gebraucht werden.

    Natürlich kann auch der Windows Installer (MSI) für die Installation genutzt werden. Bei Add-In-Projekten wird automatisch ein MSI-Projekt hinzugefügt und alle erforderlichen Registry-Einträge für die COM-Add-In-Registrierung gesetzt. Verteilt werden müssen aber noch zwei Dinge:

     

    ·         Die VSTO Runtime

    ·         Die Office Primary Interop Assemblies (PIA)

     

    Da wir mit .NET arbeiten, müssen wir uns auch um Security kümmern, genauer gesagt um Code Access Security (CAS). Diese sorgt dafür, dass nicht jede Software tun kann, was ihr so gefällt. Mittels CAS kann der Administrator ein Vertrauensverhältnis zu einer bestimmten Software festlegen. Das basiert entweder auf der Herkunft der Software (von welchem Pfad wurde sie geladen) oder auf inhaltlichen Beweisen, wie z.B. eine digitale Signatur. Der Administrator richtet also einen sog. Trusted Publisher (Vertrauter Herausgeber) ein und jeder Software, die mit dem Zertifikat signiert wurde, wird automatisch vertraut. Ich muss nicht erwähnen, das alle andere Software auf .NET Basis keinerlei Rechte besitzt. Für Office-Interoperability müssen wir das Vertrauensverhältnis auf FullTrust (wegen COM Interop) setzen.

    Fazit

     

    Wir könnten uns hier sicher noch eine Weile mit dem Thema beschäftigen. Office Integration ist inzwischen ein Thema so spannend wie .NET selbst. Während noch vor 3 Jahren kaum einer die Notwendigkeit einer Integration seiner Anwendung in Office gesehen hat, wird es meiner Meinung nach in 3 Jahren kaum noch Chancen geben, eine Anwendung ohne Office Integration zu verkaufen. Microsoft setzt mit Office 2007 und Visual Studio Tools für Office ganz klare Zeichen in Richtung LOB-Integration. In diese Richtung gehen auch Ansätze bzw. Lösungen wie IBF, Duet für SAP und Microsoft Office bzw. LOBi. Office 2007 ist  mehr als die Summe von Einzelprodukten. Es ist eine Plattform für Smarte Clients. Eine Plattform, die es leichter denn je macht, seinen Anwendern Funktionalität an Ort und Stelle zur Verfügung zu stellen.

     

  • Office Development is more than VBA

    2007 Microsoft Office System - RibbonExtensibility (Teil 1)

    • 8 Comments

    (Ein Update auf Basis VSTO 2005 SE) 

    Die Version 2007 von Microsoft Office macht Schluss mit einem über Jahre hinweg gehegten und gepflegten Stiefkind der Softwareentwicklung: Menüs. Was anfangs noch neue Möglichkeiten suggerierte, geriet schnell zum Albtraum von Ottonormalbenutzer. Überfrachtete Menüstrukturen mit hunderten von Befehlen laden zum Suchen ein. Oftmals wünschen sich Anwender bei den Softwarefirmen Funktionen, die es schon lange gibt. Nur weil diese nicht zu finden sind in mehrfach geschachtelten Untermenüs oder Dialogen. Menüs waren gestern, heute gibt es Ribbons.

    Diese Ribbons, auch Multifunktionsleisten genannt, sind nicht von irgendwoher gekommen, sondern das Produkt  langer und ausführlicher Tests in den Microsoft Usibility Labs. Da sitzen nicht etwa Mitarbeiter von Microsoft, sondern eben jene Ottonormalbenutzer vom Büro nebenan und testen die geistigen Auswüchse findiger Köpfe. Intuitive Benutzerführung, Funktionen schneller finden und natürliches Suchen sind grundlegende Ideen, die dahinter stecken. Und zugegeben, nach etwas Eingewöhnungszeit findet man sich ganz gut zurecht. Natürlich sind wir seit Jahren auf Menüs geeicht worden und wer bestimmte, immer wieder benutzte Programme, wie seine sprichwörtliche Westentasche kennt, wird sicherlich eine gewisse Umgewöhnungsphase einplanen müssen. Auch bekommen nicht alle zehn Microsoft Office Client Programme (ja, es sind zehn, von Access bis Visio) sofort die neue Oberfläche. Vorerst sind diese Ribbons den Programmen Word, Excel, Powerpoint und Outlook vorbehalten, wobei letzteres eine hybride Zwischenstellung einnimmt, da die Shell weiterhin Menüs hat, während ein Inspector Window (Nachrichten, Aufgaben, Kontakte, etc. werden in einem Inspektor-Fenster geöffnet)  diese neue Multifunktionsleiste bekommt.

     

     

    Was haben Entwickler davon?

     

    Während noch vor 3 Jahren fast ausschließlich VBA-Programmierer Lösungen für Office angeboten haben – allenfalls wurde OLE Automation von „richtigen Programmierern“ (pfui, welche Anmaßung) verwendet – wird heute der Ruf nach einer Office Integration immer lauter. Ist ja auch verständlich, will doch der produktive Anwender , welcher fast sein gesamtes (Büro-) Leben in Outlook, Word bzw. Excel zubringt, diese nicht verlassen, um businessrelevante Daten aus verborgenen Datensilos zu holen. Ganz zu schweigen von den Schulungskosten, die anfallen, um Ottonormalbenutzer für die verschiedenen Clients der ERP-, CRM- oder sonstwelcher Systeme fit zu machen. Von einigen Power Usern einmal abgesehen wird i.d.R. weniger als 10% der von solchen Spezialanwendungen zur Verfügung gestellten Funktionalität genutzt. Warum also nicht die am meisten genutzen Bestandteile dorthin bringen, wo sie am meisten gebraucht werden – in Büroanwendungen wie Microsoft Office.

    Nun wird der gemeine VB.NET oder C# - Programmierer nicht unbedingt sein gewohntes Visual Studio verlassen wollen, um dann auch noch eine andere Sprache (VBA, igitt) programmieren zu müssen. Visual Studio geht ja schon seit einiger Zeit den Weg „One Tool for Everything“ und erlaubt es, ASP.NET-Projekte, Projekte für Desktop- und Server-Anwendungen, aber auch für mobile Geräte oder Gerätetreiber unter einem Dach zu entwickeln. Auch Office-Anwendungen bilden da keine Ausnahme. Mit Visual Studio Tools für Office (VSTO) hat Microsoft eine Möglichkeit geschaffen, Projekte in Visual Studio für Microsoft Office zu entwickeln, debuggen und testen. Die für diesen Artikel zugrunde liegende Version von VSTO 2005 SE arbeitet mit Visual Studio 2005 und Office 2007 (sowie Office 2003) und integriert sich nahtlos in die IDE  der Microsoft Entwicklungsumgebung. 

     

     

     

    Um Ribbons erweitern zu können, muss ein von den Office Clients bereitgestelltes COM Interface (ja, Office 2007 ist immer noch COM Technologie) – nämlich IRibbonExtensibility – bedient werden. Es wird nur eine Funktion zur Verfügung gestellt: GetCustomUI(string), welche die Beschreibung der Ribbon-Erweiterung – natürlich in Form von XML Markup - entgegen nimmt. Es gibt nun mehrere Wege, der Office-Anwendung die eigene Ribbon-Beschreibung zu übergeben:

    1.     Die XML-Datei in einem Ordner CustomUI innerhalb der Office-Datei (Office Open XML File Format vorausgesetzt). Dies erfordert das Eintragen von Content Types und Relationships ebenfalls innerhalb der Office-Datei. Der Code, der ausgeführt werden soll, liegt dann in VBA vor.

    2.     Per COM Add-In, geschrieben in C++, VB6, o.ä.

    3.     Per Shared Add-In, geschrieben in einer .NET Sprache

    4.     Über ein VSTO Add-In, geschrieben in C# oder VB.NET

     

    VBA und native COM Add-Ins wollen wir hier nicht behandeln und Shared Add-Ins haben ein paar Nachteile, die VSTO Add-Ins nicht haben. Sie laufen nicht, wenn die Office Macro Security auf Stufe „hoch“ gesetzt wurde, da es keine digital signierte Shim (Proxy, welcher die .NET Runtime hostet und das Add-In ausführt) gibt. Außerdem werden alle Shared Add-Ins in dieselbe Application Domain geladen, was dazu führt, dass alle Add-Ins in Mitleidenschaft gezogen werden, wenn eines fehlerhaft ist. VSTO bringt einen AddInLoader, der die Aufgabe der o.g. Shim übernimmt, selbst signiert ist und ebenfalls die Code Access Security (CAS) Anforderungen des Add-Ins überprüft und mit CAS Policies der lokalen Maschine vergleicht. Des Weiteren werden klare Schnittstellen, die Events Startup und Shutdown angeboten. Shared Add-Ins bieten OnConnection, OnDisconnection, OnAddInsUpdate, OnStartupComplete und OnBeginShutdown an und es ist nicht sofort klar, was wann verwendet werden muss.

    Ribbons mit Visual Studio Tools für Office entwickeln

     

    Zuerst einmal muss sich der Leser über ein paar Begriffe klar werden, die im Zusammenhang mit Ribbons immer wieder auftauchen. Ein Ribbon ist im Prinzip eine Kombination aus Tabbed Dialog Control und Toolbar. Ein Ribbon enthält ein bis mehrere Tabs und diese wiederum Groups. In den Gruppen werden Controls platziert, die wiederum zu sog. Control Groups zusammengefasst werden können.

     

     

     

    In Visual Studio legen wir dazu einfach ein neues Projekt an und nutzen eine der von VSTO gelieferten Projektvorlagen für Add-Ins für die Programme Word, Excel, Powerpoint oder Outlook. Welche Programmiersprache Sie verwenden, ist Ihnen überlassen. Zur Verfügung stehen Visual Basic .NET und C#. Danach fügen wir über Rechtsklick auf den Projektnamen im Projektmappen-Explorer (Hinzufügen | Neues Element) den Ribbon Support ein. Hinzugefügt wird sowohl ein Ribbon XML File (Ribbon1.xml) als auch das dazugehörige Code Modul (Ribbon1.cs bzw. Ribbon1.vb). Öffnen wir also Ribbon1.xml und wir sehen den Prototyp eines Ribbons an. Er enthält einen Tab und eine Gruppe, die ein Control, nämlich einen ToggleButton enthält. Das Projekt ist sofort lauffähig, Wir können es also gleich starten. Freilich ist das Beispiel sehr spartanisch.

    Wenn wir die Möglichkeiten, die uns Ribbons zur Verfügung stellen, mit denen von älteren Office-Versionen vergleichen, fällt auf, dass da einiges Hinzugekommen ist.

    Folgende Controls stehen zur Verfügung:

    ·         button

    ·         checkBox

    ·         comboBox

    ·         dropDown

    ·         dynamicMenu

    ·         editBox

    ·         gallery

    ·         labelControl

    ·         menu

    ·         splitButton (Kombination aus Button und Menu)

    ·         toggleButton

     

    Desweiteren können folgende Elemente verwendet werden:

    ·         box (Horizontaler Gruppierungscontainer)

    ·         buttonGroup (Element zum Gruppieren von Buttons innerhalb einer Gruppe)

    ·         control (Element zum Steuern eingebauter Controls)

    ·         command (Element zum Steuern eingebauter Befehle)

    ·         group (Eine Gruppe innerhalb eines Tabs)

    ·         separator (Vertikaler Separator)

    ·         tab (Ein Reiter eines Ribbons)

     

    Da Visual Studio 2005 bzw. VSTO 2005 SE noch keine Syntaxunterstützung bieten, fällt die Erweiterung ein wenig schwer. Aber das zugrundeliegende XML Schema bringt Abhilfe. Kopieren Sie die Datei CustomUI.xsd aus dem Ordner (VSTO muß vorher installiert sein)

       \program files\microsoft visual studio 8\Xml\Schemas\1033\CustomUI.xsd

    nach

       \program files\microsoft visual studio 8\Xml\Schemas\

    Wenn wir jetzt Änderungen in Ribbon1.xml machen, haben wir IntelliSense!

     

    Doch schauen wir uns erst einmal das folgende Listing an.

     

    <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad">

     

      <ribbon startFromScratch="false">

        <tabs>

          <tab id="MyTab" label="My Tab">

     

            <group id="MiscGroup" label="Misc Group">

              <splitButton id="mySplit" size="large">

                <button id="btnSplitMain" label="Surf the Net" description="Surfin' USA"

                        imageMso="OutlookGlobe" onAction="OnSplitButton"/>

                <menu id="splitMenu" itemSize="large">

                  <button id="btnSplitMenu1" label="Smile" description="Be Happy"

                          screentip="Happy People live longer"

                          imageMso="HappyFace" 

                          onAction="OnActionDefault" />

                  <button id="btnSplitMenu2" label="Paint" description="Paint it black"

                          screentip="The famous song by the Rolling Stones"

                          imageMso="FormatPainter" 

                          onAction="OnActionDefault" />

                  <button id="btnSplitMenu3" label="Filter" description="Filter Inbox"

                          screentip="Apply the Filter and find what you are looking for"

                          imageMso="Filter"

                          onAction="OnActionDefault" />

                </menu>

              </splitButton>

            </group>

          </tab>

        </tabs>

      </ribbon>

    </customUI>

     

    Gleich in der ersten Zeile finden wir unsere CustomUI Schema Definition wieder. Danach die Verknüpfung mit dem OnLoad Callback. Überfliegen wir das Markup, sehen wir sofort, dass jedes Element einen Identifikator (id) besitzt, der im gesamten Ribbon XML eindeutig sein muss. Die weitere Spezifizierung von Elementen wird also über XML Attribute erledigt. Wir deklarieren unsere Oberfläche. Das Attribut label beispielsweise setzt den zum Control gehörenden Text, onAction den Callback für den Click Event und imageMso das zu verwendende Icon. Übrigens, wenn ein Attribut auf „Mso“ endet, so heißt das, dass eingebaute Funktionalität verwendet wird. So verweist imageMso auf ein in der Office Bibliothek vorhandenes Icon und idMso auf ein vorhandenes Element. Aber dazu später. Die Icons von Office werden jetzt per Namen referenziert und nicht mehr über eine numerische ID, die sich keiner merken konnte.

     

    Über das onAction Attribut haben wir in den callback Handler für die Click Events festgelegt. Doch wie muss dieser aussehen? Welche Signatur muss er haben, damit es funktioniert? Eine Auflistung der verfügbaren Callback Handler finden Sie hier (unter: Table 3. List of all C#, VBA, C++, and Visual Basic callbacks and signatures). Und so könnte der Callback unseres SplitButtons aussehen:

     

    public void OnSplitButton(Office.IRibbonControl control)

    {

      switch (control.Id)

      {

        case "btnSplitMain":

          MessageBox.Show("Surf");

          break;

        case "btnSplitMenu1":

          MessageBox.Show("Smile");

          break;

        case "btnSplitMenu2":

          MessageBox.Show("Paint");

          break;

        case "btnSplitMenu3":

          MessageBox.Show("Filter");

          break;

        default:

          MessageBox.Show("Not implemented yet");

          break;

      }

    }

     

    Es handelt sich um einen Callback, da wir ja mit einer COM Applikation kommunizieren müssen. Die Verdrahtung erfolgt im Hintergrund und wird dank VSTO von uns fern gehalten. Wenn wir genauer hinschauen, werden wir sehen, dass unsere Ribbon Klasse das Microsoft.Office.Core.IRibbonExtensibility Interface implementiert und ServiceRequest und andere Helper Methoden im Hintergrund werkeln.

    Was passiert nun genau, wenn ein Add-In mit einer Ribbon-Erweiterung geladen wird?

     

    1.     Office lädt das Add-In

    2.     Office überprüft das Add-In daraufhin, ob IRibbonExtensibility implementiert wurde

    3.     Das Add-In gibt Office eine Referenz auf das Objekt, das IRibbonExtensibility implementiert

    4.     Später ruft Office auf diesem Interface zurück (GetCustomUI) und holt das Ribbon XML

    5.     Office parst das XML und erzeugt Tabs, Groups und Controls
    (Diese Controls sind unmanaged und in Office. Wir haben keinen direkten Einfluss darauf)

    6.     IRibbonExtensibility ist ein Dispatch Interface, es können beliebig viele Callbacks implementiert werden

    7.     Bei Benutzerinteraktion mit diesen Controls ruft Office auf dem IRibbonExtensibility Objekt zurück und ruft den Callback Handler auf (IDispatch::Invoke)

    Dynamische Inhalte für Ribbon Elemente

     

    Während das erste Beispiel nur ein statisches Ribbon Element enthielt, wollen wir jetzt etwas dynamischer werden. Der folgende XML Code  erzeugt eine neue Gruppe und darin eine Gallery, welche erst zur Laufzeit mit Informationen bzw. Daten gefüttert wird.

     

    <group id="GalleryGroup" label="Group with Galleries" visible="true">

      <gallery id="IconGallery"

               label="IconGallery"

               columns="3"

               rows="4"

               size="large"

               getImage="getImage"

               getItemImage="getItemImage"

               getItemCount="getItemCount"

               getItemLabel="getItemLabel"

               getItemSupertip="getItemSupertip"

               itemHeight="100" itemWidth="100"

               onAction="OnIconGalleryAction">

      </gallery>

    </group>

     

    Galleries sind neue Oberflächenelemente in Office 2007, die eine visuelle Repräsentation des zu erwartenden Ergebnisses – eine Art statische Vorschau – bieten können. Abbildung 4 zeigt ein Beispiel aus Powerpoint 2007.

     

     

     

    Galleries können auch einfach nur eine mehrspaltige Liste von Fotos anzeigen. Genau das soll im folgenden Beispiel gemacht werden. Zum dynamischen Befüllen von Galleries benötigen wir mehrere Callback Handler.

     

    ·         getImage liefert das Icon des Gallery Buttons

    ·         getItemCount liefert die Anzahl der Gallery Items

    ·         getItemImage liefert die einzelnen Bilder der Gallery Items

    ·         getItemLabel liefert den Anzeigetext zu den Items

    ·         getItemSupertip liefert den Text für den erweiterten Tooltip

    ·         itemHeight bzw. itemWidth liefern Höhe und Breite der Bilder

    ·         onAction verknüpft den Click Event

     

    Wir wollen Bilder, die entweder als Ressource im Add-In vorliegen oder aus einer Datenbank zur Laufzeit geholt werden, für unsere Gallery verwenden. Dafür müssen wir eine Datenbankverbindung aufmachen, ein DataSet bzw. DataTable erzeugen und diese füllen. Das sind Standard-Aufgaben, auf die hier nicht eingegangen werden soll.

     

    Jetzt können wir daran gehen, die Callback Handler zu verdrahten. Wenn wir uns aber die Signatur von getImage ansehen, haben wir ein kleines Problem.

     

    public stdole.IPictureDisp getImage(Office.IRibbonControl control)

     

    Office möchte gerne ein COM Objekt zurück haben, welches das IPictureDisp Interface implementiert, um darüber Eigenschaften des Bildes ermitteln zu können. Unter .NET kennen wir den Typ Image. Wie können wir hier dem Wunsch von Office nachkommen? Glücklicherweise gibt es eine Klasse System.Windows.Forms.AxHost und darin eine Funktion, die wir gebrauchen können: GetIPictureDispFromPicture. Da dies eine Virtual Function ist, benötigen wir eine eigene Klasse, die von AxHost ableitet.

     

    internal class ImageConverter : System.Windows.Forms.AxHost

    {

      public ImageConverter() : base(string.Empty) {}

     

      static public stdole.IPictureDisp ImageToPictureDisp(Image image)

      {

        return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);

      }

     

      static public stdole.IPictureDisp IconToPictureDisp(Icon icon)

      {

        return ImageToPictureDisp(icon.ToBitmap());

      }

    }

     

    Ehrlich gesagt, ich hoffe stark, dass diese Konvertierungsklasse in VSTO 3 (ORCAS) nicht mehr erforderlich sein wird. Zum heutigen Zeitpunkt allerdings müssen wir uns um die Konvertierung selbst kümmern. Des Weiteren wird uns auch noch viel Arbeit beim Design von Ribbons abgenommen werden, wenn dort ebenfalls Ribbon Designer zu VSTO hinzukommen.

     

    Die implementierten Callback Handler für die dynamische Gallery sehen dann folgendermaßen aus:

     

    public stdole.IPictureDisp getImage(Office.IRibbonControl control)

    {

      switch (control.Id)

      {

        case "IconGallery":

          return ImageConverter.ImageToPictureDisp(Properties.Resources.Office);

        default:

          return ImageConverter.IconToPictureDisp(Properties.Resources.NoPhoto);

      }

    }

     

    public int getItemCount(Office.IRibbonControl control)

    {

      return vistaIconsTable.Rows.Count;

    }

     

    public string getItemLabel(Office.IRibbonControl control, int index)

    {

      return vistaIconsTable.FindByID(index + 1).ProgramName;

    }

     

    public string getItemSupertip(Office.IRibbonControl control, int index)

    {

      return vistaIconsTable.FindByID(index + 1).Description;

    }

     

    public stdole.IPictureDisp getItemImage(Office.IRibbonControl control, int index)

    {

      MemoryStream iconStream = new MemoryStream(vistaIconsTable.FindByID(index + 1).IconPic);

      return ImageConverter.ImageToPictureDisp(Image.FromStream(iconStream));

    }

     

    public void OnIconGalleryAction(Office.IRibbonControl control, string selectedId, int selectedIndex)

    {

    }

     

     

     (Fortsetzung in Teil 2)

     

  • Office Development is more than VBA

    Die DPE Brothers

    • 0 Comments

    Daß die Arbeit bei Microsoft Spaß macht und die Kollegen auch noch cool (okay, ober-cool) sind, beweist das geheim mitgeschnittene Video von der letzten Probe vor dem Auftritt auf der MS XMas Party:


    Video: Brotherhood of DPE
  • Office Development is more than VBA

    Office Open XML Format: Package Explorer 2.0 verfügbar

    • 0 Comments

    Mit dem Package Explorer in Version 2.0 können nicht nur Dateien im neuen Dateiformat von Office 2007 betrachtet werden, sondern es können (noch nicht überall) Änderungen an Document Parts vorgenommen und das Paket gegen die von der ECMA standardisierten Specs validiert werden.

    http://www.codeplex.com/PackageExplorer

     

  • Office Development is more than VBA

    Lokalisierte Versionen von VSTO 2005 SE verfügbar

    • 0 Comments

    Seit heute sind verschiedenen Sprachversionen von Visual Studio Tools für Office 2005 SE verfügbar. Damit können Sie auch mit dem deutschen Visual Studio 2005 gegen Office 2003 und 2007 entwickeln: 

    Deutsche Version von VSTO 2005 SE

    Tip: Office 2007 sollte nicht auf der gleichen Maschine wie Office 2003 installiert werden.

     

  • Office Development is more than VBA

    Office 2007 Opens Up for Eager ISVs

    • 0 Comments

    Award-winning magazine writer and former editor in chief of Software Development, Alexandra Weber Morales, writes about the value of 2007 Office System for ISVs:

    http://www.devx.com/MicrosoftISV/Article/33289

     

  • Office Development is more than VBA

    Intellisense für RibbonXML in VSTO-Projekten

    • 0 Comments

    Ich hatte schon in einem früheren Blog-Eintrag beschrieben, daß man durch das Einbinden des den Ribbons zugrunde liegenden Schemas customUI.xsd Visual Studio 2005 mit Intellisense versehen kann. Es geht noch einfacher: Kopieren Sie die Datei CustomUI.xsd aus dem Ordner

    \program files\microsoft visual studio 8\Xml\Schemas\1033\CustomUI.xsd

    nach 

    \program files\microsoft visual studio 8\Xml\Schemas\

    Damit muß nicht für jedes Projekt das Schemafile separat hinzugefügt zu werden. Natürlich muß VSTO 2005 SE installiert sein.

     

  • Office Development is more than VBA

    Microsoft Office Open XML Format ist ECMA Standard 376

    • 1 Comments

    Der erste Schritt ist geschafft. Das Office Open XML Format wurde von der ECMA als Standard anerkannt. Jetzt geht's zur ISO.

    ECMA White Paper (PDF-Format) 

    Details dazu finden Sie hier. Es gab nur eine Gegenstimme, die von IBM. Natürlich wird das wieder kontroverse und leidenschaftliche Diskussionen auslösen. Einen Vorgeschmack bietet der Blog von Bob Sutor (IBM), speziell die Kommentare des Blogeintrags sind lesenswert.

     

  • Office Development is more than VBA

    Ressourcen von der Launch Tour

    • 1 Comments

    Ich hatte versprochen, die Ressourcen für meine beiden Vorträge auf der Office, Vista und Exchange Launch Tour hier verfügbar zu machen. Hier sind sie:

    RibbonExtensibility:

     

    Download Office 2007 RTM Control ID List (Excel 97-2003 Format)

    http://officeblogs.net/UI/RibbonX-ControlIDs-xlsFormat.zip

     

    Download Office 2007 RTM Control ID List (Excel 2007 Format)

    http://officeblogs.net/UI/RibbonX-ControlIDs.zip

     

    Download List of Control ID List Changes between B2TR and RTM

    http://officeblogs.net/UI/RTMUpdates.zip

     

    Download Office 2007 RTM customUI Schema

    http://officeblogs.net/UI/customUI.zip

     

    2007 Office System Document: Lists of Control IDs

    http://www.microsoft.com/downloads/details.aspx?familyid=4329D9E9-4D11-46A5-898D-23E4F331E9AE

     

    Office 2007 Icons Gallery

    http://www.microsoft.com/downloads/details.aspx?familyid=12b99325-93e8-4ed4-8385-74d0f7661318&displaylang=en 

     

    RibbonX Schema Definition File

    http://officeblogs.net/ui/customUI.zip

     

    RibbonX Callback Handlers (unter: Table 3. List of all C#, VBA, C++, and Visual Basic callbacks and signatures)

    http://msdn2.microsoft.com/en-us/library/aa722523.aspx

      

    Customizing the Office (2007) Ribbon User Interface for Developers (Part 1 of 3)

    http://msdn2.microsoft.com/en-us/library/aa338202.aspx

     

    Customizing the Office (2007) Ribbon User Interface for Developers (Part 2 of 3)

    http://msdn2.microsoft.com/en-us/library/aa338199.aspx

     

    Customizing the Office (2007) Ribbon User Interface for Developers (Part 3 of 3)

    http://msdn2.microsoft.com/en-us/library/aa722523.aspx

     

    Developer Overview of the User Interface for the 2007 Microsoft Office System

    http://msdn2.microsoft.com/en-us/library/aa338198.aspx

     

    Customizing the Office (2007) Document Inspector

    http://msdn2.microsoft.com/en-us/library/aa338203.aspx

     

    The Office 2007 UI Bible

    http://blogs.msdn.com/jensenh/archive/2006/11/10/the-office-2007-ui-bible.aspx 

     

     

    Office Open XML File Format:

     

    http://OpenXMLDeveloper.org 

     

    Erzeugen eines Word Dokuments
    http://blogs.msdn.com/dmahugh/archive/2006/06/27/649007.aspx

     

    Erzeugen eines Excel Dokuments
    http://blogs.msdn.com/dmahugh/archive/2006/07/15/CreateXlsx.aspx

     

    Package Explorer
    http://openxmldeveloper.org/articles/261.aspx

     

    Introducing the Office (2007) Open XML File Formats

    http://msdn2.microsoft.com/en-us/library/aa338205.aspx

     

    Extending the Office (2007) Fixed-Format Export Feature

    http://msdn2.microsoft.com/en-us/library/aa338206.aspx

     

    Ecma Office Open XML File Formats Standard

    http://www.ecma-international.org/news/TC45_current_work/TC45_available_docs.htm

     

    Brian Jones: Open XML Formats

    http://blogs.msdn.com/brian_jones/

     

    MSDN Articles on Open XML and Related Topics

    http://openxmldeveloper.org/archive/2006/08/31/599.aspx

     

     

    Visual Studio Tools für Office (VSTO):

     

    Creating Custom Task Panes Using Visual Studio Tools for Office

    http://msdn2.microsoft.com/en-us/library/aa722570.aspx

     

    Migrating a Shared Add-in to a Visual Studio Tools for Office Add-In

    http://msdn2.microsoft.com/en-us/library/aa663367.aspx

     

    Migrating a VBA Solution to a Visual Studio Tools for Office Add-In

    http://msdn2.microsoft.com/en-us/library/aa830702.aspx

     

     

    Outlook:

     

    What's New for Developers in Microsoft Office Outlook 2007 (Part 1 of 2)

    http://msdn2.microsoft.com/en-us/library/ms772422.aspx

     

    What's New for Developers in Microsoft Office Outlook 2007 (Part 2 of 2)

    http://msdn2.microsoft.com/en-us/library/ms772423.aspx

     

     

    Allgemein:

     

    The Future of Office Developer Home

    http://www.microsoft.com/office/preview/developers/default.mspx

     

    Good Blogs:

    http://blogs.msdn.com/brian_jones/default.aspx  

    http://blogs.msdn.com/eric_carter/default.aspx 

    http://blogs.msdn.com/mshneer/default.aspx 

    http://blogs.msdn.com/johnrdurant/default.aspx 

    http://blogs.msdn.com/vsto2

    http://www.officezealot.com/vsto

     

    Das ist sicherlich noch nicht alles, aber ein guter Start. Wenn etwas mehr Zeit zur Verfügung steht, werde ich die Beispiele der Roadshow aufbereiten und hier ebenfalls zur Verfügung stellen.

     

     

Page 1 of 1 (11 items)