<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Head in the Clouds</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/tq/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/tq/feed.xml</link>
    <description>As a software architect, my head is often in the clouds, dreaming of the future. And the future is increasingly in the cloud...</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:34:38 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>CloudStorageAccount.Parse is your friend</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/cloudstorageaccount-parse-is-your-friend</link>
      <pubDate>Tue, 01 Feb 2011 17:38:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2011/02/01/cloudstorageaccount-parse-is-your-friend/</guid>
      <description><![CDATA[When I started writing my first Azure app, one of the first issues I ran into was dealing with Azure...]]></description>
      <content:encoded><![CDATA[<p>When I started writing my first Azure app, one of the first issues I ran into was dealing with Azure storage -- I couldn't figure out how to set it up in my code so I could use it. I found this nice article about how to <a href="http://msdn.microsoft.com/en-us/library/ee758697.aspx">structure your connection strings</a>, but what it didn't tell me was where to put it, how to get it out of there and where to pass it when I had it to actually instantiate a storage account.</p>
<p>Whichever connection string you are using, the place to put it is in the settings page of your Role. Give it a name, any name (in this case StorageCxnString), and set the type to ConnectionString.</p>
<p>Then in code, it is simple to retreive it, and pass it to, CloudStorageAccount.Parse, to do the magic.&nbsp;</p>
<p><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;">private const</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> </span></span><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;">string</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> StorageCxnString = </span></span><span style="font-family: Consolas; color: #a31515; font-size: x-small;"><span style="font-family: Consolas; color: #a31515; font-size: x-small;"><span style="font-family: Consolas; color: #a31515; font-size: x-small;">"StorageCxnString"</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">;<span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">&nbsp;</span></span></span></span>&nbsp;</p>
<p><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;">internal</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> </span></span><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;">static</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> </span></span><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;">CloudStorageAccount</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> GetStorageAccount()<br />{<br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;">string</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> storageConnection = </span></span><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;">RoleEnvironment</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">.GetConfigurationSettingValue(StorageCxnString);<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;">CloudStorageAccount</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> _storageAccount = </span></span><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;">CloudStorageAccount</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">.Parse(storageConnection);<br /><br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;">return</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> _storageAccount;<br />}<span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> </span></span></span></span></p>
<p><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"></span></span></span></span>Now, when you want to move from Development Storage to real Azure Storage, you just change the connection string in the Role Settings property page, and the code still works. Hopefully, this will save someone out there a headache.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Re-launch of my blog</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/re-launch-of-my-blog</link>
      <pubDate>Tue, 01 Feb 2011 15:03:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2011/02/01/re-launch-of-my-blog/</guid>
      <description><![CDATA[This will be, in restaurant parlance, a "soft opening": no fanfare, we'll see if anyone...]]></description>
      <content:encoded><![CDATA[<p>This will be, in restaurant parlance, a "soft opening": no fanfare, we'll see if anyone notices.&nbsp;If there are any followers of this blog -- and considering my last post was three years ago, I find that highly unlikely -- you will notice I've changed some things. And I plan on changing more. </p>
<p>Previously, the subject of this blog had been Addins and Customization. I am still interested in those things. However, in the three dark years here, things have changed. In these years, my career has grown a bit. I am now a "Principal Software Architect Lead" which means I lead a small team of architects (and we're hiring, BTW). Our architectural oversight still includes the Office facing tools like VBA, VSTO and VSTA. It also includes developer tools for SharePoint. And most recently -- very recently in fact -- we have gained what we call the "Cloud Tools": the tools for the Windows Azure Platform. And I'm sure you've noticed that Office and SharePoint are moving to the cloud as well. So, now I've got my head in the clouds...</p>
<p>This is a new and fun area, and one about which I am very excited and enthusiastic. I have a few blog posts in this area queued up. I won't promise it won't be three years between posts again, but we'll see how it goes.</p>]]></content:encoded>
    </item>
    <item>
      <title>The reports of VBA's demise have been greatly exaggerated.</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/the-reports-of-vbas-demise-have-been-greatly-exaggerated</link>
      <pubDate>Thu, 17 Jan 2008 13:34:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2008/01/17/the-reports-of-vbas-demise-have-been-greatly-exaggerated/</guid>
      <description><![CDATA[There have been spurious reports in the media saying that VBA is dead. Caused quite a firestorm...]]></description>
      <content:encoded><![CDATA[<P>There have been spurious reports in the media saying that VBA is dead. Caused quite a firestorm around here as you might imagine -- 'cause it just plain isn't true.<BR><BR>There is an official statement on the VSTO blog here:</P>
<P>\<A href="http://blogs.msdn.com/vsto2/archive/2008/01/16/the-reports-of-vba-s-demise-have-been-greatly-exaggerated.aspx">http://blogs.msdn.com/vsto2/archive/2008/01/16/the-reports-of-vba-s-demise-have-been-greatly-exaggerated.aspx</A></P>]]></content:encoded>
    </item>
    <item>
      <title>VSTO Architecture Demo from TechEd and MSDN WebCast</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/vsto-architecture-demo-from-teched-and-msdn-webcast</link>
      <pubDate>Fri, 30 Nov 2007 20:44:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2007/11/30/vsto-architecture-demo-from-teched-and-msdn-webcast/</guid>
      <description><![CDATA[Good news here -- for me especially :). The demo code from my VSTO Architecture talk at TechEd and...]]></description>
      <content:encoded><![CDATA[<P>Good news here -- for me especially :). The demo code from my VSTO Architecture talk at TechEd and in the recent MSDN WebCast is already (mostly)&nbsp;posted <A class="" title=here. href="http://msdn.microsoft.com/msdnmag/issues/07/12/VstoNet/default.aspx" target=_blank mce_href="http://msdn.microsoft.com/msdnmag/issues/07/12/VstoNet/default.aspx">here.</A>&nbsp;My colleague Andrew Whitechapel had written the WPF Control and the WCF service that I used in my demo -- which really makes it mostly his demo (thanks Andrew). Anyway, I went to ask him if I could post the code, and noticed the latest issue of <A class="" href="http://msdn.microsoft.com/msdnmag/" mce_href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</A> on his desk with a VSTO article, and lo and behold, he published virtually the same demo on MSDN. Almost completely identical. Thanks Andrew!</P>
<P>The only thing that is different is that his code does the Custom Task Pane the "easy" way, the standard way. In other words, he doesn't override RequestService and implement ICustomTaskPaneConsumer. But this was a small part of the demo and used, really, to demonstrate how VSTO works under the covers. In real life very few of you should ever have a need to override this functionality. However, if you do, feel free to ping me here.</P>]]></content:encoded>
    </item>
    <item>
      <title>TechEd and MSDN Webcast Demos</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/teched-and-msdn-webcast-demos</link>
      <pubDate>Fri, 30 Nov 2007 19:17:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2007/11/30/teched-and-msdn-webcast-demos/</guid>
      <description><![CDATA[Geez, I'm looking at this blog, and I'm realizing I've only posted once this year, and that post...]]></description>
      <content:encoded><![CDATA[<P>Geez, I'm looking at this blog, and I'm realizing I've only posted once this year, and that post said I would post more often. What a lame-o!</P>
<P>Since my last post I have been busy. I've spoken at two TechEds -- in the US in Orlando and in Europe in Barcelona. I totally recommend Barcelona for anyone who hasn't been there, what a great city!</P>
<P>But I digress. I've been asked by several people to make available the demo code that I showed at the TechEds. I had a talk on VSTO Architecture at both, and had a "done from scratch" demo showing how to do some advanced things with VSTO. I also did this the other day on an MSDN WebCast, and didn't have time to get through the whole demo (what a lame-o, again!) and said I would post it here. Just want everyone to know that I am cleaning it up for general consumption, and it should be posted here within the next day or so.</P>
<P>&nbsp;My other demo at Barcelona was integration of VSTA into a WPF application. I could post that demo, too, but it would do you little good at the moment, because VSTA v2 has not yet been released. So, once we have a public release of VSTA (currently planned for early next year) I will post that demo too. I have plans to expand that demo as well -- add fun features over time.</P>
<P>&nbsp;If you are interested now, and can't wait for VSTA, well we have an answer. We will be having a limited CTP (Customer Technical Preview) of VSTA v2 in the next week. In order to get access to the CTP you need to contact our VSTA partner Summit Software at <A href="http://www.summsoft.com/">www.summsoft.com</A>.&nbsp;If you do&nbsp;get the CTP from&nbsp;Summit and want early access to my VSTA WPF Demo, just contact me through the blog and I will get you an early copy.&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Back Into the Light</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/back-into-the-light</link>
      <pubDate>Thu, 14 Jun 2007 14:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2007/06/14/back-into-the-light/</guid>
      <description><![CDATA[And out of the dark...
I've been dark for a while now, time to come out and let you know what's...]]></description>
      <content:encoded><![CDATA[<P>And out of the dark...</P>
<P>I've been dark for a while now, time to come out and let you know what's been going on. I've been heads down writing code for VSTO v3 and VSTA v2 due to release -- hopefully, no promises -- later this year. The new version of VSTO is built upon the new version of VSTA which is built upon the new version of System.Addin. And the new version of System.AddIn is shipping in the .NET Framework 3.5 as promised.</P>
<P>&nbsp;It has been a ton of work, but we are close to being done now. Those of you who attended TechEd last week got a preview of VSTO v3 in the keynote, and hopefully attended our sessions during the week.</P>
<P>I did a session on VSTO architecture where I gave an overview of the v3 architecture and how we've changed and evolved it from previous versions. I know I promised some of you who were there that I would post my demo sample here -- and I will. It occurred to me, though, that it is of no use to you until you get a more recent drop of Visual Studio that includes all of the bits we showed. As soon as one is available publically&nbsp;I will make sure the sample works with that drop and post it.</P>
<P>I also have some more, in depth, discussion around MAF, VSTA and VSTO planned, stay tuned.</P>]]></content:encoded>
    </item>
    <item>
      <title>VSTA and Generics</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/vsta-and-generics</link>
      <pubDate>Tue, 05 Dec 2006 02:10:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2006/12/05/vsta-and-generics/</guid>
      <description><![CDATA[VSTA has been officially released now, in InfoPath in the 2007 Office System, and for use by third...]]></description>
      <content:encoded><![CDATA[<P>VSTA has been officially released now, in InfoPath in the 2007 Office System, and for use by third parties in the VS SDK. So we're getting our first batch of feature requests. Far and away the biggest request so far is generic support. Admittedly, generic support for VSTA hosts is limited. I know it's an excuse, but we had limited time and resources to get VSTA done in time for Office 2007, and we had to make some hard choices. One of the reasons generic support was considered "cut-able" was that with a small amount of work, the user (you) could add the support you needed back in. In other words, there is a workaround. In this blog post, I'm going to talk about how this is done. </P>
<P>So the good news is that the infrastructure supports, to a certain extent, generics. And there is always the flexibility of using custom contracts to support anything you want. I'm going to leave custom contracts to a future post; this post is all about doing the smallest amount of work necessary to minimally support generics in a couple common cases. I'm interested in hearing whether this meets your needs, or if there are more common cases that are not done so easily. </P>
<P>The bad news is that proxygen doesn't support generics at all. It just skips over them when it sees them. But that's one reason why proxygen emits source code. In my mind, anyway (not sure if everyone on the team would agree with this) proxygen was never intended to generate code that gets shipped as is. The code is there to be tweaked. In some cases it may be as simple as renaming some classes. I would expect that many, if not most, hosts will want to use targeted custom contracts for performance – and other – reasons; stay tuned for my next post. And if your OM contains generics, you'll have to write a little code to augment what we put out. </P>
<P>So I took the ShapeApp sample and started changing it. The first case I tried was events. The .NET Framework guidelines tell you to use EventHandler&lt;T&gt; to declare events. ShapeApp didn't use these of course, and, well, that's not too helpful to you, if you followed the guidelines. So I removed all of the custom delegates and changed all of the events to use either System.EventHandler or System.EventHandler&lt;T&gt; when they had custom event args. I also changed the EventArgs class to derive from System.EventArgs, also according to the guidelines. Seems like a bug to me that it wasn't this way in the first place. I did this on both sides, in the ShapeApp app itself and in the proxy assembly that the addins consume. </P>
<P>This worked very well. All I had to do was change the code that populates the TypeInfrastructureManager: I just changed the typeof declarations to use the qualified generic types, and events were done. </P>
<P>The next common case is collections. Again, the guidelines tell us to use the generic collection types when we define collections – and it is ton easier if you've done it this way. ShapeApp has two collections, the DrawingCollection and the ShapeCollection. The first thing I did was change the application's implementation of these collections. As you'll see, I removed a bunch of code from these by using the built-in Framework classes. I derived them both from System.Collections.ObjectModel.Collection&lt;T&gt;. In the DrawingCollection the only thing additional thing I had to do was to override the InsertItem method to set up the drawingNumber field correctly. Notice I made the DrawingCollection type itself internal, and everywhere it was exposed I changed it to System.Collections.Generic.IList&lt;Drawing&gt; just to make sure we were really making things generic. </P>
<P>I had to do a little more work in the ShapeCollection. First off, it supported indexing by string as well as integer. Built-in collections don't support this, of course. So I defined a new interface IShapeList that derives from IList&lt;IShape&gt;. My ShapeCollection class derives from System.Collections.ObjectModel.Collection&lt;IShape&gt; and also implements IShapeList. The old ShapeCollection also fired a couple internal events: ShapeAdded and ShapeRemoved. In order to fire these at the right time (the new generic version of ShapeAdded and the new System.EventHandler version of ShapeRemoved) I had to override InsertItem and RemoveItem. Again, ShapeCollection was changed to an internal type. In this case, in the places where ShapeCollection had been exposed before, I changed it to my new interface: IShapeList. But System.Collections.Generic.IList&lt;IShape&gt; will show up again. </P>
<P>I turned out that just updating the TypeInfrastructureManager population code didn't complete the story – you do need to update it, and in fact we'll take advantage of some additional functionality it supports, but it wasn't as simple as the events. The problem turned out to be that the type returned by GetEnumerator was IEnumerator&lt;T&gt; and not just IEnumerator. </P>
<P>I decided to create a custom adapter for these collections. I created a new generic class (hey, I'm all about generics, now) called CollectionAdapter&lt;T&gt;. I decided to derive CollectionAdapter&lt;T&gt; from RemoteObjectAdapter (rather than ContractAdapterBase). This means that addins would have the ability to late-bind to it in addition to the work we're doing here. I don't actually use this late-binding capability in this sample, but all of the other objects that use the built-in adapters support late-binding, so I wanted to be consistent. And I do plan on taking advantage of this in a future post. </P>
<P>Here is the code from CollectionAdapter&lt;T&gt; is at the bottom. As you can see, there are really two classes here. The EnumeratorAdapter&lt;T&gt; is necessary to support GetEnumerator, of course. The EnumeratorAdapter *does* derive from ContractAdapterBase, because it is only used as an enumerator and never late-bound. The CollectionAdapter wraps an IList&lt;T&gt; and implements IRemoteArgumentArrayListContract which is in System.AddIn.Contract.Collections. The implementation of the contract (and its base contracts) defers to the wrapped list, and where necessary unwraps the RemoteArguments to local instances of T, or wraps them up. The where T : class constraint on the Adapter classes is there so we can use the typeof(T). </P>
<P>OK, so we have an Adapter, how does it get created? Go back to the code in extension.cs and notice we handle the AdapterResolve event. The TypeInfrastructureManager (I'm just going to call it TIM from now on, tired of typing it out) has this hook just for this purpose; for the host to provide custom adapters. The implementation is simple enough, if the TIM asks for an adapter for an IList&lt;Drawing&gt; or an IList&lt;IShape&gt; we instantiate a CollectionAdapter&lt;T&gt; and return it. </P>
<P>But what about the other side? The generated ShapeCollection and DrawingCollection didn't work correctly, so I implemented some new ones. Unfortunately, on the proxy side, I couldn't use System.Collections.ObjectModel.Collection&lt;T&gt; as the base class. This is because I had to have custom enumerators (to call into the IRemoteArgumentEnumeratorContract) and System.Collections.ObjectModel.Collection&lt;T&gt; doesn't expose out the ability to override it. In fact, its Enumerator implementation is internal. So the proxies were a little more work but not much. I had them implement ICollection&lt;T&gt;. They also implement IProxy to identify them to the infrastructure as proxies. Here the implementation just defers to the contract, and when necessary uses the helpers to wrap and unwrap RemoteArguments. The DrawingCollection is implemented as ReadOnly. The ShapeCollection supports Adding and Removing. It also implements a string based indexer like the application's OM class. However, as you can see, this implementation just loops through the elements until it finds the right one. I doesn't use the IShapeList. Why? Because IShapeList is not a contract, and in order to call into it we'd need a custom contract. And I'm not covering custom contract's here. Of course, it would be *far* more efficient to do the looping locally, instead of retrieving each object, pulling across the AppDomain boundary and checking it there. An ideal place for a custom contract – guess I have more work to do ;). </P>
<P>On the proxy side, we handle the ProxyResolve event rather than the AdapterResolve event off of TIM. Makes sense. The code there is equally simple. I also changed the name of IShapeClass to Shape, just 'cause it makes more sense. </P>
<P>If you have macro or addin code written against another version of ShapeApp, it should still compile, but you *will* have to recompile since the types have changed. </P>
<P>Please let me know if this sample is helpful – or not, especially not. </P>
<P>//Collection Adapter </P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> System; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> System.Collections.Generic; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> System.Text; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> System.AddIn.Contract; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> Microsoft.VisualStudio.Tools.Applications; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> System.AddIn.Contract.Collections; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">using</SPAN> System.Runtime.Remoting; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">namespace</SPAN> Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">internal</SPAN> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: teal">EnumeratorAdapter</SPAN>&lt;T&gt; : <SPAN style="COLOR: teal">ContractAdapterBase</SPAN>, <SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">where</SPAN> T : <SPAN style="COLOR: blue">class </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">internal</SPAN> EnumeratorAdapter(<SPAN style="COLOR: teal">IEnumerator</SPAN>&lt;T&gt; wrappedEnumerator, <SPAN style="COLOR: teal">TypeInfrastructureManager</SPAN> tim) : </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">base</SPAN>(tim) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">this</SPAN>.wrappedEnumerator = wrappedEnumerator; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">this</SPAN>.tim = tim; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">private</SPAN> <SPAN style="COLOR: teal">IEnumerator</SPAN>&lt;T&gt; wrappedEnumerator; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">private</SPAN> <SPAN style="COLOR: teal">TypeInfrastructureManager</SPAN> tim; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> Base Class Overrides </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">protected</SPAN> <SPAN style="COLOR: blue">override</SPAN> <SPAN style="COLOR: teal">IContract</SPAN> QueryContract(<SPAN style="COLOR: blue">string</SPAN> contractIdentifier) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: teal">String</SPAN>.Compare(contractIdentifier, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract</SPAN>).AssemblyQualifiedName) == 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract</SPAN>)<SPAN style="COLOR: blue">this</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">base</SPAN>.QueryContract(contractIdentifier); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">protected</SPAN> <SPAN style="COLOR: blue">override</SPAN> <SPAN style="COLOR: blue">int</SPAN> GetRemoteHashCode() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> wrappedEnumerator.GetHashCode(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">protected</SPAN> <SPAN style="COLOR: blue">override</SPAN> <SPAN style="COLOR: blue">bool</SPAN> RemoteEquals(<SPAN style="COLOR: teal">IContract</SPAN> contract) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (contract == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">false</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (!<SPAN style="COLOR: teal">RemotingServices</SPAN>.IsObjectOutOfAppDomain(contract)) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: teal">EnumeratorAdapter</SPAN>&lt;T&gt; contractAdapter = contract <SPAN style="COLOR: blue">as</SPAN> <SPAN style="COLOR: teal">EnumeratorAdapter</SPAN>&lt;T&gt;; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (contractAdapter == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">false</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">this</SPAN>.wrappedEnumerator.Equals(contractAdapter.wrappedEnumerator); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">false</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">protected</SPAN> <SPAN style="COLOR: blue">override</SPAN> <SPAN style="COLOR: blue">string</SPAN> RemoteToString() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">this</SPAN>.wrappedEnumerator.ToString(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> IRemoteArgumentEnumeratorContract Members </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: teal">RemoteArgument</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract</SPAN>.GetCurrent() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">RemoteArgument</SPAN>( <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">RemoteObjectAdapter</SPAN>(<SPAN style="COLOR: blue">typeof</SPAN>(T), wrappedEnumerator.Current, tim)); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">bool</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract</SPAN>.MoveNext() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> wrappedEnumerator.MoveNext(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract</SPAN>.Reset() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedEnumerator.Reset(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">internal</SPAN> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: teal">CollectionAdapter</SPAN>&lt;T&gt; : <SPAN style="COLOR: teal">RemoteObjectAdapter</SPAN>, <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">where</SPAN> T : <SPAN style="COLOR: blue">class </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">internal</SPAN> CollectionAdapter(<SPAN style="COLOR: teal">IList</SPAN>&lt;T&gt; wrappedList, <SPAN style="COLOR: teal">TypeInfrastructureManager</SPAN> tim) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">this</SPAN>.wrappedList = wrappedList; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">this</SPAN>.tim = tim; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> Base Class Overrides </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">protected</SPAN> <SPAN style="COLOR: blue">override</SPAN> <SPAN style="COLOR: teal">IContract</SPAN> QueryContract(<SPAN style="COLOR: blue">string</SPAN> contractIdentifier) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: teal">String</SPAN>.Compare(contractIdentifier, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>).AssemblyQualifiedName, <SPAN style="COLOR: teal">StringComparison</SPAN>.Ordinal) == 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>)<SPAN style="COLOR: blue">this</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: teal">String</SPAN>.Compare(contractIdentifier, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: teal">IRemoteArgumentArrayContract</SPAN>).AssemblyQualifiedName, <SPAN style="COLOR: teal">StringComparison</SPAN>.Ordinal) == 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: teal">IRemoteArgumentArrayContract</SPAN>)<SPAN style="COLOR: blue">this</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: teal">String</SPAN>.Compare(contractIdentifier, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: teal">IRemoteArgumentCollectionContract</SPAN>).AssemblyQualifiedName, <SPAN style="COLOR: teal">StringComparison</SPAN>.Ordinal) == 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: teal">IRemoteArgumentCollectionContract</SPAN>)<SPAN style="COLOR: blue">this</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: teal">String</SPAN>.Compare(contractIdentifier, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: teal">IRemoteArgumentEnumerableContract</SPAN>).AssemblyQualifiedName, <SPAN style="COLOR: teal">StringComparison</SPAN>.Ordinal) == 0) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: teal">IRemoteArgumentEnumerableContract</SPAN>)<SPAN style="COLOR: blue">this</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">base</SPAN>.QueryContract(contractIdentifier); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">private</SPAN> <SPAN style="COLOR: teal">IList</SPAN>&lt;T&gt; wrappedList; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">private</SPAN> <SPAN style="COLOR: teal">TypeInfrastructureManager</SPAN> tim; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> IRemoteArgumentArrayListContract Members </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.Add(System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> newItem) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localItem = <SPAN style="COLOR: teal">TypeServices</SPAN>.ObjectFromRemoteArgument(newItem, <SPAN style="COLOR: blue">typeof</SPAN>(T), tim) <SPAN style="COLOR: blue">as</SPAN> T; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (localItem == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">throw</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">ArgumentException</SPAN>(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedList.Add(localItem); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.Clear() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedList.Clear(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.Insert(<SPAN style="COLOR: blue">int</SPAN> index, System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> item) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localItem = <SPAN style="COLOR: teal">TypeServices</SPAN>.ObjectFromRemoteArgument(item, <SPAN style="COLOR: blue">typeof</SPAN>(T), tim) <SPAN style="COLOR: blue">as</SPAN> T; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (localItem == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">throw</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">ArgumentException</SPAN>(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedList.Insert(index, localItem); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.Remove(System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> item) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localItem = <SPAN style="COLOR: teal">TypeServices</SPAN>.ObjectFromRemoteArgument(item, <SPAN style="COLOR: blue">typeof</SPAN>(T), tim) <SPAN style="COLOR: blue">as</SPAN> T; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (localItem == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">throw</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">ArgumentException</SPAN>(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedList.Remove(localItem); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.RemoveAt(<SPAN style="COLOR: blue">int</SPAN> index) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedList.RemoveAt(index); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">bool</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.Contains(System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> item) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localItem = <SPAN style="COLOR: teal">TypeServices</SPAN>.ObjectFromRemoteArgument(item, <SPAN style="COLOR: blue">typeof</SPAN>(T), tim) <SPAN style="COLOR: blue">as</SPAN> T; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (localItem == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">false</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> wrappedList.Contains(localItem); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">int</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayListContract</SPAN>.IndexOf(System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> item) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localItem = <SPAN style="COLOR: teal">TypeServices</SPAN>.ObjectFromRemoteArgument(item, <SPAN style="COLOR: blue">typeof</SPAN>(T), tim) <SPAN style="COLOR: blue">as</SPAN> T; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (localItem == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">throw</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">ArgumentException</SPAN>(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> wrappedList.IndexOf(localItem); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> IRemoteArgumentArrayContract Members </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayContract</SPAN>.GetItem(<SPAN style="COLOR: blue">int</SPAN> index) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localVal = wrappedList[index]; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">RemoteArgument</SPAN>(<SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">RemoteObjectAdapter</SPAN>(<SPAN style="COLOR: blue">typeof</SPAN>(T), localVal, tim)); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentArrayContract</SPAN>.SetItem(<SPAN style="COLOR: blue">int</SPAN> index, System.AddIn.Contract.<SPAN style="COLOR: teal">RemoteArgument</SPAN> value) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">T localVal = <SPAN style="COLOR: teal">TypeServices</SPAN>.ObjectFromRemoteArgument(value, <SPAN style="COLOR: blue">typeof</SPAN>(T), tim) <SPAN style="COLOR: blue">as</SPAN> T; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (localVal == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">throw</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">ArgumentException</SPAN>(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">wrappedList[index] = localVal; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> IRemoteArgumentCollectionContract Members </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">int</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentCollectionContract</SPAN>.GetCount() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> wrappedList.Count; </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> IRemoteArgumentEnumerableContract Members </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: teal">IRemoteArgumentEnumeratorContract</SPAN> <SPAN style="COLOR: teal">IRemoteArgumentEnumerableContract</SPAN>.GetEnumeratorContract() </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">EnumeratorAdapter</SPAN>&lt;T&gt;(<SPAN style="COLOR: blue">this</SPAN>.wrappedList.GetEnumerator(), <SPAN style="COLOR: blue">this</SPAN>.tim); </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/01/20/97/09/ShapeAppAdvancedCSharpGenerics.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-01-20-97-09/ShapeAppAdvancedCSharpGenerics.zip">ShapeAppAdvancedCSharpGenerics.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Outlook 2007 Form Region Sample – Second Edition</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/outlook-2007-form-region-sample-second-edition</link>
      <pubDate>Fri, 01 Dec 2006 01:28:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2006/12/01/outlook-2007-form-region-sample-second-edition/</guid>
      <description><![CDATA[Office 2007 is official today, so it is time to update my Form Region Sample. The big difference is...]]></description>
      <content:encoded><![CDATA[<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Office 2007 is official today, so it is time to update my Form Region Sample. The big difference is new methods on the _FormRegionStartup interface. With input from us here in VSTO, Outlook changed the interface to make it easier to use from VSTO addins and more&nbsp; friendly to managed dlls. The two new methods mean I could remove a bunch of the workarounds in the previous version. The new interface looks like this: </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">interface</SPAN> <SPAN style="COLOR: teal">_FormRegionStartup <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">void</SPAN> BeforeFormRegionShow(<SPAN style="COLOR: teal">FormRegion</SPAN> FormRegion);<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">object</SPAN> GetFormRegionStorage(<SPAN style="COLOR: blue">string</SPAN> FormRegionName, <SPAN style="COLOR: blue">object</SPAN> Item, <SPAN style="COLOR: blue">int</SPAN> LCID, <SPAN style="COLOR: teal">OlFormRegionMode</SPAN> FormRegionMode, <SPAN style="COLOR: teal">OlFormRegionSize</SPAN> FormRegionSize); <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">object</SPAN> GetFormRegionIcon(<SPAN style="COLOR: blue">string</SPAN> FormRegionName, <SPAN style="COLOR: blue">int</SPAN> LCID, <SPAN style="COLOR: teal">OlFormRegionIcon</SPAN> Icon); |<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">object</SPAN> GetFormRegionManifest(<SPAN style="COLOR: blue">string</SPAN> FormRegionName, <SPAN style="COLOR: blue">int</SPAN> LCID); <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P>The first two methods we've seen before, but the next two make it nice. Let's look at GetFormRegionManifest first. This means that the form region manifest that had to be installed on disk and the path registered in the form region section of the registry, can now be stored as a resource in the dll. This means a change in the registration, of course, which I'll cover below. The implementation of this method is quite trivial. We use the name we register it with to identify the actual manifest. It gets returned as a string. </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">object</SPAN> GetFormRegionManifest(<SPAN style="COLOR: blue">string</SPAN> FormRegionName, <SPAN style="COLOR: blue">int</SPAN> LCID) <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (FormRegionName == <SPAN style="COLOR: maroon">"TQForms.RssFormRegion"</SPAN>) <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> RSSMessages.Properties.<SPAN style="COLOR: teal">Resources</SPAN>.RSSFormRegion; <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">else</SPAN> <SPAN style="COLOR: blue">if</SPAN> (FormRegionName == <SPAN style="COLOR: maroon">"TQForms.PreviewRssFormRegion"</SPAN>) <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> RSSMessages.Properties.<SPAN style="COLOR: teal">Resources</SPAN>.PreviewRSSFormRegion;<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} <BR><BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">null</SPAN>; <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P>The next method – GetFormRegionIcon – solves one problem from before, but introduces another issue. We now no longer have to store icons as Win32Resources, so we can remove the workarounds we had before to make that happen. But instead, we have to convert the icon from a managed object to a COM compatible object that Outlook can use. The implementation from the sample looks like this: </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">object</SPAN> GetFormRegionIcon(<SPAN style="COLOR: blue">string</SPAN> FormRegionName, <SPAN style="COLOR: blue">int</SPAN> LCID, <SPAN style="COLOR: teal">OlFormRegionIcon</SPAN> Icon) <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (FormRegionName == <SPAN style="COLOR: maroon">"TQForms.RssFormRegion"</SPAN> &amp;&amp; Icon == <SPAN style="COLOR: teal">OlFormRegionIcon</SPAN>.olFormRegionIconPage)<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> Converter.<SPAN style="COLOR: teal">PictureUtils</SPAN>.ToIPictureDisp(RSSMessages.Properties.<SPAN style="COLOR: teal">Resources</SPAN>.FeedIcon);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">null</SPAN>; <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P>As you can see, we call a Converter class to turn the resource into an IPictureDisp. Unfortunately, there is no built in .NET way to do this conversion, the Converter class is included in the sample. I'll leave it up to you to check out how it works. </P>
<P>So the xml in the manifest changes a little. Rather than putting in a resource ID, you just put the work addin to tell Outlook to load the particular addin from via the interface. You must do them all the same way – part of getting this work done at that late stage in the cycle was simplifying the assumptions: if one icon is loaded via the addin, they all must be. The xml is here: </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">FormRegion</SPAN><SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">xmlns</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">http://schemas.microsoft.com/office/outlook/12/formregion.xsd</SPAN>"<SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">name</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>TQForms.RssFormRegion<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">name</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">title</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>View In Browser<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">title</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">formRegionType</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>separate<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">formRegionType</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">showInspectorCompose</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>false<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">showInspectorCompose</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">showInspectorRead</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>true<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">showInspectorRead</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">showReadingPane</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>false<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">showReadingPane</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">hidden</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>true<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">hidden</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">addin</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>RSSMessages<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">addin</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">version</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>1.0<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">version</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">icons</SPAN><SPAN style="COLOR: blue">&gt; <BR>&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">page</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>addin<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">page</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">icons</SPAN><SPAN style="COLOR: blue">&gt; <BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">FormRegion</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P>In fact, if you register the form region as coming from the addin, you must load your icons this way. The change in registration makes it much simpler, but it is subtle. Rather than putting a path in the registry, you put the name of the addin – the same name that goes under the Addins key. But you first prefix it with an equals sign (=). This is the clue to Outlook that the manifest and icons are loaded via these new methods. If the addin is registered this way, the new methods *must* be implemented. If it is not registered this way, the new methods will not be called. This is the the registry script: </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">Windows Registry Editor Version 5.00 </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">[HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\FormRegions\IPM.Post.RSS] <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">"TQForms.RssFormRegion"="=RSSMessages" <BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">"TQForms.PreviewRssFormRegion"="=RSSMessages" </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">Hopefully, you be as happy about these new methods as I am. It makes form regions much easier. </SPAN></P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/01/18/15/01/RSSMessages.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-01-18-15-01/RSSMessages.zip">RSSMessages.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Outlook 2007 Form Region Sample</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/outlook-2007-form-region-sample</link>
      <pubDate>Mon, 30 Oct 2006 19:02:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2006/10/30/outlook-2007-form-region-sample/</guid>
      <description><![CDATA[I've finally finished my Form Region Sample for Outlook 2007 that was promised. I've been working on...]]></description>
      <content:encoded><![CDATA[<P>I've finally finished my Form Region Sample for Outlook 2007 that was promised. I've been working on it in earnest for a couple weeks now in my spare time. I am now resisting the urge to continue tweaking it: it is time to lockdown and ship. The urge to tweak is there because this is something I'm actually going to use all of the time. Outlook 2007, you may have noticed, has a new folder for RSS feeds, so you can get your blogs right in Outlook. This is cool, but I wanted to change how the posts were displayed – they always excerpt them and then include a link to the full post. The link then opens IE in another window. I wanted to be able to see the full post in the Outlook view: perfect use for a FormRegion! </P>
<P>I've created a FormRegion that hosts the Windows WebBrowser Control, and automatically shows the link. For the purposes of the sample I decided to put it two places and do it two different ways. I show it as an "adjoining" reason in the Preview pane, and as a "separate" region in the Inspector "Reading" view. I'll leave it up to you to experiment with mixing and matching these views. I'll go into where these are specified when I talk about the FomrRegion manifest below. </P>
<P><STRONG>Implementation </STRONG></P>
<P>First, let's go through the implementation. We'll start with the ThisAddin class. If you created and Outlook addin in VSTO 2005, you'll notice that this is different. We called it ThisApplication in VSTO 2005 and it derived directly from Outlook.Application. In VSTO 2005 SE, we have restructured this so the ThisAddin class is separate from the Application. It still gives you strongly typed access to Outlook.Application, it just doesn't derive from it anymore. In my Channel9 interview, I discussed why we made this change. If you have any feedback on this change – good, bad or neutral – please send it along. </P>
<P>The important piece of code in the ThisAddin class is this: </P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console">//Override the RequestService call to handle </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: green">//requests for the FormRegion service </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">protected</SPAN> <SPAN style="COLOR: blue">override</SPAN> <SPAN style="COLOR: blue">object</SPAN> RequestService(<SPAN style="COLOR: teal">Guid</SPAN> serviceGuid) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (serviceGuid == <SPAN style="COLOR: blue">typeof</SPAN>(Outlook.<SPAN style="COLOR: teal">_FormRegionStartup</SPAN>).GUID) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: blue">this</SPAN>.formRegionManager == <SPAN style="COLOR: blue">null</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">this</SPAN>.formRegionManager = <SPAN style="COLOR: blue">new</SPAN> RSSMessages.Regions.<SPAN style="COLOR: teal">FormRegionManager</SPAN>(); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">this</SPAN>.formRegionManager; </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">base</SPAN>.RequestService(serviceGuid); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P>ThisAddin provides a new overridable function that we can be used to provide "services" to Office. If you add a ribbon to the project, you will see a similar piece of code for hooking it up. Office queries VSTO addins for various services (ribbons and FormRegions for now, there are others coming). We worked with the Office team to make this mechanism extensible, so that we could add more integrated support for the important services – you won't have to write this code in VSTO Orcas because we're providing a designer – and Office can add services over time and you can have access to them without VSTO having to change. </P>
<P>Anyway, Office requests the services by their COM guid. In this case it is the guid of the _FormRegionStatup interface. The FormRegionManager class in the project provides the implementation of _FormRegionStartup. Let's look at that next. These are the two methods on _FormRegionStartup in Outlook 2007 Beta2 TR. I make that distinction because this interface has changed since then. I'll discuss those changes – and update this sample – in a future post once they ship. Suffice it to say the changes will make some of the difficulties I discuss below go away. They are a good thing. </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">#region</SPAN> _FormRegionStartup Members </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">void</SPAN> BeforeFormRegionShow(<SPAN style="COLOR: teal">FormRegion</SPAN> formRegion) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: teal">RegionInstance</SPAN> ri = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">RegionInstance</SPAN>(formRegion); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">ri.OnFormRegionClose += <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: teal">FormRegionCloseHandler</SPAN>(ri_OnFormRegionClose); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">this</SPAN>.regionInstances.Add(formRegion, ri); </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">object</SPAN> GetFormRegionStorage(<SPAN style="COLOR: blue">string</SPAN> FormRegionName, <SPAN style="COLOR: blue">object</SPAN> Item, <SPAN style="COLOR: blue">int</SPAN> LCID, <SPAN style="COLOR: teal">OlFormRegionMode</SPAN> FormRegionMode, <SPAN style="COLOR: teal">OlFormRegionSize</SPAN> FormRegionSize) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">if</SPAN> (FormRegionName == <SPAN style="COLOR: maroon">"TQForms.RSSFormRegion"</SPAN> || FormRegionName == <SPAN style="COLOR: maroon">"TQForms.PreviewRSSFormRegion"</SPAN>) </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">{ </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> RSSMessages.Properties.<SPAN style="COLOR: teal">Resources</SPAN>.Rss_Form_Region; </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">return</SPAN> <SPAN style="COLOR: blue">null</SPAN>; </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console">} </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Lucida Console">#endregion </SPAN></P>
<P>The first method that gets called is GetFormRegionStorage. The FormRegionName parameter corresponds with the name in the form region manifest file, I'll get to that below. It returns the byte array that is the .ofs file you get from outlook. I'll talk about that below, too. Suffice it to say you simply add the ofs file to your project as a File resource and it is a simple line of code to return it as above. Then you get called on BeforFormRegionShow and get passed the instance of Outlook's FormRegion object. This gets called for each instance of the form region that is visible, and there can be any number visible at any time. So I created a separate class to represent each instance of a form region, called RegionInstance. It holds on to Outlook's FormRegion object and pulls all of the controls on the form out of that. See the function InitItems in RegionInstance.cs to see how this is done. </P>
<P>And that's about it for the implemetation: you hook up to events on the controls the way you would on any control and make them work the way you want. There are some interesting details about what I had to do to get the Icon for View in Browser to show up in the Ribbon, though. I'll cover those when I talk about the manifest below. </P>
<P><STRONG>Creating a Form Region </STRONG></P>
<P>Of course, to show a form region you have to create one, this is the .ofs file I alluded to above. The way you create one is to go into Outlook, then go to Tools…Forms…Design a Form. You'll get a dialog to choose which form you want to design – I chose RSS Article for this sample. Then you are presented with an Explorer window with the default view for that form and a bunch of tabs. From there you choose Form Region … New Form Region from the ribbon. It will add a new, blank tab and pop up a tool window with fields. You can drag and drop fields from there, and these are automatically hooked up with the outlook fields for this item. For instance the Subject and RSS Feed boxes in my form are done this way – no coding necessary. You can also show the standard Control Toolbox from the right-click menu on the form and add other controls – like the web browser control and progress bar control that I used – to the tool box and use them as well. When you have the form the way you want it, go back to the Form Region button on the Ribbon and select Save Form Region. You'll get the standard Save dialog and this will save your .ofs file. Then just copy the .ofs file to your project and add it to your resources. </P>
<P>You can also open up my .ofs file in the designer. Just go to the Form Region button on the designer and select Open Form Region. You'll see how my form regions was designed. </P>
<P><STRONG>Form Region Manifest </STRONG></P>
<P>In order for the Form Region to show up in Outlook at runtime, it must be described in a manifest and this manifest must be registered. The manifest, as you might imagine, is an XML file with a particular schema. Here is an example from my project: </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;?</SPAN><SPAN style="COLOR: maroon">xml</SPAN><SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">version</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">1.0</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">encoding</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">utf-8</SPAN>"<SPAN style="COLOR: blue">?&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">FormRegion</SPAN><SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">xmlns</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">http://schemas.microsoft.com/office/outlook/12/formregion.xsd</SPAN>"<SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">name</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>TQForms.RSSFormRegion<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">name</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">title</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>View In Browser<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">title</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">formRegionType</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>separate<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">formRegionType</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">showInspectorCompose</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>false<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">showInspectorCompose</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">showInspectorRead</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>true<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">showInspectorRead</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">showReadingPane</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>false<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">showReadingPane</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">addin</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>RSSMessages<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">addin</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">version</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>1.0<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">version</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">icons</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">page</SPAN><SPAN style="COLOR: blue">&gt;</SPAN>..\bin\debug\rssmessages.dll,101<SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">page</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">icons</SPAN><SPAN style="COLOR: blue">&gt; </SPAN></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"><SPAN style="COLOR: blue">&lt;/</SPAN><SPAN style="COLOR: maroon">FormRegion</SPAN><SPAN style="COLOR: blue">&gt;</SPAN></SPAN> </P>
<P>As noted above, the Name element corresponds to what gets passed in to GetFormRegionStorage. The title is what shows up in the Ribbon (in this case) as the visible name. This particular manifest specifies the formRegionType as "separate" meaning it has its own separate window. The other manifest in the project specifies "adjoining" which means it shares the window. The next three elements declare where the form region will be shown. In this case it shown in the reading Inspector, but not the reading pane in the explorer. RSS Articles don't have a Composing inspector, but it they did, this would be false as well. The addin element corresponds to the name of the addin to call when looking for the FormRegionStorage and the code. </P>
<P>I noted above that there was some weirdness with the icon. The good news is that this weirdness goes away when Office ships, but in interest of full disclosure, I'll tell you what I had to do to make it work in this sample. As you can guess from what it says here, the page icon is a resource in my dll. But in this case it *MUST* be "win32resource" not a managed resource. There is no simple way to add a win32resource to a dll in Visual Studio. As you can see I created a simple resource script – res.rc – in my project. I added a custom pre-build step to compile that rc file into a .res file. So far so good. But it turns out to get the res file linked into the dll, I had to manually edit the .csproj file of the project. Open up the .csproj file in notepad and look for the &lt;Win32Resource&gt; element and you'll see what I did. It turns out there is no way that I could find to get VS to add this element, but it is honored by msbuild and passes it on to the compiler as a /win32resource directive. Again, though, the requirement to do this will be going away soon. Stay tuned for further updates. </P>
<P>So, we have a Form Region manifest now, how do you register it? You associate it with a "Message class" – in this case IPM.Post.RSS – and add the path to the manifest as a named value under that key under FormRegions in the registry: </P>
<P>HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\FormRegions\&lt;MessageClass&gt;. </P>
<P>See the sample registry script in the project to get the exact location. </P>
<P>So that's the story on Form Regions for right now. As I said, this gets easier when Office releases – and easier yet in Orcas. Hope this is enough to get you going in VSTO 2005 SE.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/00/90/48/03/RSSMessages.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-00-90-48-03/RSSMessages.zip">RSSMessages.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Back in Redmond</title>
      <link>https://docs.microsoft.com/archive/blogs/tq/back-in-redmond</link>
      <pubDate>Tue, 10 Oct 2006 19:49:00 GMT</pubDate>
      <dc:creator><![CDATA[Thomas Quinn [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/tq/2006/10/10/back-in-redmond/</guid>
      <description><![CDATA[It's good to be home. But we had a great time in Europe and learned a ton. The best thing I learned...]]></description>
      <content:encoded><![CDATA[<P>It's good to be home. But we had a great time in Europe and learned a ton. The best thing I learned is that ISVs are using VSTO and using it well. Hopefully they learned from us as well. I have nothing but good things to say about the Frontline program, it was a rousing success.</P>
<P>I was happy to see that VB .NET is being used in several companies. VB suffered a bit of a downturn recently, but it survives and is being used extensively in Office customization. C# is being used extensively as well, of course. One customer asked if they could use ML to customize Office. The short answer is yes -- but you'd have to know what you are doing. If anyone is seriously interested, it could be a future blog post. But the easiest way to do this, of course, would be to write a simple addin in C# of VB and have that load your ML assembly that does all of the work -- that is one of the beauties of .NET, the Common Language Runtime.</P>
<P>&nbsp;Anyway, I'm going to sit right down and write myself a little Custom Form Region Cypress sample while I wait for my machines to upgrade to Vista.</P>]]></content:encoded>
    </item>
  </channel>
</rss>