<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Add-in Express Blog</title>
	<atom:link href="http://www.add-in-express.com/creating-addins-blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.add-in-express.com/creating-addins-blog</link>
	<description>All about developing COM add-ins, smart tags and RTD servers in Visual Studio .NET, VSTO and Delphi + Add-in Express</description>
	<pubDate>Tue, 13 May 2008 18:49:16 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>Handling NewMail, NewMailEx and ItemAdd Outlook events in .NET</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/04/25/newmail-itemadd-outlook-events/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/04/25/newmail-itemadd-outlook-events/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 19:44:43 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[MAPI]]></category>

		<category><![CDATA[Outlook]]></category>

		<guid isPermaLink="false">http://www.add-in-express.com/creating-addins-blog/?p=46</guid>
		<description><![CDATA[Sometimes you need to process incoming e-mails and meeting requests in order to retrieve sender data for your CRM, to save attachments to your Document Management System (DMS), to process automated e-mails, or to convert selected incoming messages to plain text. Whenever you need to track incoming e-mails, you face the following Outlook events: NewMail, NewMailEx, and ItemAdd. ]]></description>
			<content:encoded><![CDATA[<p>Sometimes you need to process incoming e-mails and meeting requests in order to retrieve sender data for your CRM, to save attachments to your Document Management System (DMS), to process automated e-mails, or to convert selected incoming messages to plain text. Whenever you need to track incoming e-mails, you face the following Outlook events: NewMail, NewMailEx, and ItemAdd. </p>
<p>In a minute I will tell you how to use these events, uncover their drawbacks, and show how to use the <a href="http://www.add-in-express.com/products/mapi-store-events.php">MAPI Store Accessor</a> to bypass negative sides of these events in .NET.</p>
<h3>NewMail</h3>
<p>Notwithstanding its name, this event fires at a few minute intervals. It ignores any incoming items which arrived shortly after a previous NewMail event. Another limitation makes the NewMail event almost useless – if more than 16 items arrive at once, the event will not fire at all!</p>
<h3>NewMailEx</h3>
<p>This event was introduced in Outlook 2003. It improves monitoring of incoming messages by providing access to EntryIDs of newly arrived e-mails. EntryIDs are separated with commas in a string parameter of the NewMailEx event. You can easily get any item using its EntryID: </p>
<pre><code class=vb>NameSpace.GetItemFromID(EntryID)</code></pre>
<p>Well, this method has restrictions of its own. Say, if more than 1000 items come at once, some of them may be missing. That is, you can&#8217;t rely on the NewMailEx event alone. You may want to regularly check for unprocessed messages, say by using a timer.</p>
<h3>ItemAdd</h3>
<p>You can also use the ItemAdd event of the Items collection of Outlook folder class (MAPIFolder in Outlook 2000-2007, Folder in Outlook 2007). This is especially useful when you need to check new mails in some other folder, say, another user&#8217;s Inbox. However, note that ItemAdd will not fire if more than 16 items are added at the same time. This restriction has the same root as that of the NewMail event. For instance, <a href="http://support.microsoft.com/kb/249156/">Microsoft writes</a> that &#8220;this is due to Microsoft Exchange Server and MAPI using different methods when moving large amounts of data. Outlook does not take this into account and therefore the event fails to fire in those cases.&#8221;. They also suggest periodically checking the number of items in the folder to see if there are new items.</p>
<h3>MAPI</h3>
<p>MAPI enables you to bridge the gap between Outlook events and developers’ demands. You can use our <a href="http://www.add-in-express.com/products/mapi-store-events.php">MAPI Store Accessor</a> which connects to the MAPI subsystem and subscribes to selected events at the MAPI level. As a result, you will get all needed notifications such as NewMail, ObjectModified, ObjectDeleted, etc. No restrictions of mentioned above. But, alas, in this case there is the other side of the coin, too. If you use Exchange Server in a profile you may encounter situations in which you don’t get a needed event notification such as OnNewMail. The reasons may be:</p>
<ul>
<li>The Mapi Store Accessor connects to the MAPI subsystem after the first synchronization between Outlook and Exchange (i.e. when Outlook loads). That is, you will not get notifications for all e-mails that were received before the MAPI Accessor initialize subroutine. To solve this problem you can try to use Exchange Client Extensions. You can read more in an article in <a href="http://support.microsoft.com/kb/28599">MSDN</a>.  </li>
<li>You close Outlook before event notification arrived and that is why you do not get it anymore. To resolve this issue you have to track all items and check by timer for new items. For instance, you can use ReceivedTime or set user properties on arrived emails and is this way you can recognize old and new ones. Certainly you can choose your own way of tracking new emails.</li>
</ul>
<p>	My experience shows that for Exchange server profiles, an event notification may delay for an on an arbitrary period. Some developers mistakenly reported that event notification didn’t work with Exchange server. In fact, they missed event notifications when closing Outlook immediately after the event had occurred. </p>
<p>Eugene Astafiev<br />
Add-in Express Team</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/04/25/newmail-itemadd-outlook-events/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Office add-in localization: ribbon and commandbar controls, task panes etc.</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/04/19/localization-office-addin-ribbon-commandbar/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/04/19/localization-office-addin-ribbon-commandbar/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 13:42:21 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[Add-in Express VCL]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[COM add-ins]]></category>

		<category><![CDATA[Delphi]]></category>

		<category><![CDATA[Office]]></category>

		<category><![CDATA[Office 2007 Ribbon]]></category>

		<category><![CDATA[Outlook]]></category>

		<guid isPermaLink="false">http://www.add-in-express.com/creating-addins-blog/?p=44</guid>
		<description><![CDATA[To localize your COM add-in, you need to know the language settings of the Office application (host application) that the add-in is currently loaded in. In this post you will find some VB.NET and Delphi code samples of localizing your COM add-ins.]]></description>
			<content:encoded><![CDATA[<p>To localize your COM add-in, you need to know the language settings of the Office application (host application) that the add-in is currently loaded in. This is possible through the Application.LanguageSettings property provided by every Office application. This property returns a COM class (of the LanguageSettings type) which provides the LanguageID property (function in C#). LanguageID returns an integer value which is the language id of the Office application.  Every language id (also known as Locale ID or LCID) is listed at <a href="http://www.microsoft.com/globaldev/reference/lcid-all.mspx">http://www.microsoft.com/globaldev/reference/lcid-all.mspx</a>. In a minute I will show you what events to use and how to get access to the host application object. You will also find some VB.NET and Delphi code samples of localizing your <a href="http://www.add-in-express.com/">Add-in Express</a> based COM add-ins. </p>
<h3>Localizing command bar controls</h3>
<p>Pay attention to the AddinInitialize event of the <a href="http://www.add-in-express.com/add-in-net/architecture.php">add-in module</a> (OnAddInInitialize in the VCL edition). Its event handler is the best place to check the localization of the Office application and modify all user-visible properties of your command bar controls. Note that this event fires <strong>before </strong>any custom command bar is added to the command bar system of the host application.</p>
<p>When localizing command bar controls in Add-in Express, make a clear distinction between temporary and non-temporary (permanent) controls. Temporary command bar controls are created every time the add-in starts and are removed when the host application closes or the add-in is checked off in the COM Add-ins dialog. In the following code, it is assumed that AdxCommandBarButton1 is a temporary command bar button. That is, its Temporary property is set to true.</p>
<pre class=SrcCode><code class=vb>   Private Sub AddinModule_AddinInitialize(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles Me.AddinInitialize
      Dim LCID As Integer
      LCID = Me.HostApplication.LanguageSettings. _
         LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI)
      Select Case LCID
         Case 1033 'English
            AdxCommandBarButton1.Caption = "English Caption"
            AdxCommandBarButton1.TooltipText = "English Hint"
            AdxCommandBarButton1.DescriptionText = "English Description"
         Case 1036 'French
            ...
         Case 1031 'German
            ...
         Case 1040 'Italian
            ...
         Case Else ' isn't supported - use English
            ...
      End Select
   End Sub</code></pre>
<p>See how to implement the same approach in VCL (Delphi):</p>
<pre class=SrcCode><code class=delphi>procedure TAddInModule.adxCOMAddInModuleAddInInitialize (Sender: TObject);
begin
  case HostApp.LanguageSettings.LanguageID[msoLanguageIDUI] of
  1033: begin // English
    CommandBar1.Controls[0].AsButton.Caption :=
                                             'English Caption';
    CommandBar1.Controls[0].AsButton.TooltipText :=
                                                      'English Hint';
    CommandBar1.Controls[0].AsButton.DescriptionText :=
                                                  'English Description';
  end;
  1036: begin // French
    ...
  end;
  1031: begin // German
    ...
  end;
  1040: begin // Italian
    ...
  end;
  else begin // not supported - use English
    ...
  end;
end;</code></pre>
<p>Non-temporary controls are created at the first start of the add-in. They are removed when you uninstall the add-in or uncheck it in the COM Add-ins dialog in the Office application. So, if AdxCommandBarButton2 has the Temporary property set to false, the following code should be used:</p>
<pre class=SrcCode><code class=vb>   Private Sub AddinModule_AddinInitialize(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles Me.AddinInitialize
      If Me.StartMode = AddinExpress.MSO.ADXStartMode.smFirstStart Then
         Dim LCID As Integer
         LCID = Me.HostApplication.LanguageSettings. _
            LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI)
         Select Case LCID
            Case 1033 'English
               AdxCommandBarButton2.Caption = "English Caption2"
               AdxCommandBarButton2.TooltipText = "English Hint2"
               AdxCommandBarButton2.DescriptionText = "English Description2"
            Case 1036 'French
               ...
            Case 1031 'German
               ...
            Case 1040 'Italian
               ...
            Case Else ' isn't supported - use English
               ...
         End Select
      End If
   End Sub</code></pre>
<p>Delphi developers write the conditional statement in their own way:</p>
<pre class=SrcCode><code class=delphi>  if Self.StartMode = smFirstStart then</code></pre>
<p>When localizing custom .NET controls to be <a href="http://www.add-in-express.com/office-toolbar-controls/">embedded onto Office toolbars</a>, you use one of the approaches above depending on the value of the Temporary property of the corresponding <a href="http://www.add-in-express.com/docs/toolbar-controls-terminology.php">AdvancedCommandBarControl</a>. Note, that you need to localize the control specified in the AdvancedCommandBarControl.Control property.</p>
<h3>Localizing Ribbon controls</h3>
<p>Office 2007 Ribbon controls are created when the add-in starts. They are removed whenever the add-in unloads. You can localize the controls in the OnRibbonBeforeCreate event of the add-in module. </p>
<p>The only exception to this rule is the dynamicMenu Ribbon control. It provides the OnCreate event that allows populating the component with controls. Naturally, this event is suitable for localizing the controls.</p>
<h3>Localizing Office 2007 Task Panes</h3>
<p>In .NET, a task pane is a UserControl an instance of which is created whenever the task pane is shown. The instance is removed when the task pane is destroyed (see the OnTaskPaneBeforeDestroy event of the add-in module). To localize the task pane, use the Load event of the UserControl.</p>
<p>In Delphi, a custom Office task pane is a descendant of TActiveForm and you use its OnCreate event. For instance:</p>
<pre class=SrcCode><code class=delphi>procedure TmyPane.ActiveFormCreate(Sender: TObject);
begin
  case ADDIN_MODULE_GLOBAL_VARIABLE.HostApp.LanguageSettings.LanguageID[2] of
    1033: begin
    ...
  end;
end;</code></pre>
<h3>Localizing Outlook property pages</h3>
<p>Property pages for the Tools | Options and Folder Properties dialogs are created every time when the dialogs are shown. To localize them, use the Load event of the property page class.</p>
<p>In Delphi, you use the OnCreate event exactly in the same way as shown above.</p>
<h3>Localizing Excel task panes and Outlook forms</h3>
<p><a href="http://www.add-in-express.com/docs/net-custom-task-panes.php#Excel-Task-Panes">Add-in Express Excel task panes</a> as well as <a href="http://www.add-in-express.com/outlook-extension/">Outlook forms</a> are created whenever the application-specific task pane or form manager decides that the current context fits the form or pane settings. At this very moment, the constructor of the pane or form is called. That is, the localization code can be safely placed in their constructors. For instance, </p>
<pre class=SrcCode><code class=vb>    Public Sub New()
      MyBase.New()

      'This call is required by the Windows Form Designer.
      InitializeComponent()

      'Add any initialization after the InitializeComponent() call
      Dim LCID As Integer
      LCID = MyOutlookTodayAddin.AddinModule.CurrentInstance. _
         HostApplication.LanguageSettings. _
         LanguageID(Office.MsoAppLanguageID.msoLanguageIDUI)
      Select Case LCID
         Case 1033 'English
            Me.Text = "English Text"
         Case 1036 'French
            ...
         Case 1031 'German
            ...
         Case 1040 'Italian
            ...
         Case Else ' isn't supported - use English
            Me.Text = "English Text"
      End Select
   End Sub</code></pre>
<p>In Add-in Express for Office and CodeGear VCL, you localize your Add-in Express Outlook forms and Excel task panes in the OnCreate event. To retrieve the current LCID, you use an appropriate manager. For instance, in an Add-in Express Outlook form, you do it as follows: </p>
<pre class=SrcCode><code class=delphi>procedure TadxOlForm1.adxOlFormCreate(Sender: TObject);
var
LCID: Integer;
begin
  if (self.FormsManager <> nil) then begin
    LCID := self.FormsManager.OutlookAppObj.LanguageSettings.LanguageID[2];
  end;
end;</code></pre>
<p>When using Add-in Express Excel task pane in Delphi, the same code may look like the following one:</p>
<pre class=SrcCode><code class=delphi>procedure TadxExcelTaskPane1.adxExcelTaskPaneCreate(Sender: TObject);
var
LCID: Integer;
begin
  if (self.ExcelTaskPaneManager <> nil) then begin
    LCID :=
        self.ExcelTaskPaneManager.ExcelAppObj.LanguageSettings.LanguageID[2];
  end;
end;</code></pre>
<h3>Localizing Outlook Bar shortcuts and shortcut groups</h3>
<p>Outlook Bar shortcuts and shortcut groups are created when the add-in starts for the first time. They are removed when the add-in is unchecked in the COM Add-ins dialog or the add-in is uninstalled. To localize them, you can use the same event and the same approach as shown above for the non-temporary command bar controls.</p>
<p>Andrei Smolin<br />
Add-in Express Team Leader </p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/04/19/localization-office-addin-ribbon-commandbar/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to customize Outlook Today page programmatically?</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/04/11/outlook-today-page-customize-programmatically/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/04/11/outlook-today-page-customize-programmatically/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 17:49:03 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.add-in-express.com/creating-addins-blog/?p=36</guid>
		<description><![CDATA[In this post, I show you how to create a custom Outlook home folder page and enrich it with VBScript. Also I reveal the .NET way provided by Add-in Express: you create a custom .NET form and show it in the same way as Outlook Today does.]]></description>
			<content:encoded><![CDATA[<p>In this post, I will show you how to create a custom Outlook home folder page in VBScript and in .NET (VB, C#, C++). </p>
<p>In fact, there are 2 ways of customizing Outlook Today: </p>
<ul>
<li>It can be modified by the user, you just need to open Outlook help (see the Help menu) and enter &#8220;customize Outlook today&#8221; in the Search For field.</li>
<li>Or, if you are a developer, you may want to add some functionality to Outlook Today programmatically. Let’s dig deeper into this.</li>
</ul>
<p>Outlook Today is a set of HTML pages that use VBScript to display some Outlook-related information. If you open the Properties window for Personal Folder and navigate to the Home tab, you&#8217;ll see that the default page address is as follows:</p>
<pre class=SrcCode><code class=vb>res://C:\Program Files\Microsoft Office\OFFICE11\1033\outlwvw.dll/outlook4.htm</code></pre>
<p>That is, the first Outlook Today page is shown from resources of some Outlook-related .DLL and this implies that no source code is available for Outlook Today. </p>
<p>On other words, the developer can only <a href="http://www.add-in-express.com/outlook-extension/video.php">replace Outlook Today with a custom page</a>. Let&#8217;s create such a page: open NotePad and copy / paste the text below:</p>
<pre class=SrcCode><code class=vb>
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;VBScript: the first try&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
</code></pre>
<p>So, our custom page consists of the html tag that contains the head and body tags. The page is empty, as you can see. Now let&#8217;s add a button:</p>
<pre class=SrcCode><code class=vb>...
&lt;body&gt;
&lt;input type="button" value="Go" onClick="greeting()"/&gt;
&lt;/body&gt;
...
</code></pre>
<p>The button caption is &#8220;Go&#8221; and when you click on the button, the greeting function is called. Now let&#8217;s add the function:</p>
<pre class=SrcCode><code class=vb>...
&lt;head&gt;
&lt;script type="text/vbscript"&gt;

function greeting()
   document.write("&lt;p&gt;Hello, developer!&lt;/p&gt;")
end function

&lt;/script&gt;
&lt;/head&gt;
...
</code></pre>
<p>This simple function prints a paragraph containing the greeting. </p>
<p>Now we are ready to plug the page into Outlook:</p>
<ul>
<li>Right-click on a folder and choose Properties in the context menu. Note that if the folder is Personal Folders, it means that we replace the Outlook Today page with our custom one.</li>
<li>Specify the page location and tick the checkbox that shows the page.</li>
</ul>
<p><img src="/creating-addins-blog/wp-upload/outlook-home-page-settings.gif" width="367" height="450"alt="Folder Properties dialog in Outlook" /> </p>
<p>Note that the Address textbox in the screenshot above corresponds to the WebViewUrl property of the MAPIFolder class (Folder in Outlook 2007). Accordingly, the checkbox labeled as &#8220;Show home page by default for this folder&#8221; corresponds to the WebViewOn property. These properties allow you to set an HTML page for any Outlook folder on the fly. For instance, you can replace the Outlook Today page with your custom one. If you use these properties, you should keep in mind that Outlook 2002 has a well-known bug confirmed by Microsoft: when you set WebViewUrl, the page will show up after the user switches to another folder, and then switches back to the folder with the home page (see <a href="http://support.microsoft.com/kb/305093">http://support.microsoft.com/kb/305093</a> for details).</p>
<p>Here is the page:</p>
<p><img src="/creating-addins-blog/wp-upload/custom-home-page.gif" width="532" height="317"alt="An HTML page shown in Outlook" /> </p>
<p>At this stage, you can move in the following directions:</p>
<ul>
<li>Learning HTML</li>
<p>As always, Google is a good helper: just search for HTML Tutorial </p>
<li>Learning VBScript</li>
<p>Here is a highly recommended guide: <a href="http://msdn2.microsoft.com/en-us/library/d1wf56tt.aspx">http://msdn2.microsoft.com/en-us/library/d1wf56tt.aspx</a></p>
</ul>
<p>However, Outlook Today can display some information about tasks, e-mails / messages and appointments and meetings. To get these data as well as information about contacts, notes and other Outlook items, you have to dig into the Outlook object model: </p>
<ul>
<li>Open Outlook </li>
<li>Choose Tools | Macros | Visual Basic Editor in the menu or just press Alt+F11</li>
<li>In the VB IDE, choose View | Object Browser in the menu or just press F2</li>
</ul>
<p>The object browser allows choosing the object model to browse in its topmost combo. Then you choose a class in the left pane and see class members in the right pane. </p>
<p><img src="/creating-addins-blog/wp-upload/outlook-object-model.gif" width="558" height="399" alt="VBA Object Browser" /> </p>
<p>Application is the most important Outlook class. It provides the Session property of the NameSpace type. The NameSpace class contains Folders. Each folder (of the Folder type in Outlook 2007, MAPIFolder in Outlook 2000-2003) contains Items and other Folders. Each Item provides the Class property the value of which is a constant uniquely identifying every item type: MailItem, TaskItem, ContactItem, etc. To get help on a class or a class member just press F1. When reading help, pay attention to the availability and other aspects of using this or that class or class member in VBScript. For instance, Outlook events are not available in VBScript.</p>
<p>The following sample function uses the Outlook object model to demonstrate how you can apply the above-mentioned information. The function lists top-level folders in the current Outlook session:</p>
<pre class=SrcCode><code class=vb>function greeting()
   on error resume next

   dim OutlookApp
   on error resume next
   set OutlookApp = GetObject(, "Outlook.Application")
   if OutlookApp is Nothing then
      document.write("&lt;p&gt;Hello, developer!&lt;/p&gt;")
      exit function
   else
      document.write("&lt;p&gt;Hello, Outlook developer!&lt;/p&gt;")
   end if
   on error goto 0

   dim folderCount
   folderCount = OutlookApp.Session.Folders.Count
   document.write("&lt;p&gt;There are " &#038; folderCount &#038; " top-level folders in this session. ")
   document.write("Here they are:&lt;/p&gt;&lt;ul>")
   for i = 1 to folderCount
      dim fldr
      set fldr = OutlookApp.Session.Folders.Item(i)
      document.write("&lt;li&gt;" &#038; fldr.Name &#038; "&lt;/li&gt;")
   next
   document.write("&lt;/ul&gt;")
   document.title = "VBScript: the first try"
end function
</code></pre>
<p>When I click the button, the function shows the following output in my Outlook 2003. You can do the same in Outlook 2000, 2002 (XP) and Outlook 2007:</p>
<p><img src="/creating-addins-blog/wp-upload/custom-outlook-today.gif" width="599" height="297" alt="Custom HTML page shown in Outlook" /> </p>
<p>As you can see, it is quite simple. </p>
<p><a href="http://www.add-in-express.com/add-in-net/">Add-in Express</a> allows .NET developers to avoid such an extreme. It introduces the Advanced Outlook Form Regions technology, which among other features, empowers Outlook developers to quickly create <a href="http://www.add-in-express.com/outlook-extension/overview.php">custom forms / views in Outlook Today style</a>. </p>
<p>Add-in Express provides a form class designed for deep integration with Outlook windowing: structures, chains, and procedures. To control the form, it supplies a special component, the Outlook Forms Manager. Let&#8217;s try this way.</p>
<p>In an Outlook COM add-in project, you add the above-mentioned form using the Add New Item dialog:</p>
<p><img src="/creating-addins-blog/wp-upload/add-custom-form.gif" width="540" height="347" alt="Add-in Express Outlook Form in the Add New Item dialog in Visual Studio 2008" /> </p>
<p>Then you add a Forms Manager to the <a href="http://www.add-in-express.com/add-in-net/components.php#COMADDIN">Add-in module</a>:</p>
<p><img src="/creating-addins-blog/wp-upload/outlook-forms-manager.gif" width="174" height="90" alt="Outlook Forms Manager added to the add-in module" /> </p>
<p>In the properties window, you choose the Forms property and add an item to the collection:</p>
<p><img src="/creating-addins-blog/wp-upload/webview-settings.gif" width="599" height="544" alt="Specifying item settings" /> </p>
<p>This item tells the Outlook Forms Manager to show the form specified in the FormClassName property when the user navigates to the folder specified in the FolderName property. The form will be shown as the home page for that folder: this is specified by the value of the ExplorerLayout property.</p>
<p>Here is how my custom Outlook Today form works in Outlook 2007. Please remember that you can achieve the same result in Outlook 2000, 2002 and Outlook 2003 :</p>
<p><img src="/creating-addins-blog/wp-upload/custom-outlook-today-page.gif" width="599" height="297" alt="Custom .NET form shown as a home folder page in Outlook" /> </p>
<p>And this way is a really simple and easy one! Note that you can debug your form in the same manner as you debug any .NET project: specify the external program to run and press F5. As to deploying the form, Add-in Express provides both MSI and <a href="http://www.add-in-express.com/docs/net-clickonce-solution.php">ClickOnce</a> ways.</p>
<p>Andrei Smolin<br />
Add-in Express Team Leader</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/04/11/outlook-today-page-customize-programmatically/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to get access to hidden Outlook items via Extended MAPI?</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/04/07/how-to-get-access-to-hidden-outlook-items-via-extended-mapi/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/04/07/how-to-get-access-to-hidden-outlook-items-via-extended-mapi/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 14:38:01 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[MAPI]]></category>

		<category><![CDATA[Outlook]]></category>

		<guid isPermaLink="false">http://www.add-in-express.com/creating-addins-blog/?p=32</guid>
		<description><![CDATA[Microsoft Outlook and Exchange are among the most popular applications utilizing MAPI. Add-in Express provides Outlook developers with a free component, MAPI Store Accessor, that hides MAPI complexities to provide developers with easy access to MAPI features.]]></description>
			<content:encoded><![CDATA[<p>MAPI (also known as Extended MAPI) is a powerful and complex COM-based API developed for creating mail-enabled applications. Microsoft Outlook and Exchange are among the most popular applications utilizing MAPI. Add-in Express provides Outlook developers with a free component, <a href="http://www.add-in-express.com/products/mapi-store-events.php">MAPI Store Accessor</a>, that hides MAPI complexities to provide developers with easy access to MAPI features. One of them is hidden items. </p>
<h3>Hidden items in Extended MAPI</h3>
<p>Storing some application-specific data between sessions is quite a usual task for Outlook developers. Such data are store either in the Windows registry or just in a file (binary or text, custom format or XML). </p>
<p>The MAPI subsystem provides yet another possibility: it allows you to create and save any data in hidden items. As the name suggests, a hidden item isn&#8217;t visible in Outlook. Hidden items are similar to usual mail, contact, and task items because they have the same properties: subject, body, attachments, etc.  Also, you can find the term “associated content” in various information sources which has exactly the same meanings.</p>
<p>As an example of this approach, Outlook saves folder view settings in hidden items. Views, custom form definitions, archive settings, and many other configuration options can be stored in such hidden items. In Outlook 2007, you can find the StorageItem class that describes a hidden item.</p>
<p>MAPI Store Accessor provides an easy access to this feature of MAPI through the HiddenMapiItems property of the AddinExpress.MAPI.Folder class. To demonstrate the use of this property, I developed a small application that creates a new MAPI session for the default MAPI profile and show the following form:</p>
<p><img src="/creating-addins-blog/wp-upload/hidden-mapi-items.gif" width="474" height="377" alt="Create, view, and delete hidden Outlook items with a simple application." /></p>
<p>The form allows choosing a folder name in order to see its hidden items. In the list box, I show the subject and the class name of hidden items. You can download the <a href="http://www.add-in-express.com/support/addin-vb-net.php#2168">source code of the Hidden Outlook Items via Extended MAPI sample in VB.NET</a> and in <a href="http://www.add-in-express.com/support/addin-c-sharp.php#2169">C#</a>.</p>
<p>You can create such an item and use standard and / or custom properties to store your data. </p>
<p>To set a value of some standard property in the SetProperty method, you use the corresponding property tag from the AddinExpress.MAPI.ADXMAPIPropertyTag enumeration.</p>
<p>To create a custom property you have to combine a property type with a property ID into the property tag. For example, consider the following code:</p>
<p><strong>C#</strong>:
<pre class=SrcCode><code class=c#>mapiItem.SetProperty(0x340F0003, myLongValue);</code></pre>
<p><strong>VB.NET</strong>:
<pre class=SrcCode><code class=c#>mapiItem.SetProperty(CType(&#038;H340F0003, UInteger), myLongValue)</code></pre>
<p>The first parameter of the SetProperty method is a property tag. The first part of the property tag is a property ID (0&#215;340F) and the second one is a property type. In this case the property type is PT_LONG (0&#215;0003). </p>
<p>Extended MAPI allows you to choose an ID for your custom property from the predefined ranges of values. The ranges are listed in the MAPITags.h file. Here they are:</p>
<p>The following ranges should be used for all property IDs. Note that property IDs for objects other than messages and recipients should all fall in the range 0&#215;3000 to 0&#215;3FFF:</p>
<table class="TableWideBorder" cellspacing="1" cellpadding="1" border="1" style="width: 600px; ">
<tr>
<td><b>From</b></td>
<td><b>To</b></td>
<td><b>Kind of property</b></td>
</tr>
<tr>
<td>0001</td>
<td>0BFF</td>
<td>MAPI_defined envelope property</td>
</tr>
<tr>
<td>0C00</td>
<td>0DFF</td>
<td>MAPI_defined per-recipient property</td>
</tr>
<tr>
<td>0E00</td>
<td>0FFF</td>
<td>MAPI_defined non-transmittable property</td>
</tr>
<tr>
<td>1000</td>
<td>2FFF</td>
<td>MAPI_defined message content property</td>
</tr>
<tr>
<td>3000</td>
<td>3FFF</td>
<td>MAPI_defined property (usually not message or recipient)</td>
</tr>
<tr>
<td>4000</td>
<td>57FF</td>
<td>Transport-defined envelope property</td>
</tr>
<tr>
<td>5800</td>
<td>5FFF</td>
<td>Transport-defined per-recipient property</td>
</tr>
<tr>
<td>6000</td>
<td>65FF</td>
<td>User-defined non-transmittable property</td>
</tr>
<tr>
<td>6600</td>
<td>67FF</td>
<td>Provider-defined internal non-transmittable property</td>
</tr>
<tr>
<td>6800</td>
<td>7BFF</td>
<td>Message class-defined content property</td>
</tr>
<tr>
<td>7C00</td>
<td>7FFF</td>
<td>Message class-defined non-transmittable property</td>
</tr>
<tr>
<td>8000</td>
<td>FFFE</td>
<td>User-defined Name-to-id mapped property</td>
</tr>
</table>
<p>The 3000-3FFF range is further subdivided as follows:</p>
<table class="TableWideBorder" cellspacing="1" cellpadding="1" border="1" style="width: 600px; ">
<tr>
<td><b>From</b></td>
<td><b>To</b></td>
<td><b>Kind of property</b></td>
</tr>
<tr>
<td>3000</td>
<td>33FF</td>
<td>Common property such as display name, entry ID</td>
</tr>
<tr>
<td>3400</td>
<td>35FF</td>
<td>Message store object</td>
</tr>
<tr>
<td>3600</td>
<td>36FF</td>
<td>Folder or Adderess Book container</td>
</tr>
<tr>
<td>3700</td>
<td>38FF</td>
<td>Attachment</td>
</tr>
<tr>
<td>3900</td>
<td>39FF</td>
<td>Address book object</td>
</tr>
<tr>
<td>3A00</td>
<td>3BFF</td>
<td>Mail user</td>
</tr>
<tr>
<td>3C00</td>
<td>3CFF</td>
<td>Distribution list</td>
</tr>
<tr>
<td>3D00</td>
<td>3DFF</td>
<td>Profile section</td>
</tr>
<tr>
<td>3E00</td>
<td>3FFF</td>
<td>Status object</td>
</tr>
</table>
<p>Find more about <a href="http://msdn2.microsoft.com/en-us/library/ms531530.aspx">MAPI property tags</a> on MSDN. </p>
<p>Eugene Astafiev<br />
Add-in Express Team</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/04/07/how-to-get-access-to-hidden-outlook-items-via-extended-mapi/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Build Outlook add-in in .NET to manage Outlook templates &#038; signatures</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/03/28/build-outlook-add-in-in-net-to-manage-outlook-templates-signatures/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/03/28/build-outlook-add-in-in-net-to-manage-outlook-templates-signatures/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 17:57:28 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[add-ins]]></category>

		<category><![CDATA[Outlook]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=31</guid>
		<description><![CDATA[How to avoid a boring and time consuming work of retyping the sane words and phrases in Outlook correspondence. Let’s develop an Outlook add-in that will keep and manage all our template phrases and signatures.]]></description>
			<content:encoded><![CDATA[<p>I love small plug-ins. They are simple, quick, and reasonably priced. There is a small add-in, which I love with all my heart. It is <a href="http://www.ablebits.com/outlook-templates-phrases/index.php">Template Phrases for Outlook.<br />
</a><br />
I want to walk you through this Outlook plug-in, show you how it works and also how to create such add-ins.</p>
<p>You can easily imagine how often the Add-in Express support team type the same words or phrases in their e-mails hundreds of time, explain the same things again and again to our customers and prospects: greetings, signatures, the same answers to the same questions about ordering, downloading, installing, activating, and using our products, etc. </p>
<p>Probably you need to do the same in your daily work. Of course, you can use signatures in Outlook, but it is not convenient if you have more than   10-15 of them.</p>
<p>The idea was born when we realized that we spent too much time on inserting standard phrases into our e-mails. Aren&#8217;t we Office developers? Didn&#8217;t we develop Add-in Express for <a href="http://www.add-in-express.com/add-in-net/">building Office add-ins in .NET</a>, <a href="http://www.add-in-express.com/add-in-vsto/">Outlook, Excel and Word plug-ins in VSTO</a>, and <a href="http://www.add-in-express.com/add-in-delphi/">Office COM add-ins in Delphi</a>. Didn&#8217;t we develop the Add-in Express Extensions for Outlook that allows <a href="http://www.add-in-express.com/outlook-extension/">embedding custom forms into Outlook windows</a>? When we detected the problem and found the way to solve it, the life speeded up – you know how this happens. </p>
<p>Here is the result of our work.<br />
<img src="/creating-addins-blog/wp-upload/custom-outlook-form.gif" width="562" height="342" alt=" Template Phrases for Outlook add-in in my e-mail window" /><br />
The form embedded to the right side of the e-mail window above is a warehouse of phrases and blocks of text I use in my daily work. The screenshot above shows how you can organize your phrases in a folder tree. If you double-click the caption of the phrase template, the add-in pastes the phrase to where the text cursor stands in your e-mail. The add-in UI allows you to resize the form using the splitter. You can also use the button on the splitter to collapse / expand the form.</p>
<p>Now let&#8217;s create a sample COM add-in project to show a form like the one above.</p>
<p>You create a new Outlook COM add-in by choosing the Add-in Express COM Add-in project template in the New Project dialog in Visual Studio 2003 - 2008 or in the File | New | Other dialog in Delphi. VSTO developers create a COM add-in project and add an Add-in Express COM Add-in Module to the project via the Add New Item dialog.</p>
<p>The plug-in will display a form embedded into Outlook windows. To create such a form, you follow two steps below:<br />
  1.	  Add a new Outlook Form to your project and populate it with controls<br />
  2.	  Add Outlook Forms Manager to the add-in module, create an item in the Forms collection of the Forms Manager, choose the form the item controls, and specify context and UI properties for the form.</p>
<p>To create the form itself, you choose the Add-in Express Outlook Form item in the appropriate dialog of your development platform:</p>
<ul class="list">
<li>  For Add-in Express .NET projects, in the Add New Item dialog, you choose the Common Items / Add-in Express Items / Outlook / Add-in Express Outlook Form item</li>
<li>   For Add-in Express VSTO projects, in the Add New Item dialog, you choose the Common Items / Add-in Express for VSTO Items / Outlook / Add-in Express Outlook Form item</li>
<li>   In Add-in Express VCL projects, you choose the Add-in Express Outlook Form item in the File |New | Other dialog.</li>
</ul>
<p>The form is a special descendant of System.Windows.Forms.Form (in Delphi, TForm). It provides a number of properties. In our Outlook plug-in, we will use the InspectorObj property. It returns the Outlook.Inspector COM object for the e-mail window that the form is shown in. Using this object, you can implement the most important functionality provided by the plug-in:  pasting a string at the cursor location in the current message body. </p>
<p>To understand the scale of the problem, it&#8217;s enough to admit that Outlook shows the following e-mail inspector window types: </p>
<ul class="list">
<li>   Word</li>
<li>   HTML </li>
<li>   Plain text</li>
<li>   RTF</li>
</ul>
<p>However, for the add-in that inserts text strings into the message, the last one, RTF, doesn&#8217;t make sense because Outlook uses this format to read (not edit) e-mail messages.</p>
<p>To recognize the message format, you can use the Inspector.EditorType property. Then, you work with the message text using the following routes:</p>
<table class="TableWideBorder" cellspacing="1" cellpadding="1" border="1" style="width: 600px; ">
<tr>
<td><b>EditorType</b></td>
<td><b>How to get the editor?</b></td>
<td><b>Comments</b></td>
</tr>
<tr>
<td>Word</td>
<td>See the Inspector.WordEditor property.	</td>
<td>Use the Word object model.</td>
</tr>
<tr>
<td>HTML	</td>
<td>See the Inspector.HTMLEditor property.</td>
<td>Use any HTML parser, say mshtml.</td>
</tr>
<td>Plain-text</td>
<td>Use Windows API to get the editor.	</td>
<td>Use Text Object Model.</td>
</table>
<p>Note also that when you use <a href="http://www.ablebits.com/outlook-templates-phrases/index.php">Outlook Templates plug-in</a> to paste a phrase, the add-in returns focus to the editor window and enables the Edit | Undo menu item without faults. &#8220;I love this game&#8221;.</p>
<p>A notable part of the form is the toolbar at its top. To create such a toolbar, you can use built-in and third party controls. For more ideas, have a look at<a href="http://www.add-in-express.com/creating-addins-blog/2008/03/21/custom-office-controls-colors/"> how to paint toolbar controls in the Office style.</a></p>
<p>Other tasty features of the plug-in are the result of usual developer&#8217;s work:</p>
<table class="TableWideBorder" cellspacing="1" cellpadding="1" border="1" style="width: 600px; ">
<tr>
<td><b>Feature</b></td>
<td><b>How to implement it?</b></td>
</tr>
<tr>
<td>You can organize your templates in folders and sub-folders.</td>
<td>	Any tree component will do it for you.</td>
</tr>
<tr>
<td>The add-in allows importing<br />
 / exporting template phrases using a file containing an XML markup.	</td>
<td>You can use any XML parser.</td>
</tr>
<tr>
<td>You can assign a key combination to a phrase.</td>
<td>Add-in Express provides the keyboard shortcut component. A far longer way is creating a keyboard hook (see SetWindowsHookEx in MSDN).</td>
</tr>
<tr>
<td>Macros in template phrases.	</td>
<td>Well, it&#8217;s mostly a familiar find-and-replace. </td>
</tr>
<tr></tr>
</table>
<p>Enough with the form. Now we need to add an Outlook Forms Manager to the add-in module, add an item to its Items collection, and specify the item&#8217;s settings. We know that the form must be located on the right side of the mail inspector window. Here are the item&#8217;s properties to set:</p>
<table class="TableWideBorder" cellspacing="1" cellpadding="1" border="1" style="width: 600px; ">
<tr>
<td><b>Property</b></td>
<td style="widht=70px;"><b>Value</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>InspectorItemTypes	</td>
<td>Mail</td>
<td>	Our form will be shown for mail inspector windows only.</td>
</tr>
<tr>
<td>InspectorLayout</td>
<td>Right	</td>
<td>The form will be shown on the right side of the inspector window.</td>
</tr>
<tr>
<td>FormClassName	</td>
<td>&nbsp;</td>
<td>	This specifies the form we created on the previous step.</td>
</tr>
</table>
<p>That’s all for now. Hope you find it useful and enjoy using the <a href="http://www.ablebits.com/outlook-templates-phrases/index.php">Template Phrases for Outlook</a> as I do. </p>
<p>Andrei Smolin<br />
Add-in Express Team Leader</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/03/28/build-outlook-add-in-in-net-to-manage-outlook-templates-signatures/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Give Microsoft Office colors look to your custom .NET controls</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/03/21/custom-office-controls-colors/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/03/21/custom-office-controls-colors/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 18:52:36 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Office]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=30</guid>
		<description><![CDATA[To make your controls look like Office ones isn’t a simple task. When Office developers show .NET controls in their add-ins or standalone applications, they have to customize controls in order to conform to Office color styles.]]></description>
			<content:encoded><![CDATA[<p>To make your controls look like Office ones isn’t a simple task. When Office developers show .NET controls in their add-ins or standalone applications, they have to customize controls in order to conform to Office color styles. The common question in our support flow is “Do you have Office colors, can you please send them to me”? If you are asking the same question, I&#8217;ll try to answer it in this post. Also, I will show you some tricks in customizing .NET controls for that will be used with Office. But I believe that you just underestimate the pain you might have when creating such custom controls :)</p>
<p>For example, imagine the following situation: you develop an add-in which shows some data from a database. For this task, standard Office controls are practically useless, because their number is limited: button and combo box. Besides the obvious fact that such controls don’t fit for the task, they are toolbar controls and you can use them on Office toolbars only. Isn&#8217;t it better to show data using data presentation controls, such as DataView, ComboBox, TextBox, RichTextbox, etc designed specially for this purpose? You can show them in separate forms, on custom task panes in Office 2007, on toolbars, and on pre-Office 2007 panes. BTW, Add-in Express .NET and Add-in Express for VSTO allows you to place <a href="http://www.add-in-express.com/office-toolbar-controls/">.NET controls onto Office toolbars</a>, create <a href="http://www.add-in-express.com/docs/net-custom-task-panes.php">custom task panes in Excel 2000 – 2007</a>, <a href="http://www.add-in-express.com/outlook-extension/">Advanced Form Regions for Outlook 2007 - 2000</a>. </p>
<p>But you know that look-n-feel of these controls differ from standard Office controls. How to cope with this? Remember the rule of thumb: if you can’t do something with ready-to-use components, customize them! As a .NET developer you can inherit any existing control and add your own logic to it. That is the right way. Let&#8217;s follow it.</p>
<p>To make your controls comply with Office styles, you should know how Office paints its controls.</p>
<h3>Microsoft Office 2000</h3>
<p>The color scheme of the MS Office 2000 is almost completely based on colors of the operating system. Just change a system color, and Office 2000 will reflect this change without any unexpected mismatches. To search for Office colors, you use the PrintScreen button and any graphic editor which is able to determine RGB components of a pixel.  For instance, you can use <a href="http://www.getpaint.net/">Paint.NET</a>. Using this or some other graphic editor you can study every detail of a command bar control (which is an essence of pre-Ribbon coloring approaches) or any other area of all Office applications. </p>
<h3>Microsoft Office 2002 &#038; 2003</h3>
<p>Some colors in Office 2002 and 2003 are identical to system colors but others look like computed using a combination of system colors. Unfortunately, I am not good at guessing them. And you?</p>
<p>.NET Framework 2.0 provides two classes to help you in searching Office colors:</p>
<pre class=SrcCode><code class=c#>System.Windows.Forms.ProfessionalColorTable
System.Windows.Forms.ProfessionalColors
</code></pre>
<p>These classes allow your colors to approach (no more than that) to Office colors. All Office 2003 applications have color gradients – vertical and horizontal – in toolbars and toolbar controls. These classes give you the beginning, middle and ending colors of Office gradients. </p>
<h3>Microsoft Office 2007</h3>
<p>Microsoft presented a new GUI – Ribbon, also known as Fluent UI. Only the following Office applications use this new GUI:</p>
<ul class=list>
<li>Word </li>
<li>Excel 	</li>
<li>PowerPoint </li>
<li>Outlook (except for the Explorer window) </li>
<li>Access</li>
</ul>
<p>Others use the traditional command bar model. The color scheme of Microsoft Office 2007 isn’t based on Windows system colors. Instead, all Office 2007 applications use three predefined schemes:</p>
<ul class=list>
<li>Black</li>
<li>Blue</li>
<li>Silver </li>
</ul>
<p>To switch between them, you use the Options menu in any Office application that uses the Ribbon UI.</p>
<p>Add-in Express provides the OfficeColorSchemeChanged event that allows tracking changes in the color scheme. The second parameter in the event handler is of the AddinExpress.MSO.OfficeColorScheme type. To get the current color scheme, you use the OfficeColorScheme property. Believe me, this part is an easy one. </p>
<h3>High contrast mode</h3>
<p>This mode is used in the operating system to improve readability. To turn this mode on or off, you can use “Alt + Shift + PrtScr” shortcut (left Alt and Shift buttons only) or use settings in the Control Panel. To find out whether the user has enabled the high-contrast mode you need to check the following static property:</p>
<pre class=SrcCode><code class=vb>System.Windows.Forms.SystemInformation.HighContrast
</code></pre>
<p>In the System.Windows.Forms.SystemInformation (supported in all versions of the .NET platform),  you can find a lot of useful information about system settings such as current GUI settings of the OS and such.</p>
<h3>Changing color schemes</h3>
<p>When the user changes the system color settings, Windows notifies all windows on the system. In .NET, you can subscribe to the UserPreferenceChanged event of the SystemEvents class. Consider the following code:</p>
<pre class=SrcCode><code class=vb>[VB.NET]
AddHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, _
   AddressOf SystemSettingsChanged

....

Private Sub SystemSettingsChanged(ByVal sender As System.Object, _
   ByVal e As Microsoft.Win32.UserPreferenceChangedEventArgs)
   If (e.Category = Microsoft.Win32.UserPreferenceCategory.General) Then
      '
   End If
End Sub
</code></pre>
<pre class=SrcCode><code class=c#>[C#]
Microsoft.Win32.SystemEvents.UserPreferenceChanged +=
new Microsoft.Win32.UserPreferenceChangedEventHandler(
         SystemEvents_UserPreferenceChanged);

...

void SystemEvents_UserPreferenceChanged(object sender,
   Microsoft.Win32.UserPreferenceChangedEventArgs e)
   {
      if (e.Category == Microsoft.Win32.UserPreferenceCategory.General)
      {
         //
      }
   }
</code></pre>
<p>In the event handler, you choose new colors and update your custom control view. </p>
<h3>Gradients and fonts</h3>
<p>As you can see, Office 2003 and 2007 toolbars are filled with a gradient. Note, however, that the gradient may differ depending on the position of the command bar: horizontal, vertical, and floating</p>
<p>When customizing .NET controls, remember about fonts. Office toolbars&#8217; fonts are based on system fonts listed in System.Drawing.SystemFonts. You can use UserPreferenceChanged to track one or several system fonts that Office controls depend on (you have to determine this yourself). To apply a font to your controls, you have to use the System.Drawing namespace.</p>
<p>Eugene Astafiev<br />
Add-in Express Team</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/03/21/custom-office-controls-colors/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Make the Office 2007 Ribbon work easy</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/03/14/office-2007-ribbon-ui/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/03/14/office-2007-ribbon-ui/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 18:40:35 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Office]]></category>

		<category><![CDATA[Office 2007 Ribbon]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=29</guid>
		<description><![CDATA[Why the Ribbon tab designer by Add-in Express is better than that of VSTO 2008? Because it prevents the Office 2007 Ribbon XML from being constructed manually and in this way leaves no place for run-time errors.]]></description>
			<content:encoded><![CDATA[<p>Microsoft Office 2007 allows XML-based customizations for its Ribbon UI (user-interface). To achieve this, you, the developer, need to generate a string that contains a markup specifying custom ribbon controls and their properties as well as names of event handler procedures for these controls. Then, in an appropriate moment, you should supply the host application with the string. If the string is correct, the controls will be shown and you will get their events in the procedures which names you specified. </p>
<p>Say, if the event handler for your Office 2007 Ribbon button is called MyEventHandler, the XML must contain this name in the following way:</p>
<pre class=SrcCode><code class=c#>
&lt;customui xmlns=&quot;http://schemas.microsoft.com/office/2006/01/customui&quot;&gt;
  &lt;ribbon&gt;
    &lt;tabs&gt;
      &lt;tab idMso=&quot;MyTab&quot;&gt;
        &lt;group id=&quot;MyGroup&quot; label=&quot;My Group&quot;&gt;
          &lt;button id=&quot;button1&quot;
                    size=&quot;large&quot;
                    label=&quot;My Button&quot;
                    screentip=&quot;My Button Screentip&quot;
                    onAction=&quot;MyEventHandler&quot;
                    imageMso=&quot;HappyFace&quot; /&gt;
        &lt;/group&gt;
      &lt;/tab&gt;
    &lt;/tabs&gt;
&lt;/customui&gt;
</code></pre>
<p>The only way to make sure that the XML above is correct is to run your add-in. That is, you can&#8217;t check if your XML is valid at design-time. All my life I have been told that run-time warnings cost more than compile-time ones. Haven’t you?</p>
<p>There is another source of troubles: the signature of the method should conform to the rules described in manuals (see Downloads in the end of this post). However, if the signature of your method doesn&#8217;t correspond to that required by the Office 2007 Ribbon (say, if you add an extra parameter, mistakenly, of course), you&#8217;ll be never informed about this and your event handler will never be called. Nice, isn’t it?</p>
<p>These error-prone and time-consuming issues are successfully resolved in Add-in Express 2007 by introducing the <a href="http://www.add-in-express.com/add-in-net/modules.php#ribbon">Office 2007 Ribbon tab designer</a>.</p>
<p>With this Ribbon tab designer, you never have to deal with XML. Instead, you create the UI right in the designer that generates appropriate Ribbon components, events of which are handled in the usual manner. </p>
<p>For instance, let’s create a custom group with a custom Ribbon button on a custom tab in Excel 2007:</p>
<p><img src='/creating-addins-blog/wp-upload/ribbonbutton.gif' alt='A ribbon button in the Office 2007 Ribbon tab designer' /> </p>
<p>Now we handle the Click event of the button:</p>
<p><img src='/creating-addins-blog/wp-upload/buttonclick.gif' alt='Handling the Click event of a ribbon button' /> </p>
<p>After that re-target the group to the TabHome built-in tab:</p>
<p><img src='/creating-addins-blog/wp-upload/builtintab.gif' alt='The tab now targets to the TabHome built-in tab.' /> </p>
<p>That&#8217;s easy. However, the potential of our approach to the Office 2007 Ribbon UI customization becomes even more evident now, when Visual Studio 2008 includes the Ribbon designer for its VSTO 3 projects. Note that VSTO 3 is integrated with VS 2008; it provides project templates in the Office Visual Basic / Office and Visual C# / Office nodes of the New Project dialog in Visual Studio 2008.</p>
<p>To start with, <a href="http://www.add-in-express.com/add-in-net/">Add-in Express 2008 for Office and .NET</a> supports all Microsoft Office versions and, accordingly, you needn’t have several code bases for different Office versions. Instead, you create just one project that works for all Office versions. That is, you can just use the Ribbon visual designer in your project and the corresponding Ribbon XML markup will be generated, verified and transferred to Office 2007 with no extra steps from you part. I&#8217;m sure, the last feature is exactly what any developer would expect from the designer. But this isn&#8217;t the case with the Visual Studio 2008 designer. It is available for projects targeting Office 2007 only. I don&#8217;t like to speculate on why Microsoft chooses this or that way. Nevertheless, the fact is that if you need to support both Office 2003 and 2007, you need to create two VSTO projects: one for Office 2003 and another one for Office 2007.</p>
<p>Now I want to compare both Ribbon designers: Add-in Express’ and VSTO’s. Let me be honest and start from flaws in the Add-in Express Ribbon tab designer. Currently, I see two of them: first, our Office 2007 Ribbon tab designer allows designing a single tab only and second, it has a design-time defect in drawing items of a list, combo, and gallery. On the other hand, Microsoft&#8217;s designer supports designing many tabs and hopefully they display every tiny thing in their designer correctly. </p>
<p>Both designers provide quite similar features: you can design and handle any custom Ribbon controls: button groups, buttons, list boxes, combo boxes etc. You can target any control to a built-in or custom tab. Both Add-in Express and VSTO 3 generate XML from their designers transparently.</p>
<p>The most evident distinction between designers lies on the surface, however. In VSTO, the designer is just a designer. While in Add-in Express, the designer is part of the component set purposed for constructing the UI of your Office 2007 add-in. Let’s take built-in Ribbon controls. Neither of the designers allows you to process a built-in ribbon control. But Add-in Express provides a special component, RibbonCommand that allows connecting to any built-in ribbon control and handling its events without the need to dig into XML. </p>
<p>For instance, see how to disable the Copy command in Word 2007.</p>
<p><img src='/creating-addins-blog/wp-upload/disablebuiltin.gif' alt='Built-in Ribbon command 'Copy' is now disabled.' /> </p>
<p>As to VSTO 3, it includes the Ribbon (XML) item available in the Add New Item dialog (for projects targeting Office 2007 only). This approach adds some more flies to the ointment; just read comments in the file created when the Ribbon (XML) item is run: </p>
<ul>
<li>Copy a code block to this or that class</li>
<li>Create callbacks and note some special case</li>
<li>Add callback names to appropriate attributes of appropriate control tags in the XML file.</li>
</ul>
<p>R-r-r-r!  :)</p>
<p>Here, at Add-in Express we are working on simplifying and speeding up the development of Office COM add-ins. That&#8217;s why Add-in Express Ribbon UI designer gives you the possibility to <a href="http://www.add-in-express.com/docs/net-office-ribbon-tips.php">share Ribbon controls across multiple add-ins</a>. Note that this requires manual operations in VSTO 3. </p>
<p>Here is the source code that creates the above mentioned Ribbon components (Ribbon tab that contains a ribbon group containing a ribbon button). Note that the tab is shown only when the user composes or edits an e-mail in Outlook 2007.<br />
<a name=ribbon-vb-net></a></p>
<p class="smalltext"><b><br />
[VB.NET code] </b></p>
<pre class=SrcCode><code class=vb>
Private Sub InitializeComponent()
   Me.components = New System.ComponentModel.Container
   Dim resources As System.ComponentModel.ComponentResourceManager =
New System.ComponentModel.ComponentResourceManager(GetType(AddinModule))
   Me.RibbonTab = New AddinExpress.MSO.ADXRibbonTab(Me.components)
   Me.RibbonGroup = New AddinExpress.MSO.ADXRibbonGroup(Me.components)
   Me.RibbonButton = New AddinExpress.MSO.ADXRibbonButton(Me.components)
   Me.ImageList1 = New System.Windows.Forms.ImageList(Me.components)
   '
   'RibbonTab
   '
   Me.RibbonTab.Caption = "My Ribbon Tab"
   Me.RibbonTab.Controls.Add(Me.RibbonGroup)
   Me.RibbonTab.Id = "adxRibbonTab_33d6c3f63d17474db7bc3a04e1b1e7d9"
   Me.RibbonTab.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose
   '
   'RibbonGroup
   '
   Me.RibbonGroup.Caption = "My Ribbon Group"
   Me.RibbonGroup.Controls.Add(Me.RibbonButton)
   Me.RibbonGroup.Id = "adxRibbonGroup_65d7dab572ef41f7b462701d5210256c"
   Me.RibbonGroup.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose
   '
   'RibbonButton
   '
   Me.RibbonButton.Caption = "My Ribbon Button"
   Me.RibbonButton.Id = "adxRibbonButton_8257f64d29104b11a37ceb4b65f69359"
   Me.RibbonButton.Image = 0
   Me.RibbonButton.ImageTransparentColor = System.Drawing.Color.Transparent
   Me.RibbonButton.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose
   Me.RibbonButton.Size = AddinExpress.MSO.ADXRibbonXControlSize.Large
   '
   'ImageList1
   '
   Me.ImageList1.ImageStream = CType(resources.GetObject("ImageList1.ImageStream"),
System.Windows.Forms.ImageListStreamer)
   Me.ImageList1.TransparentColor = System.Drawing.Color.Transparent
   Me.ImageList1.Images.SetKeyName(0, "account_actions_24.png")
   '
   'AddinModule
   '
   Me.AddinName = "MyAddin7"
   Me.Images = Me.ImageList1
   Me.SupportedApps = AddinExpress.MSO.ADXOfficeHostApp.ohaOutlook

End Sub
</code></pre>
<p><a name=ribbon-csharp></a></p>
<p class="smalltext"><b>[C# code]</b> </p>
<pre class=SrcCode><code class=c#>
private void InitializeComponent()
{
   this.components = new System.ComponentModel.Container();
   System.ComponentModel.ComponentResourceManager resources =
 new System.ComponentModel.ComponentResourceManager(typeof(AddinModule));
   this.RibbonTab = new AddinExpress.MSO.ADXRibbonTab(this.components);
   this.RibbonGroup = new AddinExpress.MSO.ADXRibbonGroup(this.components);
   this.RibbonButton = new AddinExpress.MSO.ADXRibbonButton(this.components);
   this.imageList1 = new System.Windows.Forms.ImageList(this.components);
   //
   // RibbonTab
   //
   this.RibbonTab.Caption = "My Ribbon Tab";
   this.RibbonTab.Controls.Add(this.RibbonGroup);
   this.RibbonTab.Id = "adxRibbonTab_04dee6e0f08a4f8fa31f0f5982a998c7";
   this.RibbonTab.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose;
   //
   // RibbonGroup
   //
   this.RibbonGroup.Caption = "My Ribbon Group";
   this.RibbonGroup.Controls.Add(this.RibbonButton);
   this.RibbonGroup.Id = "adxRibbonGroup_74cbaba4b40444e6b45f1b8d9570410d";
   this.RibbonGroup.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose;
   //
   // RibbonButton
   //
   this.RibbonButton.Caption = "My Ribbon Button";
   this.RibbonButton.Id = "adxRibbonButton_6f220d15d7824b048e09e627e77f4227";
   this.RibbonButton.Image = 0;
   this.RibbonButton.ImageTransparentColor = System.Drawing.Color.Transparent;
   this.RibbonButton.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose;
   this.RibbonButton.Size = AddinExpress.MSO.ADXRibbonXControlSize.Large;
   //
   // imageList1
   //
   this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)
(resources.GetObject("imageList1.ImageStream")));
   this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
   this.imageList1.Images.SetKeyName(0, "account_actions_24.png");
   //
   // AddinModule
   //
   this.AddinName = "MyAddin8";
   this.Images = this.imageList1;
   this.SupportedApps = AddinExpress.MSO.ADXOfficeHostApp.ohaOutlook;

}
</code></pre>
<p>Andrei Smolin<br />
Add-in Express Team Leader</p>
<h3>Related posts:</h3>
<p><a href="http://www.add-in-express.com/creating-addins-blog/2007/04/30/customize-office-toolbars-ribbons-task-panes-on-ro-chrome/ ">Customize Office toolbars, ribbons, task panes on RO Chrome</a><br /><a href="http://www.add-in-express.com/creating-addins-blog/2007/07/04/create-office-addins-ribbons-toolbars-task-panes-menus/">Create Office add-ins: ribbons, toolbars, task panes, menus</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/03/14/office-2007-ribbon-ui/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to program IE add-on, toolbar / bar, menu in C#, VB.NET, C++</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2008/03/14/ie-addons-toolbars-menus-programming/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2008/03/14/ie-addons-toolbars-menus-programming/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 18:25:22 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express for Internet Explorer]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[IE add-ons]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=28</guid>
		<description><![CDATA[When I started developing IE add-ons I found out that Internet Explorer might generate a huge number of threads and processes and that my add-on is created in each of those threads.  However, my plug-in contains data that should be accessible for all instances of the IE add-on. In this post, I will tell you how to make communication between IE add-on instances easy using Add-in Express for Internet Explorer.]]></description>
			<content:encoded><![CDATA[<p>When I started developing IE add-ons I found out that Internet Explorer might generate a huge number of threads and processes and that my add-on is created in each of those threads.  However, my plug-in contains data that should be accessible for all instances of the IE add-on. In this post, I will tell you how to make communication between IE add-on instances easy using <a href="http://www.add-in-express.com/programming-internet-explorer/">Add-in Express for Internet Explorer</a>.</p>
<p>Let’s run Internet Explorer version 6 or 7. Now run Windows Task Manager and go to the Processes tab, find the IE process. You see that you have one running process of Internet Explorer. Run a new instance of Internet Explorer using a shortcut or typing “iexplore” in the Run menu of the Start button. And have a look at Task Manager again. Now you see that you have two different IE processes running on your machine. In other words, you have two windows of Internet Explorer in different processes.  </p>
<p>Close either of the IE windows and press “Ctrl+N” in the other. Check up Task Manager again. Now you see that you have one running IE process. But you have two IE windows. Interesting, isn’t it? The point is that you opened a new frame of Internet Explorer, but not a new instance. IE 7 behaves in the same manner. Let’s make sure. Click on the “New Tab” button to create a new tab or use the “Ctrl+T” shortcut. Check Task Manager for IE processes. You see that you still have one IE process. Naturally, each tab and window is created in a separate thread of execution. What is more, a new instance of your IE add-on is created for every such tab. </p>
<p>With Add-in Express you have a few ways to communicate with various add-on instances.</p>
<h3>Communicating with IE add-ons in the same process</h3>
<p>In Add-in Express, an IE module corresponds to the Internet Explorer add-on. That is, to access another instance or instances of the add-on, you need to find the corresponding IE modules. Then you can access the page and browser window (frame) using the appropriate properties of the module.</p>
<p>Every IE thread has its own ID – Thread ID (see the ThreadId property of the module). Using the thread ID you can easily get the module instance of your IE plug-in. Having the module object you can do various things on your own. Consider the following code in the class definition of the module:</p>
<pre class=SrcCode><code class=c#>int threadId = this.ThreadID;
AddinExpress.IE.ADXIEModule module = this.GetModuleByThread(threadId);
</code></pre>
<p>You can also get the module by index in the collection:</p>
<pre class=SrcCode><code class=c#>int threadId = this.GetModuleIndex();
AddinExpress.IE.ADXIEModule module = this.GetModuleByIndex(threadId);
</code></pre>
<p>Please note that using the thread id you can avoid the non-existing index error. For example, you’ve closed a tab and are trying to get the module by index which you saved earlier. You will have an exception, because there isn’t such an index in the collection.</p>
<p>To get the module, you can also use the CurrentInstance property that returns a System.Collections.SortedList collection: </p>
<pre class=SrcCode><code class=c#>System.Collections.SortedList listOfModules=
AddinExpress.IE.ADXIEModule.CurrentInstance;
</code></pre>
<p>The key in the collection is a thread ID of the add-on. But this collection is not thread-safe, so you’d better use GetModuleByThread and GetModuleByIndex.</p>
<h3>Communicating with IE add-ons in different processes</h3>
<p>In this case, you can’t get a module using GetModuleByThread and GetModuleByIndex, because the modules you need to access are located in another process. But you can use windows messages to communicate between processes. Fortunately, the IE the module contains methods for this task. First, you need to specify message Id constants that identify your messages. For example, consider the following code:</p>
<pre class=SrcCode><code class=c#>// declare the following constants at the module level
private static int WM_USER = 0x0400;
private static int WM_EXAMPLE = WM_USER+1000;
...
// add an event handler to the OnSendMessage event
private void IEModule_OnSendMessage(AddinExpress.IE.ADXIESendMessageEventArgs e)
      {
         if (e.Message == WM_EXAMPLE)
         {
            System.Windows.Forms.MessageBox.Show(this.ThreadID.ToString());
         }
      }
</code></pre>
<p>When you call one of the SendMessage methods provided by the IE module, the method generates a windows message and puts it to the message queue of the corresponding window. When OS permits, the message will be processed and the IE module will generate the OnSendMessage event. The code above produces a message box for each IE module that is run on the PC. </p>
<p>There are some forms of SendMessage methods:</p>
<p>&nbsp;-&nbsp;&nbsp;public void SendMessage(int message, IntPtr wParam, IntPtr lParam);</p>
<p>It sends a custom message to the internal window of Internet Explorer. When the message is received, the Add-in Module raises the OnSendMessage event.</p>
<p>&nbsp;-&nbsp;&nbsp;public void SendMessageToAll(int message, IntPtr wParam, IntPtr lParam);</p>
<p>It sends a custom message to the all windows of Internet Explorer. When the message is received, the Add-in Module raises the OnSendMessage event.</p>
<p>&nbsp;-&nbsp;&nbsp;public void SendMessageToInstance(IntPtr nativeHandle, int message, IntPtr wParam, IntPtr lParam);</p>
<p>Sends a custom message to the specified window of IE. When the message is received, the Add-in Module raises the OnSendMessage event.</p>
<p>       Which of the above methods to use? It depends. When I was programming <a href="http://www.add-in-express.com/products/internet-explorer-search.php">the Advanced Search for Internet Explorer plug-in</a> I had to report to other add-on instances that the current instance (the current thread of execution, which may be a tab or a window) was closing in order to update the Search Results tree. The solution is to use the SendMessageToAll method and the OnSendMessage event handler. It is a non-trivial event for IE add-ons, to trigger which you need to call one of the functions specified above. To handle this event you just need to monitor the id of the message in the OnSendMessage event handler of the add-on module.</p>
<h3>Tips on how to program IE plug-ins</h3>
<p><strong>To show a tab.</strong> Sometimes you need to activate a tab in an IE window. For example, in the Advanced Search add-on, when you press on the tree node to highlight the found element, you are taken to the tab that the element belongs to. In this case, the add-in finds the module of the tab that should be activated, and calls the TabActivate method that activates the tab.</p>
<p><strong>To show an IE toolbar programmatically.</strong> Let&#8217;s assume that you added a toolbar item to the IE add-on project and named it “MyIEToolBar1” .The following code shows / hides the toolbar. In particular, you can use such code, for example, in the event handler of your custom keyboard shortcut.</p>
<pre class=SrcCode><code class=c#>     // getting the add-on module by thread ID
     IEModule module = AddinExpress.IE.ADXIEModule.CurrentInstance[this.ThreadID] as IEModule;
            if (module != null)
            {
		 // getting the toolbar type
                Type t = typeof(MyIEToolBar1);
                int index = module.ToolBars.IndexOf(t.FullName);
                if (index >= 0)
                {
		     // getting an instace of the toolbar by index
                    AddinExpress.IE.ADXIEToolBarItem item = module.ToolBars[index];
                    object g = t.GUID.ToString(&quot;B&quot;);
                    object dummy = null;
                    if (item.ToolBarObj == null)
                    {
                        object bShow = true;
		         // showing the IE toolbar
                        IEApp.ShowBrowserBar(ref g, ref bShow, ref dummy);
                    }
                    else
                    {
                        MyIEToolBar1 dm = item.ToolBarObj as MyIEToolBar1;
                        if (dm != null)
                        {
                            if (!dm.Visible)
                            {
                                object bShow = true;
				  // showing the IE toolbar
                                IEApp.ShowBrowserBar(ref g, ref bShow, ref dummy);
                            }
                            else
                            {
                                object bShow = false;
			          // hiding the IE toolbar
                                IEApp.ShowBrowserBar(ref g, ref bShow, ref dummy);
                            }
                        }
                    }
                }
     }
</code></pre>
<p>It&#8217;s easy to change the code above in order to show / hide an IE bar: you just need to replace the types of the module and toolbar / bar with those that you have in your add-on. Also use the Bars collection instead of Toolbars.</p>
<p>All the sources above belong to the Advanced Search for Internet Explorer (you can download it <a href="http://www.add-in-express.com/downloads/mapi-store-events.php">here</a>) and to other samples distributed with <a href="http://www.add-in-express.com/programming-internet-explorer/">Add-in Express for Internet Explorer</a>. </p>
<p>Eugene Astafiev<br />
Add-in Express Team</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2008/03/14/ie-addons-toolbars-menus-programming/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Windows Installer Error 2908 when installing bulky setup projects</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2007/11/12/windows-installer-error-2908/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2007/11/12/windows-installer-error-2908/#comments</comments>
		<pubDate>Mon, 12 Nov 2007 14:20:55 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=27</guid>
		<description><![CDATA[You created an MSI-based setup project, say in Visual Studio, installed it on the customer PC, and it resulted in Error 2908. In this post you will find a workaround for this scenario.  ]]></description>
			<content:encoded><![CDATA[<p>On one of our test PC (a virtual one) with VS 2008 Beta2 installed, we got the following problem. If any of <a href="http://www.add-in-express.com/add-in-net/">Add-in Express for .NET</a> product packages are installed, uninstalled and re-installed for the second time, the &#8220;Error 2908&#8243; message is shown a tremendous number of times. It is obvious that the message is shown for every file included into the package. What is worse, when the setup program is complete, you get this error again when you install or uninstall any MSI-based product. That is, from the common point of view, Windows becomes inoperable. <a href="http://msdn2.microsoft.com/en-us/library/aa372835.aspx">Windows Installer Error Messages</a> doesn&#8217;t provide any useful info. </p>
<p>If you google for &#8220;Error 2908&#8243;, you&#8217;ll find out that this error occurs for a number of applications. Workarounds exist for installing Office 2000 on Windows 98 or ME, NET Framework 1.1, Visual Studio 2005. But none of those workarounds worked for us. </p>
<p>Then we found an interesting post on the <a href="http://www.eggheadcafe.com/software/aspnet/29115424/2908-installer-error.aspx">www.eggheadcafe.com forum</a>: they added Crystal Reports merge modules to their setup and got this error. This resulted in &#8220;reinstalling windows on computers affected with this error.&#8221; What Microsoft suggested is &#8220;ask Business Objects company that produces the Crystal Report for assistance&#8221;. As you may assume, Crystal Reports supporters <a href="http://diamond.businessobjects.com/node/1044">sent poor devils back to Microsoft</a>. </p>
<p>However, we googled out some vague notes that the cause of this error may relate to the number of files included into the package. This was somehow backed up by Orca that reported the following incomprehensible warning message: Feature &#8216;DefaultFeature&#8217; has XXXX components. This could cause problems on Win9X systems. You should try to have fewer than 817 components per feature.</p>
<p>To verify this assumption, we created a simple setup with some 2000 files. Nevertheless, this setup program has run through the install/uninstall/install procedure successfully. But when we added a custom action (Install, Rollback, and Uninstall), we got Error 2098 again. Moreover, it turned out that install/uninstall is enough for breaking the Windows Installer down. Then we found that the number of files that does the trick lies between 1000 and 1022. We don&#8217;t know if this number depends on the number of custom actions.</p>
<p>This research forced us to decrease the number of Add-in Express files by moving demo projects to a ZIP archive. And in this way, we overpowered Error 2908. </p>
<p>But this was not the end of the story. We felt obliged to find a way for our customers to restore their PCs if they have got into this trap by installing Add-in Express.</p>
<p>The solution was found by a pure chance. Thank Heavens. </p>
<p>Deleting the following key restores the functionality of the Windows Installer: </p>
<pre class=SrcCode><code class=vb>
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
Installer\UserData\S-1-5-21-1123561945-1935655697-1060284298-1003\
Components\AD95649F068525549B26938D7D18FEA7
</code></pre>
<p>We don&#8217;t know who created this key: repairing Office and all .NET Framework versions on that PC doesn&#8217;t restore the key. Currently, we believe this key is created by Visual Studio 2008 Beta 2. We don&#8217;t know what impact the deletion of this key may have on any software on that PC. </p>
<p>What makes us think the key is suspicious? The registry contains the following branches:<br />
<img src="/creating-addins-blog/wp-upload/registryinstaller.jpg" width="539" height="231" alt=" The Installer-UserData registry branches." /></p>
<p>Further on, I will refer to branch S-1-5-18 as ShortSID and S-1-5-21-1409082233-343818398-725345543-1004 as LongSID.</p>
<p>Our experiments showed that products installed for all users fall into the ShortSID/Products branch. Accordingly, products installed for the current user only, fall into the LongSID/Products branch. For every file in the setup project, we got an entry in the Components branch. This entry contains a registry value whose name refers to the product&#8217;s entry in the Products branch. Hope this makes sense :)</p>
<p>The key mentioned above looks suspicious for the following reasons:<br />
Firstly, it is located in the LongSID/Components branch (the registry value is (B3414A45B4B628042B8446B35265C1BC), but, in the LongSID/Products branch, there is no corresponding product.</p>
<p>Secondly, the value of this registry value contains a question mark instead of a colon in the path: C?\WINDOWS\system32\rgb9rast_2.dll<br />
<img src='/creating-addins-blog/wp-upload/error2008key.gif' alt="The registry key that causes Error 2908." /><br />
 We tried deleting this key and it helped. Finally, we tried creating this key on a clean PC and reproduced Error 2908 with our test setup project. </p>
<p><strong>Conclusions:</strong><br />
1. It required 3 days X 4 developers to fix the problem that, as we know for sure, was not engendered by us.<br />
2. Any developer can create a setup project that may make Windows practically inoperable.<br />
3. This developer will be blamed for no reasons.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2007/11/12/windows-installer-error-2908/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Bypass Outlook security warnings when sending email messages in MS Access</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2007/09/12/disable-outlook-security-warnings-sending-email-messages-in-access/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2007/09/12/disable-outlook-security-warnings-sending-email-messages-in-access/#comments</comments>
		<pubDate>Wed, 12 Sep 2007 17:20:27 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Outlook]]></category>

		<category><![CDATA[Outlook security]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=25</guid>
		<description><![CDATA[Whenever you send e-mail messages in Microsoft Access, you get Outlook security warnings like “A program is trying to automatically send email…”. To get rid of such security prompts, use the Outlook Security Manager. With the ActiveX edition of this component you need just a few lines of code to switch the Outlook security off and on.]]></description>
			<content:encoded><![CDATA[<p>Whenever you send e-mail messages in Microsoft Access, you get Outlook security warnings like <a href="http://www.add-in-express.com/docs/outlook-security-manager-automate.php">A program is trying to automatically send email</a>…:</p>
<p><img src="/creating-addins-blog/wp-upload/aprogramistrying.gif" width="359" height="190" alt="A program is trying to automatically send email on your behalf." /> </p>
<p>To get rid of such security warning messages, use the <a href="http://www.add-in-express.com/outlook-security/">Outlook Security Manager</a> that effectively disables / enables the Outlook Security. With the ActiveX edition of this product you can easily switch the Outlook security off and on. Here we describe two methods of sending emails in Microsoft Access using the ActiveX edition of Outlook Security Manager.</p>
<h3>Sending emails using the DoCmd. SendObject method</h3>
<p>With the ActiveX edition of Outlook Security Manager you write the following simple code:</p>
<pre class=SrcCode><code class=vb>
Sub SendEmailMessageViaDoCmd()
Dim SecurityManager As Object
  Set SecurityManager = CreateObject(&quot;AddInExpress.OutlookSecurityManager&quot;)
  SecurityManager.DisableSMAPIWarnings = True
  On Error GoTo Finally
  DoCmd.SendObject acSendNoObject, , ,&quot;user@server.com&quot;, , , _
  &quot;Message subject&quot;, &quot;Message body&quot;, False
Finally:
  SecurityManager.DisableSMAPIWarnings = False
  Set SecurityManager = Nothing
End Sub</code></pre>
<p><strong>What does this procedure do?</strong></p>
<p>At first, the Outlook Security Manager object is declared and created. Then DisableSMAPIWarnings of this object is set to true. At this moment the Outlook Security Manager disables security warnings from the so-called Simple MAPI email processing protocol, which is used whenever an email is being sent. Then your familiar DoCmd creates and sends your e-mail. And finally, DisableSMAPIWarnings is set to False, enabling security warnings from Simple MAPI. Note, this last step is important, because if you fail to re-enable the Simple MAPI Security, some other MDB or ADP opened in this MS Access session can potentially do some harm to you.</p>
<h3>Sending emails using Outlook Object Model</h3>
<p>With the ActiveX edition of Outlook Security Manager you send emails in the following way:</p>
<pre class=SrcCode><code class=vb>
Sub SendEmailMessageViaOutlookObjectModel()
Dim olApp As Outlook.Application
  Set olApp = New Outlook.Application 'GetObject(,&quot;Outlook.Application&quot;)
Dim email As Outlook.MailItem
  Set email = olApp.CreateItem(olMailItem)

Dim SecurityManager As Object
  Set SecurityManager = CreateObject(&quot;AddInExpress.OutlookSecurityManager&quot;)
  SecurityManager.ConnectTo olApp
  SecurityManager.DisableOOMWarnings = True
  On Error GoTo Finally
  email.Recipients.Add &quot;user@server.com&quot;
  email.Subject = &quot;Message subject&quot;
  email.Body = &quot;Message body&quot;
  email.Send
Finally:
  SecurityManager.DisableOOMWarnings = False
  Set SecurityManager = Nothing
  Set email = Nothing
  Set olApp = Nothing
End Sub
</code></pre>
<p><strong>How does this procedure work?</strong></p>
<p>First off, you get the Outlook.Application object and the MailItem object (the last one represents an email in Outlook). Then you create the Outlook Security Manager object and connect it to the Outlook application. Then the DisableOOMWarnings of the Outlook Security object is set to true. The &#8216;OOM&#8217; part in the property name stands for &#8220;Outlook Object Model&#8221;. At this moment the Outlook Security Manager disables Outlook Security prompts. Then you set the email properties, such as, Subject, Body, add email addresses to the Recipients collection and send the email. And finally, DisableOOMWarnings is set to False, enabling Outlook Security. Note, this last step is highly important, because in the other case you can leave your Outlook unprotected from really malicious software. Sure, it is not what you really want. That&#8217;s all for now. Hope this helps.</p>
<p>Andrei Smolin<br />
Add-in Express Team Leader</p>
<h3>Related posts:</h3>
<p><a href="http://www.add-in-express.com/creating-addins-blog/2006/08/17/outlook-not-closing/">Why Outlook is not closing when I run my add-in?</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2007/09/12/disable-outlook-security-warnings-sending-email-messages-in-access/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Create Office add-ins: ribbons, toolbars, task panes, menus etc.</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2007/07/04/create-office-addins-ribbons-toolbars-task-panes-menus/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2007/07/04/create-office-addins-ribbons-toolbars-task-panes-menus/#comments</comments>
		<pubDate>Wed, 04 Jul 2007 11:44:21 +0000</pubDate>
		<dc:creator>Andrei Smolin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[COM add-ins]]></category>

		<category><![CDATA[Office]]></category>

		<category><![CDATA[Office 2007 Ribbon]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=24</guid>
		<description><![CDATA[How to get started with COM add-ins for Microsoft Office 2007 – 2000. Learn about object models, typical issues with Office add-ins, add-in deployment, shims, ClickOnce and more.]]></description>
			<content:encoded><![CDATA[<p>Starting from version 2000, Office applications allow COM add-ins to customize their user interface with toolbars, menus, context menus, ribbons, task panes etc. COM add-ins run within the process of their host application and use programmatic interfaces provided by the host in order to access currently open documents and modify their contents or react to user actions. Naturally, to be executed in this way add-ins should conform to some rules. </p>
<p>For the .NET developer, Office add-ins are class libraries implementing the IDTExtensibility2 COM interface and registered in an appropriate registry branch in HKEY_CURRENT_USER. To run for all users on the current PC, Office COM add-ins must be registered in HKEY_LOCAL_MACHINE. Obviously, this requires administrative privileges.</p>
<p><img src="/creating-addins-blog/wp-upload/addinsregistry.gif" width="411" height="386" alt="Office add-ins in the registry" /></p>
<p>A number of other COM interfaces require implementation if your add-in <a href="http://www.add-in-express.com/add-in-net/modules.php#ribbon">customizes the Office 2007 Ribbon user interface</a> (IRibbonExtesibility), creates <a href="http://www.add-in-express.com/docs/net-custom-task-panes.php">custom task panes</a> (ICustomTaskPaneConsumer), and so on. The user is allowed to <a href="http://www.add-in-express.com/forum/read.php?FID=5&#038;TID=1094">enable or disable COM add-ins via COM Add-ins dialog</a>:</p>
<p><img src="/creating-addins-blog/wp-upload/comaddinsdialog.gif" width="468" height="252" alt="COM Add-ins dialog" /></p>
<p>How to start writing add-ins for Microsoft Office? What problems should you be aware of? How do you deploy the add-in? What tools are available?</p>
<h3>Is it possible to write an Office add-in that will fulfill my task?</h3>
<p>First off, you are to find out if the Office application you want to use as a host for your add-in provides the features you need. Here is one of the most frequently asked questions on the <a href="http://www.add-in-express.com/forum/">Add-in Express forum</a>: Is it possible to add a custom page to the Tools | Options dialog in Excel? Our standard answer is: It is not possible because the Excel Object Model doesn&#8217;t provide any way for this. </p>
<p>However, where does an object model live? The best way to study any Office Object model is the Object browser available in the Visual Basic IDE. Having run the host application, you open the environment by choosing the Tools / Macro / Visual Basic Editor menu item or by pressing Alt + F11. Note that some Office applications, recent ones mainly, do not provide IDE. If it is the case, please refer to Programmer&#8217;s Reference or MSDN.</p>
<p>When in the IDE, you choose View / Object Browser in the menu or press F2. The Object Browser provides you with public classes, their properties and methods as well as with public enumerations for all object models that the currently open document refers to (use Tools | References to add a new reference). You can restrict the browser to show the public interfaces of a single object model: use the topmost combo to select, say Outlook, Word, Excel, or MSProject. The Object browser allows searching through any or all object models. There is a restriction though: it doesn&#8217;t search through a method&#8217;s parameters. When you find an object of interest, you click it and press F1 to get the help article related to this object. Those help articles are the shortest way to understanding of the object model. </p>
<p> <img src="/creating-addins-blog/wp-upload/wordobjectbrowser.gif" width="559" height="324" alt="Object Browser in Office VB IDE" /></p>
<p>The Object Browser reveals all the declarations in VBA syntax. If you have no or little experience in VB6 (VBA) programming, please note that some declarations don&#8217;t specify the types of parameters and/or return values. Consider the following declaration in the Word object model – note that this pattern is often used in other object models:</p>
<p><code>Function Item(Index) As Bookmark</code></p>
<p>It defines the Item function which returns a value of the Bookmark type. However, the declaration doesn&#8217;t reveal the type of the Index parameter. In such situations you should know that the Browser omits the Variant keyword. That is, the declaration above should read as follows:</p>
<p><code>Function Item(Index as Variant) As Bookmark</code></p>
<p>The Variant data type is a predecessor of the Object data type in .NET programming. Like Object variables, Variant variables can accept almost any data types. When you click the function above and press F1, it appears that the Index parameter can accept numeric and string values – either the index position of the Bookmark in the Bookmarks collection or a bookmark&#8217;s name. </p>
<p>I understand that you may never have used (and will probably never use) VBA. However, I insist on using the Object Browser: it is the essential step of getting into the insight of the Object Model of any Office application.</p>
<p>To understand <b>user interface</b> options, you select Office in the topmost combo of the Object Browser. Here you find definitions of the types that all Office applications share: COM add-ins, command bars and controls, custom task panes, ribbons, etc.</p>
<h3>What are the typical problems with Office add-ins?</h3>
<p>If you&#8217;ve never done Office development before, you’ll be in a shock because while the user&#8217;s side of any Office application is remarkably stable and robust, the application&#8217;s object model is a completely different story. It’s like a minefield of bugs and issues: command bars behave differently in different Office applications or become disconnected suddenly, Outlook hangs in the Task Manager or doesn&#8217;t fire the events you rely upon, Office updates change the sequence of events, and many, many more. All this stuff increases the debugging time considerably.</p>
<p>Many problems arise on the .NET – COM interaction area because .NET and COM differ in their strategies of object releasing. Blogs and newsgroups have a great number of questions like &#8220;<a href="http://www.add-in-express.com/creating-addins-blog/2006/08/17/outlook-not-closing/">Why Outlook is not closing?</a>&#8220;. The problem has its name: Releasing COM objects in .NET. When releasing COM objects in a stand-alone .NET application, you are free to use any of the three approaches discussed by Andrew Whitechapel. Please note, these approaches are applied to standalone applications but not to add-ins.  I&#8217;ll try to prepare some add-ins demonstrating the problems with using the approaches described in Andrew Whitechapel&#8217;s book. To make a long story short, COM add-ins developers have the only way. I&#8217;d call it the Bee Way: whenever you get a reference to a COM object, you must release it using the Marshal.ReleaseComObject method. You may think this will bloat your code sufficiently. However, this is the right way: you keep every aspect of your add-in under control. Here, at Add-in Express, we have a saying: Office overlooks mistakes for a very short period only.</p>
<h3>Add-in deployment</h3>
<p>The crucial question is: who will install your add-in? There are two possible answers: an admin or a standard user. If the admin installs your add-in, you have no problems when, say, your add-in requires to install its prerequisites. Note that some prerequisites are absolute musts: .NET Framework :), Windows Installer 3.1, Shared Add-in Support Update for Microsoft .NET Framework 2.0 (KB908002). </p>
<p>However, administrators are not inclined to participate in the add-in installation process: you can easily imagine installing an add-in on some two hundred PCs. In short, it is unpleasant for all sides of the process (you, the admin, and the user) to get the admin involved. The best practice is installing with non-admin permissions. To create such a setup you should know if the non-admin user has access rights to this or that folder / registry branch. Say, a standard user does not have access rights to Program Files and HKEY_LOCAL_MACHINE. If you know this, you target your setup project to the Application Data folder and HKEY_CURRENT_USER. In addition, you drop from your package every prerequisite that requires admin rights for installation.</p>
<p>The &#8220;non-administrative installation&#8221; theme has received its continuation in <a href="http://www.add-in-express.com/docs/net-clickonce.php">ClickOnce</a> - a deployment technology introduced in .NET Framework 2.0. The name suggests that you can install some software in several clicks (let&#8217;s not waste time on trifles). When asked if COM add-ins can be installed with ClickOnce, Microsoft says no. Nevertheless, some clever guys in Add-in Express have found <a href="http://www.add-in-express.com/docs/net-clickonce-solution.php">their own ClickOnce solution</a>.</p>
<h3>What are the tools?</h3>
<p>You can create managed COM add-in using the following tools:</p>
<li>Visual Studio 2003 &#038; 2005 Shared Add-in Project Template </li>
<li>VSTO 2005 or VSTO 2005 SE</li>
<li>Visual Studio 2003 &#038; 2005 with <a href="http://www.add-in-express.com/add-in-net/">Add-in Express 2007 for Microsoft .NET</a>.</li>
<p>Every tool differs in the functionality it provides as well as in the shim it uses. </p>
<p><b>Shims</b> are unmanaged DLLs used to make Office load managed code. When you register your unmanaged add-in, the shim info gets written to the registry (instead of targeting the add-in assembly) for Office to load the shim whenever the add-in is to be loaded. Thus, the shim becomes an essential part of the add-in development in .NET since it: </p>
<li>Loads the CLR</li>
<li>Сreates an AppDomain for your add-in </li>
<li>Сreates and caches instances of the managed COM add-in classes </li>
<li>Redirects calls made into unmanaged classes to their managed counterparts</li>
<p><b>Shim comparison</b>.  Shared Add-ins are based on the universal shim installed with .NET Framework. It is called MSCOREE.DLL. VSTO add-ins are based on the VSTO Loader which is installed as part of VSTO run-time. The <a href="http://www.add-in-express.com/docs/net-deploying-addins.php">Add-in Express Loader</a> is a custom shim that you install as part of your add-in installation. The Add-in Express Loader is configured via a manifest, it runs HKCU and HKLM targeted add-ins; it provides you with logging and allows installing the add-in when the previous version is being run. Also, note that Add-in Express supports the above-mentioned shims too. FYI, MSCOREE.DLL loads all Shared add-ins to the same AppDomain and in this way, one add-in can impede the work of other add-ins. In addition, you cannot sign it. </p>
<p><b>Office applications supported</b>.  All of the tools above support a number of Office applications. However, Shared Add-in and Add-in Express provide support for a broad set of Office applications (all Office versions), while VSTO confines itself to add-ins for Outlook 2003 only, and VSTO SE allows creating add-ins for 2003-2007 versions of Outlook, Excel, Word, PowerPoint, Visio, and for InfoPath 2007. </p>
<p><b>Office versions</b>.  Every tool allows developing for the currently installed Office version. Note, that every add-in developed for a given Office version will work for higher versions (with few exceptions). However, if you develop an add-in for Office 2003 in VSTO (VSTO SE), you will have to create another version of your add-in to access the features of Office 2007. Add-in Express provides Office 2000 interop assemblies. Thus, it makes possible to develop add-ins for Office 2000 no matter what Office version is installed on your development PC. What is more, your plug-ins developed with Add-in Express are <a href="http://www.add-in-express.com/add-in-net/wizards.php">version-independent</a>, i.e. you write your code once and have the add-in work in all Office versions.</p>
<p><b>Setup</b>.  All of the tools above create an appropriate setup project automatically. However, with VSTO (VSTO SE) you will need to create custom actions for your add-in to get registered in .NET configs. With both VSTO and Shared Add-in you will have to configure your setup manually in order to allow non-admin installations. Note that Add-in Express simplifies and speeds up this part of add-in development: it allows choosing the installation type and provides ready-to-use custom actions.</p>
<p><b>ClickOnce</b>.  Shared Add-in doesn&#8217;t provide it. And as I pointed above, the VSTO ClickOnce wizard will not allow installing add-ins via ClickOnce. Add-in Express offers <a href="http://www.add-in-express.com/docs/net-clickonce-solution.php">ClickOnce Solution</a> that allows the end-user to install and update the add-in without the admin involved.</p>
<p><b>Development speed vs. flexibility</b>.  Shared Add-in and VSTO allow using all available Office interfaces and leave you face to face with them. The current Add-in Express version supports main interfaces only: COM add-in, Ribbon UI, and Custom Task Panes. To speed up the development, it provides components that solve typical problems of creating and using command bars (<a href="http://www.add-in-express.com/add-in-net/components.php">toolbars, menus, and context menus</a>) and controls, <a href="http://www.add-in-express.com/docs/net-components.php#Ribbon components">Ribbon tabs</a>, Office 2007 Menu, <a href="http://www.add-in-express.com/add-in-net/office-2007.php#quickaccess">Quick Access Toolbar</a>, <a href="http://www.add-in-express.com/docs/net-custom-task-panes.php">custom task panes</a>, <a href="http://www.add-in-express.com/add-in-vsto/task-pane.php#shortcuts">keyboard shortcuts</a>, as well as a number of <a href="http://www.add-in-express.com/add-in-net/programming-outlook.php">Outlook–oriented components</a>: <a href="http://www.add-in-express.com/add-in-net/programming-outlook.php#ribbons">Explorer and Inspector command bars</a>, Outlook Bar shortcuts, and property pages for the Tools | Options and Folder Properties dialogs. In addition, Add-in Express provides unique plug-ins that allow <a href="http://www.add-in-express.com/outlook-extension/">embedding custom .NET forms into Outlook windows</a> and <a href="http://www.add-in-express.com/office-toolbar-controls/">custom .NET controls into Office toolbars</a>.</p>
<h3>Conclusion</h3>
<p>Of course, I&#8217;m a bit biased. Nevertheless, if I just say that I love <a href="http://www.add-in-express.com/add-in-net/">Add-in Express for .NET</a>, it will be close to nothing. Add-in Express allows me to create the user interface of my add-in in minutes. I never spend too much time to create an Outlook Explorer command bar: I drop a component on the AddinModule and specify its properties (its name is the most essential one) and events. To create a task pane, I just add a UserControl to my project and bind it to the TaskPanes collection of the AddinModule using a combo box. And so on, and so forth. The development speed on this stage is beyond any expectations. I used to program add-ins in VB 6 and I say: I could not even imagine that such things are possible.<br />
Well, of course, it is possible to live without Add-in Express: you can google out many useful things about command bars and their oddities when using them in some Office applications. You can also find many interesting things about this or that situation with this or that Office application. Just think of the time you will waste if using the “make-it-yourself” scenario. Say, it is easy to add a command bar in Outlook explorer window (list of mails). However, you will have to foresee the command bar&#8217;s behavior in multi-explorer and no-explorer scenarios (when Outlook is run via Automation). Then you&#8217;ll find that the command bar (and custom controls) can become disconnected spontaneously. Then you will have to debug it in all Outlook versions you plan to support. Isn&#8217;t it too much work for just to show a command bar? </p>
<p><b>Support</b>.  Support is an integral part of all Add-in Express product packages. I guess you’d better see customers&#8217; opinions yourself. Try to search for the following through the currently available posts on our forums:</p>
<li>Search for <a href="http://www.add-in-express.com/search-addin.php?q=%28excellent+or+great%29+support&#038;where=forum">excellent or great support</a></li>
<li>Search for <a href="http://www.add-in-express.com/search-addin.php?q=%28fast+or+quick+or+speedy%29+%28support+or+response%29&#038;where=forum">fast, quick or speedy support or response</a></li>
<li>Search for <a href="http://www.add-in-express.com/search-addin.php?q=%22next+release%22+or+%22next+build%22&#038;where=forum">next release or next build</a></li>
<p>A couple of useful links:</p>
<p><a href="http://msdn2.microsoft.com/en-us/library/aa679806(office.11).aspx">Andrew Whitechapel. Microsoft .NET Development for Microsoft Office. Selected chapters</a><br />
<a href="http://blogs.msdn.com/omars/archive/2004/12/07/276136.aspx">When ReleaseComObject is necessary in Outlook</a><br />
<a href="http://msdn2.microsoft.com/en-us/library/extensibility.idtextensibility2(VS.80).aspx">IDTExtensibility2 Interface</a><br />
<a href="http://msdn2.microsoft.com/en-us/library/Aa433868.aspx">IRibbonExtensibility</a><a href="http://msdn2.microsoft.com/en-us/library/aa679806(office.11).aspx"><br />
</a><a href="http://windowsclient.net/blogs/faqs/archive/2004/06/11/can-i-use-clickonce-to-deploy-an-office-addin.aspx">Microsoft: It is impossible to use ClickOnce for Office add-in deployment</a><br />
<a href="http://msdn2.microsoft.com/en-us/library/aa164016(office.10).aspx">Deployment of Managed COM Add-Ins in Office XP</a> (contains additional info on shims)</p>
<p>Regards from Belarus,</p>
<p>Andrei Smolin<br />
Add-in Express Team Leader</p>
<h3>Related posts:</h3>
<p><a href="http://www.add-in-express.com/creating-addins-blog/2007/04/30/customize-office-toolbars-ribbons-task-panes-on-ro-chrome/ ">Customize Office toolbars, ribbons, task panes on RO Chrome</a><br /><a href="http://www.add-in-express.com/creating-addins-blog/2008/03/14/office-2007-ribbon-ui/">Make the Office 2007 Ribbon work easy</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2007/07/04/create-office-addins-ribbons-toolbars-task-panes-menus/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Customize Office toolbars, ribbons, task panes on RO Chrome</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2007/04/30/customize-office-toolbars-ribbons-task-panes-on-ro-chrome/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2007/04/30/customize-office-toolbars-ribbons-task-panes-on-ro-chrome/#comments</comments>
		<pubDate>Mon, 30 Apr 2007 13:21:04 +0000</pubDate>
		<dc:creator>Eugene Starostin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[COM add-ins]]></category>

		<category><![CDATA[Office]]></category>

		<category><![CDATA[Office 2007 Ribbon]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=23</guid>
		<description><![CDATA[Special components for Office 2000 – 2007 customization. Customize the Office UI including toolbars, menus, sub-menus, ribbons, task panes and property pages.]]></description>
			<content:encoded><![CDATA[<p>This post is the third part of my RemObjects Chrome and Add-in Express series. In part one I highlighted the key features of <a href="http://www.add-in-express.com/">Add-in Express</a> and showed how <a href="http://www.add-in-express.com/creating-addins-blog/2007/04/24/create-microsoft-office-extensions-using-ro-chrome/">to get started with Outlook COM add-ins on RemObjects Chrome </a> and Add-in Express. In part two, I explored such crucial for Office development concepts as <a href="http://www.add-in-express.com/creating-addins-blog/2007/04/25/office-plugins-chrome/">security and deployment, RAD modules and visual designers</a> . Today, in the final post of this series, I&#8217;ll dwell on the most important fields of Office customization: creating custom toolbars for traditional Office 2000 – 2007 user interface, customizing Ribbon UI in Office 2007 and adding application-level keyboard shortcuts.</p>
<h3>Customizing Office</h3>
<p>Due to the Microsoft Office extensibility and Add-in Express components you can customize the Office UI including toolbars, menus, sub-menus, ribbons, task panes and property pages. In this example I describe three most important fields of Office customization - extending the Office UI, accessing Office objects and handling their events.</p>
<p><strong>Creating custom toolbars for traditional Office 2000 – 2007 UI</strong><br />
With the <a href="/creating-addins-blog/2007/04/25/office-plugins-chrome/#command_bar_components">command bar components</a> described in <a href="/creating-addins-blog/2007/04/25/office-plugins-chrome/">part 2 of my RemObjects Chrome series</a> you can add your own or customize any existing toolbars and menus in your host applications. For example, to add a new toolbar to the Outlook Explorer window, open and right click on the Add-in Designer, and then select the Add Explorer CommandBar item. This adds an adxOlExplorerCommandBar component. Next, select the added component and customize it through the Properties window using the CommandBarName, Position, Protection, UseForRibbon properties. The FolderNames and ItemTypes properties are Outlook-specific; you can use them to bind your toolbar to certain Outlook folders or specified content. For example, select Mail in the ItemTypes property to show your toolbar for mail folders only (see the picture below).</p>
<p><img src="/creating-addins-blog/wp-upload/outlook-explorer-toolbar-props.gif" alt="Specifying Outlook Explorer command bar properties" /></p>
<p>All command bar components have the Controls collection which is a container for controls of you toolbar. Using its designer you can add to your toolbar standard Office toolbar controls such as button, edit and combo boxes, pop-ups, etc. To add a button to the toolbar, select the Controls collection on the Properties window and open its designer. Then, click the Add button, select ADXCommandBarButton and customize it.</p>
<p><img src="/creating-addins-blog/wp-upload/controls-designer.gif" alt="Populating the command bar with controls" /></p>
<p>Then, create an event handler for the button click:</p>
<p><code><br />
method AddinModule.adxCommandBarButton1_Click(sender: System.Object);<br />
var<br />
  MailItem: outlook.MailItem;<br />
begin<br />
    if OutlookApp.ActiveExplorer.Selection.Count > 0 then begin<br />
        MailItem := OutlookApp.ActiveExplorer.Selection.Item(1) as MailItem;<br />
        MessageBox.Show(MailItem.Subject);<br />
    end;<br />
end;<br />
</code></p>
<p>Finally, register your project as an Office add-in.  To do this, select the Register ADX Project item on the Build menu of your Visual Studio, run Outlook and click your button.</p>
<p><strong>Third-party controls on Office toolbars</strong><br />
For Outlook, Excel, Word and PowerPoint you can use any third-party controls on Office toolbars. For example, let&#8217;s add a label that shows the subject of the selected mail.</p>
<p>First, you add to the add-in module a special component that supports third-party controls on Outlook toolbars. It is adxOutlookControlAdapter that you can find on the Toolbox; add it to the Add-in Designer. Next, add a label to the Add-in Designer and customize it through the Properties window.</p>
<p>Then, select your toolbar, open the Controls collection designer, click the Add button, select ADXCommandBarAdvancedControl and select the added label in the Control property.</p>
<p><img src="/creating-addins-blog/wp-upload/controls-designer-adv-control.gif" alt="Adding a custom control to the command bar" /></p>
<p>To show the subject of the selected mail we need to handle the SelectionChange event. To do this, right click on the Add-in Designer, select Add Events, click Outlook Events on the opened window and click OK. This adds the Outlook events component to the Add-in Designer.</p>
<p><img src="/creating-addins-blog/wp-upload/outlook-events.gif" alt="Processing Outlook events" /></p>
<p>Using the Properties window, create an event handler for the ExplorerSelectionChange event:</p>
<p><code><br />
method AddinModule.adxOutlookEvents_ExplorerSelectionChange(sender: System.Object; explorer: System.Object);<br />
var<br />
  MailItem: outlook.MailItem;<br />
begin<br />
    if OutlookApp.ActiveExplorer.Selection.Count > 0 then begin<br />
        MailItem := OutlookApp.ActiveExplorer.Selection.Item(1) as MailItem;<br />
        (Self.adxCommandBarAdvancedControl1.ActiveInstance as Label).Text := MailItem.Subject;<br />
    end;<br />
end;<br />
</code></p>
<p>Finally, rebuild your project, run Outlook and select any mail. If you reproduce the steps above correctly, your label will show the subject of the selected mail item. Please note you needn&#8217;t register your project for the second time.</p>
<p><img src="/creating-addins-blog/wp-upload/outlook1.gif" alt="Your sample Outlook toolbar in action" /></p>
<p><strong>Customizing Office 2007 Ribbon UI</strong><br />
Add-in Express includes special components for the Ribbon UI customization. To create your own ribbon tab, right click on the Add-in Designer and select Add Ribbon Tab. This adds an adxRibbonTab component to the Add-in Designer. Next, name your tab via the Caption property and specify its ribbons via the Ribbons property (for example, select OutlookMailCompose).</p>
<p><img src="/creating-addins-blog/wp-upload/ribbon-tab-properties.gif" alt="Creating a custom Ribbon tab" /></p>
<p>Then, add a group and button to the tab through the Ribbon Tab designer of the Controls collection.</p>
<p><img src="/creating-addins-blog/wp-upload/ribbon-tab-designer.gif" alt="Populating the Ribbon tab" /></p>
<p>Next, handle the click of the button:</p>
<p><code><br />
method AddinModule.adxRibbonButton1_OnClick(sender: System.Object;<br />
    control: AddinExpress.MSO.IRibbonControl; pressed: System.Boolean);<br />
var<br />
    MailItem: outlook.MailItem;<br />
begin<br />
    MailItem := OutlookApp.ActiveInspector.CurrentItem as MailItem;<br />
    if Assigned(MailItem) then<br />
        MailItem.Subject := 'Test';<br />
end;<br />
</code></p>
<p>Finally, rebuild your project, run Outlook, create a new mail and click your button.</p>
<p><strong>Adding application-level keyboard shortcuts</strong><br />
With Add-in Express you can easily create application-level keyboard shortcuts. To do this, click on the Add-in Designer, set its HandleShortcuts property to true, right click on the Add-in Designer and select Add Keyboard Shortcut. An adxKeyboardShortcut will be added to the Add-in Designer. Next, set the shortcut text to the ShortcutText property of the add-in component (Ctrl-Shift-R for this example).</p>
<p><img src="/creating-addins-blog/wp-upload/keyboard-shortcuts.gif" alt="Intercepting a keyboard shortcut" /></p>
<p>Then, handle your shortcut action. In this example we reply to the currently selected mail and initialize its text:</p>
<p><code><br />
method AddinModule.adxKeyboardShortcut1_Action(sender: System.Object);<br />
var<br />
    MailItem: outlook.MailItem;<br />
begin<br />
    if OutlookApp.ActiveExplorer.Selection.Count > 0 then begin<br />
        MailItem := OutlookApp.ActiveExplorer.Selection.Item(1) as MailItem;<br />
        MailItem := MailItem.Reply;<br />
        MailItem.Body := 'Test';<br />
        MailItem.Display(false);<br />
    end;<br />
end;<br />
</code></p>
<p>Finally, rebuild your project, run Outlook and press Ctrl-Shift-R.</p>
<p>In this post I described only some of the features and capabilities that Add-in Express offers for customizing and enhancing your Office applications. To learn about other benefits provided by Add-in Express to .NET developers, visit <a href="http://www.add-in-express.com/add-in-net/">Add-in Express home page</a></p>
<h3>Related posts:</h3>
<p><a href="http://www.add-in-express.com/creating-addins-blog/2008/03/14/office-2007-ribbon-ui/">Make the Office 2007 Ribbon work easy</a><br /><a href="http://www.add-in-express.com/creating-addins-blog/2007/07/04/create-office-addins-ribbons-toolbars-task-panes-menus/">Create Office add-ins: ribbons, toolbars, task panes, menus</a><br /><a href="http://www.add-in-express.com/creating-addins-blog/2007/04/24/create-microsoft-office-extensions-using-ro-chrome/">Create Microsoft Office extensions using RemObjects Chrome</a><br /><a href="http://www.add-in-express.com/creating-addins-blog/2007/04/25/office-plugins-chrome/">Develop MS Office add-ins, smart tags, RTD servers on RO Chrome</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2007/04/30/customize-office-toolbars-ribbons-task-panes-on-ro-chrome/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Develop MS Office add-ins, smart tags, RTD servers on RO Chrome</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2007/04/25/office-plugins-chrome/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2007/04/25/office-plugins-chrome/#comments</comments>
		<pubDate>Wed, 25 Apr 2007 18:41:40 +0000</pubDate>
		<dc:creator>Eugene Starostin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[COM add-ins]]></category>

		<category><![CDATA[Office]]></category>

		<category><![CDATA[Office 2007 Ribbon]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=20</guid>
		<description><![CDATA[Security and deployment, RAD modules and visual designers for Microsoft Office plug-ins. Adding toolbars, customizing Office Ribbon, Quick Access toolbar and Office Menu, creating task panes and more.]]></description>
			<content:encoded><![CDATA[<p>In part one of the Add-in Express and RO Chrome series I explored the idea of <a href="http://www.add-in-express.com/creating-addins-blog/2007/04/24/create-microsoft-office-extensions-using-ro-chrome/">Office application-level extensibility</a>, highlighted the key features of <a href="http://www.add-in-express.com/add-in-net/">Add-in Express</a> and showed how to get started with Outlook COM add-ins on RemObjects Chrome and Add-in Express. In part two, I&#8217;ll dig deeper into the concepts that are crucial for Office development and will speak about security and deployment, RAD modules and visual designers.</p>
<h3>The inside of your Office solution</h3>
<p>By default, every Office solution (either <a href="http://www.add-in-express.com/add-in-net/com-addins.php">COM add-in</a>, <a href="http://www.add-in-express.com/add-in-net/excel-rtd-servers.php">RTD server</a>, <a href="http://www.add-in-express.com/add-in-net/smart-tags.php">smart tag</a> or UDF) based on Add-in Express includes two projects: the main project and a setup project. The first project is your extension itself, the second one you use to deploy the extension. Both projects include all necessary references and dependencies.</p>
<p><img src="/creating-addins-blog/wp-upload/solution-explorer.gif" alt="Add-in Express project" /></p>
<p><strong>Security and deployment</strong><br />
Every solution based on Add-in Express templates is secure and deployable. Firstly, Add-in Express isolates your solution in its own AppDomain by a custom shim, the <a href="http://www.add-in-express.com/docs/net-deploying-addins.php#loader">Add-in Express Loader</a>, included in the setup project. The loader gives you the ability to update your add-in on the fly which makes deployment and redeployment very comfortable for your administrators. Secondly, the loader acts in accordance with the strict Office security model, so your Office add-ins run under the High Security setting.</p>
<p><strong>RAD modules</strong><br />
Each of your solutions includes a special RAD module (AddinModule.pas in this example) which is the &#8220;heart&#8221; of your project. It is an analog of the <strong>Data Module</strong> in Borland Delphi that has its own visual designer. This module is a container for all Office-specific components and provides &#8220;access points&#8221; for handling Office objects. Thus, the RAD module is the place where your write your applied code.</p>
<p>In this example, the AddinModule class uses all necessary namespaces including AddinExpress.MSO. It is a descendant of ADXAddinModule and it implements several methods and properties (see the listing below; some insignificant code pieces are skipped).</p>
<p><code><br />
namespace MyFirstOutlookAddin;</p>
<p>interface</p>
<p>uses<br />
  AddinExpress.MSO;</p>
<p>type</p>
<p>  [GuidAttribute('6B9D2084-1414-4054-ADBD-26840BCE3DD6'), ProgId('MyFirstOutlookAddin.AddinModule')]<br />
  AddinModule = public class(AddinExpress.MSO.ADXAddinModule)<br />
  public<br />
    constructor;</p>
<p>    [ComRegisterFunctionAttribute]<br />
    class procedure AddinRegister(t: System.Type);<br />
    [ComUnregisterFunctionAttribute]<br />
    class procedure AddinUnregister(t: System.Type);<br />
    method UninstallControls(); override;</p>
<p>    property OutlookApp: outlook._Application read self.HostApplication as outlook._Application;<br />
  end;</p>
<p>implementation</p>
<p>constructor AddinModule;<br />
begin<br />
  InitializeComponent();<br />
end;</p>
<p>{$REGION Component Designer generated code}<br />
/// Required by designer support - do not modify the following method<br />
method AddinModule.InitializeComponent;<br />
begin<br />
  self.AddinName := 'MyFirstOutlookAddin';<br />
  self.SupportedApps := (AddinExpress.MSO.ADXOfficeHostApp.ohaOutlook);<br />
end;<br />
{$ENDREGION}</p>
<p>end.<br />
</code></p>
<p><strong>The concept of designers</strong><br />
Open the Solution Explorer windows and click on AddinModule. You will see the Add-in Designer. As described above, it is a container for any components including Office-specific components delivered with Add-in Express. You can add any components from the Toolbox to the module, however Office-specific ones can be added only by the designer commands available by the right click of the mouse. You can add the following Office-specific components (see the picture below or right click on the Add-in Designer):</p>
<ul>
<li><strong><a name="command_bar_components">Command bar</a></strong> – adds a new or customizes any existing toolbars of any Office applications.
</li>
<li><strong>Outlook Explorer and Inspector command bar</strong> – used to create new or change any existing toolbars on the Outlook Explorer and Inspector windows.
</li>
<li><strong>Built-in control connector</strong> – use it to intercept any ID-based control built in Office applications; for example, to handle the Save menu item in Word or the Send button in Outlook.
</li>
<li><strong>Keyboard shortcut</strong> – provides the application-level keyboard shortcut; e.g. pressing Ctrl-Alt-S in Excel or Ctrl-F in PowerPoint.
</li>
<li><strong>Outlook Bar shortcut manager</strong> – use it to create your own set of shortcuts on the Navigation Pane of Outlook.
</li>
<li><strong>Ribbon tab</strong> – allows creating a new or customizing an existing tab on the ribbon context.
</li>
<li><strong>Ribbon Quick Access Toolbar</strong> – enables you to create your own quick access toolbar.
</li>
<li><strong>Ribbon Office menu</strong> – this component provides you with customization for the Office Menu in Office 2007 applications.
</li>
<li><strong>Outlook forms manager</strong> – you add it to your project to customize Outlook views and forms using advanced Outlook regions.
</li>
<li><strong>Event helpers</strong> – these components are used to handle all important events of all Office applications such as Outlook NewMail, Word DocumentBeforeSave, Excel WorkbookBeforeOpen, etc.
</li>
<li>The <strong>Host Configuration</strong> item is used to configure Office applications for a specified .NET Framework version.
</li>
</ul>
<p><img src="/creating-addins-blog/wp-upload/addin-module-designer.gif" alt="Add-in Designer" /></p>
<p>Since AddinModule in this example is the central module of the project, it implements all COM-interfaces required by the COM Add-in technology and it has the base properties and events of COM add-ins (see the picture below). You can use the Properties window to name your add-in, to specify images for your toolbars and ribbon controls, to register your add-in for the current user or for all users, to collect and register your custom task panes and custom Outlook property pages, to define the namespace for your ribbon customization. Finally, using the SupportedApps property of your AddinModule you can enable / disable your extensions for certain Office applications. The events of your AddinModule include the common Office events for add-in initialization, finalization, error trapping, ribbon loading and task pane creation (see the picture below).</p>
<p><img src="/creating-addins-blog/wp-upload/addin-properties.gif" alt="Add-in Module properties" /></p>
<p><img src="/creating-addins-blog/wp-upload/addin-events.gif" alt="Add-in Module events" /></p>
<p>That’s all for now. In part three of the series, we will look more closely at the Office customization, namely creating your own toolbars for traditional Office 2000 – 2007 UI, customizing Office 2007 Ribbon UI and adding application-level keyboard shortcuts.</p>
<h3>Related posts:</h3>
<p><a href="http://www.add-in-express.com/creating-addins-blog/2007/04/24/create-microsoft-office-extensions-using-ro-chrome/">Create Microsoft Office extensions using RemObjects Chrome</a><br /><a href="http://www.add-in-express.com/creating-addins-blog/2007/04/30/customize-office-toolbars-ribbons-task-panes-on-ro-chrome/">Customize Office toolbars, ribbons, task panes on RO Chrome</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.add-in-express.com/creating-addins-blog/2007/04/25/office-plugins-chrome/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Create Microsoft Office extensions using RemObjects Chrome</title>
		<link>http://www.add-in-express.com/creating-addins-blog/2007/04/24/create-microsoft-office-extensions-using-ro-chrome/</link>
		<comments>http://www.add-in-express.com/creating-addins-blog/2007/04/24/create-microsoft-office-extensions-using-ro-chrome/#comments</comments>
		<pubDate>Tue, 24 Apr 2007 17:48:22 +0000</pubDate>
		<dc:creator>Eugene Starostin</dc:creator>
		
		<category><![CDATA[Add-in Express .NET]]></category>

		<category><![CDATA[COM add-ins]]></category>

		<category><![CDATA[Office]]></category>

		<guid isPermaLink="false">/creating-addins-blog/?p=19</guid>
		<description><![CDATA[Create secure, deployable, version-independent Microsoft Office extensions on RO Chrome for Visual Studio. Use RAD modules, designers and components to develop application-level COM add-ins, smart tags, RTD servers and user-defined functions.]]></description>
			<content:encoded><![CDATA[<p>Two of the most popular words in the Microsoft Office development globe right now are Office extensibility and application-level customization. These two features are a great way to get the most from Microsoft Office and build plugins that your customers long for. </p>
<p>In this three post series, I&#8217;ll be covering the most important concepts and approaches of creating custom Office extensions based on <a href="http://www.remobjects.com/page.asp?id=%7bC5B896C5-5C61-4C1C-A617-136711C07F46%7d">RO Chrome for Visual Studio</a> and <a href="http://www.add-in-express.com/add-in-net/">Add-in Express for Microsoft .net</a>. </p>
<p>Today, I&#8217;ll dig a little bit into the history of Office application-level extensibility, highlight the key features of Add-in Express and show how to quickly get started with developing Outlook COM add-ins using Chrome and Add-in Express.</p>
<h3>Office application-level extensibility</h3>
<p>Microsoft Office has a long history of applications extensibility. Microsoft added the support for <strong>COM add-ins</strong> to Office 2000. In the first release of Microsoft Office 2002, the <strong>Smart Tags</strong> technology got supported. The second release of Office 2002 added Excel customization with <strong>Real-Time Data servers</strong> (RTDS) and <strong>Automation add-ins</strong> (user-defined functions). Finally, Office 2007 made the <strong>Ribbon UI</strong> customizable and extended the COM add-in technology for all Office applications. On the other hand, Microsoft released <strong>Visual Studio Tools for Office</strong> (VSTO) 2003 and 2005 that allow developers to extend Office with document- and application-level extensions. Unfortunately, VSTO supports VB.NET and C# only. Today on the development tools market there is only one tool that supports Offic