Thursday 11 November 2010

Word 2007 Fluent Ribbon Addin

I recently came across an interesting issue when our Office was recently upgraded from 2003 to 2007. Previously the company Word templates (.dot) were loaded into the menu system for easy selection. With 2007 this has been replaced with the Fluent Ribbon.

It should have been easy to find examples of transferring these macro based functions to the new ribbon. However, the articles were mainly based on the XML with very little written to help with a C# solution.

Here is how I solved some of the issues in using the Visual Studio tools.

First, open a new project.

 This creates a soulution with a C# file called "ThisAddIn".
We now add a new Ribbon using Visual Designer and NOT the XML.
 
Now we can get to the code as we would with any other Winform or Webform application.

The visual design mode allows us to remove the existing tab, which would show as the "Add In" tab in Office and replace with our own Custom Tab.  We add two groups, one for the list of templates using the Menu, and the second for a print button and insert footer function.  All the icons are part of the Office Gallaery, a list of which can be downloaded here.



Next we add the code to load the templates.  These can be anywhere on the system, including a share, but for this demo I am using the standard templates in C:\Program Files\Microsoft Office\Templates\1033.

I am using a recusive method to loop the folders and sub folders to build the list.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Word =  Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using System.IO;
using System.Windows.Forms;

namespace CustomRibbon
{
    public partial class CustomRibbon : OfficeRibbon
    {
        public CustomRibbon()
        {
            InitializeComponent();
        }

        private void CustomRibbon_Load(object sender, RibbonUIEventArgs e)
        {
            LoadDirectories();
        }


    private int count = 0;

    #region Template Loader

    private void LoadDirectories()
    {
      tpltMenu.Dynamic = true;
      RibbonMenu m = new Microsoft.Office.Tools.Ribbon.RibbonMenu(); // For VS 2010 Use this.Factory.CreateRibbonMenu();
      DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(@"C:\Program Files\Microsoft Office\Templates\1033"));
      foreach (DirectoryInfo d in di.GetDirectories())
      {
          RibbonMenu subM = new Microsoft.Office.Tools.Ribbon.RibbonMenu(); // For VS2010 use this.Factory.CreateRibbonMenu();
          BuildFolders(d, ref tpltMenu, subM);
      }
    }

    private void BuildFolders(DirectoryInfo di,ref RibbonMenu parentM , RibbonMenu m)
    {
      count++;
      try
      {

        //if (di.Name != "1033")
        //{
          m.Dynamic = true;
          m.Name = "dir" + count;
          m.Label = di.Name;
          m.ShowLabel = true;

          foreach (DirectoryInfo d in di.GetDirectories())
          {
              RibbonMenu subM = new Microsoft.Office.Tools.Ribbon.RibbonMenu();
              BuildFolders(d, ref m, subM);
          }


          FileInfo[] files = di.GetFiles();
          foreach (FileInfo f in files)
          {
              if (f.Name.ToLower().EndsWith(".dot") || f.Name.ToLower().EndsWith(".dotx"))
              {
                  count++;
                  string FileName = f.Name.Trim();
                  FileName = FileName.Replace(".Dotx", "");

                  RibbonButton b = new Microsoft.Office.Tools.Ribbon.RibbonButton();
                  b.Name = "cmd" + count;
                  b.Label = FileName;

                  b.SuperTip = f.FullName;
                  b.Click += new EventHandler(button1_Click); // For VS 2010 use Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.button1_Click);
                  m.Items.Add(b);
              }
          }
          parentM.Items.Add(m);
       // }
      }
      catch (UnauthorizedAccessException e){}
      catch { }
    }


    private void button1_Click(object sender, RibbonControlEventArgs e)
    {
      RibbonButton btn = (RibbonButton)sender;
      object nullobj = System.Reflection.Missing.Value;
      Object oTemplatePath = btn.SuperTip;
      Object SaveOption = Word.WdSaveOptions.wdDoNotSaveChanges;
      Word._Application wordApp = new Word.Application();
      Word.Document doc = new Word.Document();
      wordApp.Documents.Add(ref oTemplatePath, ref nullobj, ref nullobj, ref nullobj);
      wordApp.Visible = true;
      doc = wordApp.Documents.Add(ref oTemplatePath, ref nullobj, ref nullobj, ref nullobj);
    }
    #endregion



    private void cmdPrintX2_Click(object sender, RibbonControlEventArgs e)
    {

      object nullobj = System.Reflection.Missing.Value;
      object copies = "1";
      object pages = "1";
      object range = Word.WdPrintOutRange.wdPrintAllDocument;
      object items = Word.WdPrintOutItem.wdPrintDocumentContent;
      object pageType = Word.WdPrintOutPages.wdPrintAllPages;
      object oTrue = true;
      object oFalse = false;

      Word.Application applicationObj = Globals.ThisAddIn.Application;
      string CurrentPrinter = applicationObj.ActivePrinter;
      applicationObj.ActivePrinter = @"\\SERVER\PRINTER";

      Word.WdPaperTray wdHeaded = (Word.WdPaperTray)260; //Different for other printers
      Word.WdPaperTray wdAllPages = (Word.WdPaperTray)261;//Different for other printers

      Word.Document document = applicationObj.ActiveDocument;
      document.PageSetup.FirstPageTray = wdHeaded;
      document.PageSetup.OtherPagesTray = wdAllPages;

      try
      {
        document.PrintOut(
            ref oTrue, ref oFalse, ref nullobj, ref nullobj, ref nullobj, ref nullobj,
            ref items, ref copies, ref pages, ref pageType, ref oFalse, ref oTrue,
            ref nullobj, ref oFalse, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }

     //Return back to Original Printer
      applicationObj.ActivePrinter = CurrentPrinter;
    }

    private void cmdInsertFooter_Click(object sender, RibbonControlEventArgs e)
    {
      Word.Application applicationObj = Globals.ThisAddIn.Application;
      Word.Document doc = applicationObj.ActiveDocument;

      applicationObj.ActiveWindow.View.SeekView = Word.WdSeekView.wdSeekCurrentPageFooter;
      applicationObj.Selection.TypeParagraph();

      applicationObj.ActiveWindow.Selection.TypeText("\t");
      applicationObj.ActiveWindow.Selection.TypeText(doc.FullName);

      applicationObj.ActiveWindow.View.SeekView = Word.WdSeekView.wdSeekMainDocument;

    }
  }
}