<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Soledad Pano's Blog</title><link>http://weblogs.asp.net/spano/default.aspx</link><description>Just Technical Stuff </description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/spano" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>How to find Visual Studio command bars</title><link>http://feedproxy.google.com/~r/spano/~3/S4jqNmNqB9M/how-to-find-visual-studio-command-bars.aspx</link><pubDate>Tue, 07 Oct 2008 14:07:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6662584</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2008/10/07/how-to-find-visual-studio-command-bars.aspx#comments</comments><description>&lt;p&gt;When developing a Visual Studio Addin it is a common task to add custom commands to existing menus and toolbars. It is a common problem too, not to find the proper command bar (we have to traverse all command bars to see its names, the names are not unique, etc). In these two posts: &lt;a href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-ivsproffercommands-to-retrieve-a-visual-studio-commandbar.aspx" mce_href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-ivsproffercommands-to-retrieve-a-visual-studio-commandbar.aspx"&gt;Using IVsProfferCommands to retrieve a Visual Studio CommandBar&lt;/a&gt; and&amp;nbsp; &lt;a href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-enablevsiplogging-to-identify-menus-and-commands-with-vs-2005-sp1.aspx" mce_href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-enablevsiplogging-to-identify-menus-and-commands-with-vs-2005-sp1.aspx"&gt;Using EnableVSIPLogging to identify menus and commands with VS 2005 + SP1&lt;/a&gt; it is very well explained how to solve this problem.&lt;/p&gt;  &lt;p&gt;The answer relies on the fact that every toolbar and menu is uniquely identified in Visual Studio by a &lt;b&gt;GUID,&lt;/b&gt;&lt;b&gt;Id&lt;/b&gt; pair. In order to see which is the GUID, Id pair for a given command, you must:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Add or change the registry key HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\General\EnableVSIPLogging to 1.&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;img src="http://weblogs.asp.net/blogs/spano/VSCommandRegKey.png" mce_src="http://weblogs.asp.net/blogs/spano/VSCommandRegKey.png"&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;Click on the toolbar or menu you want identify while keeping CTRL+SHIFT pressed. This will show a dialog with the command bar properties. Take note of the &lt;b&gt;Guid&lt;/b&gt; and the &lt;b&gt;CmdID&lt;/b&gt;:&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;img src="http://weblogs.asp.net/blogs/spano/VSCommandGuid.png" mce_src="http://weblogs.asp.net/blogs/spano/VSCommandGuid.png"&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;From the Addin, use the following code to add your command in the desired command bar:&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;private&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; AddMyCustomCommand()        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;{&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;…&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;       &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;     &lt;/p&gt;&lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;         &lt;p&gt;&amp;nbsp;&lt;/p&gt;       &lt;/span&gt;&lt;/p&gt;     &lt;span style="font-size: 10pt; color: blue;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; object&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;[] contextGuids = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;object&lt;/span&gt;[0];        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; myCommand = ((&lt;span style="color: rgb(43, 145, 175);"&gt;Commands2&lt;/span&gt;)&lt;span style="color: blue;"&gt;this&lt;/span&gt;._applicationObject.Commands).AddNamedCommand2(&lt;span style="color: blue;"&gt;this&lt;/span&gt;._addInInstance,&amp;nbsp; &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; partialCommandName,&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;displayName, tooltip, &lt;span style="color: blue;"&gt;true&lt;/span&gt;, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: blue;"&gt;ref&lt;/span&gt; contextGuids,        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(&lt;span style="color: blue;"&gt;int&lt;/span&gt;)&lt;span style="color: rgb(43, 145, 175);"&gt;vsCommandStatus&lt;/span&gt;.vsCommandStatusSupported + (&lt;span style="color: blue;"&gt;int&lt;/span&gt;)&lt;span style="color: rgb(43, 145, 175);"&gt;vsCommandStatus&lt;/span&gt;.vsCommandStatusEnabled,        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(&lt;span style="color: blue;"&gt;int&lt;/span&gt;)&lt;span style="color: rgb(43, 145, 175);"&gt;vsCommandStyle&lt;/span&gt;.vsCommandStyleText,&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;vsCommandControlType&lt;/span&gt;.vsCommandControlTypeButton);        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;b&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CommandBar&lt;/span&gt; ownerBar = FindCommandBar(&lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Guid&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"{9AEB9524-82C6-40B9-9285-8D85D3DBD4C4}"&lt;/span&gt;), 1280); &lt;span style="color: green;"&gt;           &lt;p&gt;&amp;nbsp;&lt;/p&gt;         &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;myControl = workflowCommand.AddControl(ownerBar, 1) &lt;span style="color: blue;"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;CommandBarButton&lt;/span&gt;;&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&amp;nbsp;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;private&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;CommandBar&lt;/span&gt; FindCommandBar(&lt;span style="color: rgb(43, 145, 175);"&gt;Guid&lt;/span&gt; guidCmdGroup, &lt;span style="color: blue;"&gt;uint&lt;/span&gt; menuID)        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;{       &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: green;"&gt;// Retrieve IVsProfferComands via DTE's IOleServiceProvider interface         &lt;p&gt;&amp;nbsp;&lt;/p&gt;       &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IOleServiceProvider&lt;/span&gt; sp = (&lt;span style="color: rgb(43, 145, 175);"&gt;IOleServiceProvider&lt;/span&gt;)_applicationObject;        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Guid&lt;/span&gt; guidSvc = &lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;IVsProfferCommands&lt;/span&gt;).GUID;        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Object&lt;/span&gt; objService;        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;sp.QueryService(&lt;span style="color: blue;"&gt;ref&lt;/span&gt; guidSvc, &lt;span style="color: blue;"&gt;ref&lt;/span&gt; guidSvc, &lt;span style="color: blue;"&gt;out&lt;/span&gt; objService);        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IVsProfferCommands&lt;/span&gt; vsProfferCmds = (&lt;span style="color: rgb(43, 145, 175);"&gt;IVsProfferCommands&lt;/span&gt;)objService;        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt; vsProfferCmds.FindCommandBar(&lt;span style="color: rgb(43, 145, 175);"&gt;IntPtr&lt;/span&gt;.Zero, &lt;span style="color: blue;"&gt;ref&lt;/span&gt; guidCmdGroup, menuID) &lt;span style="color: blue;"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;CommandBar&lt;/span&gt;;        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;ComImport&lt;/span&gt;,&lt;span style="color: rgb(43, 145, 175);"&gt;Guid&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"6D5140C1-7436-11CE-8034-00AA006009FA"&lt;/span&gt;),        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: rgb(43, 145, 175);" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;InterfaceTypeAttribute&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;ComInterfaceType&lt;/span&gt;.InterfaceIsIUnknown)]        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt; color: blue;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;internal&lt;/span&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;IOleServiceProvider         &lt;p&gt;&amp;nbsp;&lt;/p&gt;       &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;{       &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;PreserveSig&lt;/span&gt;]        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt; QueryService([&lt;span style="color: rgb(43, 145, 175);"&gt;In&lt;/span&gt;]&lt;span style="color: blue;"&gt;ref&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Guid&lt;/span&gt; guidService, [&lt;span style="color: rgb(43, 145, 175);"&gt;In&lt;/span&gt;]&lt;span style="color: blue;"&gt;ref&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Guid&lt;/span&gt; riid,        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-top: 0in; line-height: normal;"&gt;&lt;span style="font-size: 10pt;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;MarshalAs&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;UnmanagedType&lt;/span&gt;.Interface)] &lt;span style="color: blue;"&gt;out&lt;/span&gt; System.&lt;span style="color: rgb(43, 145, 175);"&gt;Object&lt;/span&gt; obj);        &lt;p&gt;&amp;nbsp;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%;" courier="" new="" ;="" mso-no-proof:="" yes=""&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6662584" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/S4jqNmNqB9M" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2008/10/07/how-to-find-visual-studio-command-bars.aspx</feedburner:origLink></item><item><title>CodeCamp Buenos Aires 2008</title><link>http://feedproxy.google.com/~r/spano/~3/5Hr7WlNpUjM/codecamp-buenos-aires-2008.aspx</link><pubDate>Sun, 05 Oct 2008 14:13:18 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6658537</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2008/10/05/codecamp-buenos-aires-2008.aspx#comments</comments><description>&lt;p&gt;I attended yesterday to the &lt;a href="http://www.microsoft.com/argentina/codecamp/"&gt;Microsoft Code Camp&lt;/a&gt; event at Buenos Aires. It was fun! &lt;/p&gt;  &lt;p&gt;Here's a picture of the &lt;a href="http://www.lagash.com/"&gt;Lagash&lt;/a&gt; stand:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img src="http://weblogs.asp.net/blogs/spano/CodeCamp04.JPG" /&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6658537" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/5Hr7WlNpUjM" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/spano/archive/2008/10/05/codecamp-buenos-aires-2008.aspx</feedburner:origLink></item><item><title>UI Automation Article Published on Level Extreme</title><link>http://feedproxy.google.com/~r/spano/~3/qfOYHJtjWoo/ui-automation-article-published-on-level-extreme.aspx</link><pubDate>Wed, 12 Mar 2008 17:38:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5957057</guid><dc:creator>spano</dc:creator><slash:comments>9</slash:comments><comments>http://weblogs.asp.net/spano/archive/2008/03/12/ui-automation-article-published-on-level-extreme.aspx#comments</comments><description>&lt;p&gt;On this month's edition of the  &lt;a href="http://www.levelextreme.net/" mce_href="http://www.levelextreme.net/"&gt;Level Extreme .Net Magazine&lt;/a&gt;, my article about &lt;a href="http://www.levelextreme.net/ViewPageArticle.aspx?Session=3143664868567841524F303D2031476A37344564662F76543075542F4C2B70546C34513D3D" mce_href="http://www.levelextreme.net/ViewPageArticle.aspx?Session=3143664868567841524F303D2031476A37344564662F76543075542F4C2B70546C34513D3D"&gt;Building an UI Automation Client Application&lt;/a&gt; was published.  The article walks through building a client application for automating a win 32 target application (the Windows Address Book). The idea is to show through simple code snippets how to use the &lt;a href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx" mce_href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx"&gt;UI Automation&lt;/a&gt; API for manipulating a target application programmatically through its UI. It shows how to find the UI elements, and how to work with the UI Automation patterns and handle events. The sample client application code contains further examples and can be downloaded from the article's page. Hope you read it!&lt;/p&gt;&lt;p&gt;&lt;img src="http://weblogs.asp.net/blogs/spano/LevelExtremeMarch2008.jpg" title="March edition Level Extreme" alt="March edition Level Extreme" mce_src="http://weblogs.asp.net/blogs/spano/LevelExtremeMarch2008.jpg" height="172" width="134"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Read more on the magazine from &lt;a href="http://blog.salias.com.ar/2008/03/level-extreme-net-de-marzo.html" mce_href="http://blog.salias.com.ar/2008/03/level-extreme-net-de-marzo.html"&gt;Martin Salias&lt;/a&gt;.&lt;br&gt;&lt;/p&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5957057" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/qfOYHJtjWoo" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/WPF/default.aspx">WPF</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2008/03/12/ui-automation-article-published-on-level-extreme.aspx</feedburner:origLink></item><item><title>CCF: Listening to External Application Events</title><link>http://feedproxy.google.com/~r/spano/~3/KkD8tnggki4/ccf-listening-to-external-application-events.aspx</link><pubDate>Tue, 15 Jan 2008 15:05:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5605091</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2008/01/15/ccf-listening-to-external-application-events.aspx#comments</comments><description>&lt;P&gt;It is often necessary to listen to external application UI events when automating applications in CCF. For example, we may need to save a value in the Context if the user presses a button, or do something when an alert dialog appears. There are many ways we can handle events. In CCF 2008, the Hosted Application Toolkit (HAT) provides an easy way to listen to them. If not using HAT we can hook to events using the UIAutomation or MSAA (Microsoft Active Accessibility) APIs within our own application adapters.&lt;/P&gt;
&lt;H3&gt;Events in HAT&lt;/H3&gt;
&lt;P&gt;When we configure a hosted application for using an Automation Adapter, this adapter listens to the application events. We can hook and unhook to these events using the CCF's WF activities &lt;STRONG&gt;RegisterActionForEvent&lt;/STRONG&gt; (see figure bellow)&amp;nbsp; and &lt;STRONG&gt;UnregisterActionForEvent&lt;/STRONG&gt; respectively.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;IMG src="http://weblogs.asp.net/blogs/spano/hat_registerEvent.JPG" mce_src="http://weblogs.asp.net/blogs/spano/hat_registerEvent.JPG"&gt;&lt;/P&gt;
&lt;P&gt;It is the Data Driven Adapter (DDA) the one who throws the &lt;STRONG&gt;ControlChanged&lt;/STRONG&gt; event (to which the activity subscribes). The arguments of the event consists of eventTypeName, controlName and controlValue.&lt;/P&gt;
&lt;P&gt;For example, the WinDataDrivenAdapter that CCF provides supports the following event types:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;SetControlValue: When the DDA set's a control's value. &lt;/LI&gt;
&lt;LI&gt;ExecuteControlAction: When the DDA executes a control. &lt;/LI&gt;
&lt;LI&gt;ContextChanged: When the context changes. &lt;/LI&gt;
&lt;LI&gt;MenuShown: When a menu is shown &lt;/LI&gt;
&lt;LI&gt;WindowShown: When a window is shown &lt;/LI&gt;
&lt;LI&gt;WindowDisappeared: When a window is closed &lt;/LI&gt;
&lt;LI&gt;LostFocus &lt;/LI&gt;
&lt;LI&gt;SetFocus &lt;/LI&gt;
&lt;LI&gt;CheckBoxSet &lt;/LI&gt;
&lt;LI&gt;CheckBoxCleared &lt;/LI&gt;
&lt;LI&gt;RadioButtonSet &lt;/LI&gt;
&lt;LI&gt;RadioButtonCleared &lt;/LI&gt;
&lt;LI&gt;ButtonPressed &lt;/LI&gt;
&lt;LI&gt;ButtonReleased &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;There are some tricks about how to use this events, for example: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;4-6: For menu and window events we must not register with the control's friendly name that we set in the databindings section of the AppInitString. We must specify the window or menu's caption instead.&lt;/EM&gt;&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;7-14: For these events the related control must be previously found on the UI. You can use the FindControl activity to ensure that the control is successfully found. When the DDA finds the control it registers it in a KnownControls collection. Only for those registered controls the events are thrown.&lt;/EM&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Custom DDAs or Legacy Adapters&lt;/H3&gt;
&lt;P&gt;If we need to handle events from a custom DDA or from a legacy adapter we can use win32 or accessibility APIs. If we use a custom DDA we can throw a ControlChanged event in order to use the WF/Automation activities mentioned before.&lt;/P&gt;
&lt;H4&gt;WinEvents&lt;/H4&gt;
&lt;P&gt;A low level approach is to use the SetWinEventHook and UnhookWinEvent functions from user32.dll. When we hook for events we specify the callback function that will handle the events. You can see the list of &lt;A href="http://msdn2.microsoft.com/en-us/library/ms697187(VS.85).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms697187(VS.85).aspx"&gt;supported events&lt;/A&gt; and its constants in the MSAA SDK documentation on msdn.&lt;/P&gt;
&lt;P&gt;In order to show some sample code, here are the user32 functions imports:&lt;/P&gt;
&lt;P&gt;[&lt;SPAN class=cb1&gt;Flags&lt;/SPAN&gt;]&lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb2&gt;internal&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;enum&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;SetWinEventHookFlags&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;{&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WINEVENT_INCONTEXT = 4,&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WINEVENT_OUTOFCONTEXT = 0,&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WINEVENT_SKIPOWNPROCESS = 2,&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WINEVENT_SKIPOWNTHREAD = 1&lt;/P&gt;
&lt;P class=cl&gt;}&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red163\green21\blue21;\red0\green0\blue255;}??\fs20         [\cf3 DllImport\cf0 (\cf4 "user32.dll"\cf0 , SetLastError = \cf5 true\cf0 )]\par ??        \cf5 internal\cf0  \cf5 static\cf0  \cf5 extern\cf0  \cf3 IntPtr\cf0  SetWinEventHook(\cf5 int\cf0  eventMin, \cf5 int\cf0  eventMax, \cf3 IntPtr\cf0  hmodWinEventProc, \cf3 WinEventProc\cf0  lpfnWinEventProc, \cf5 int\cf0  idProcess, \cf5 int\cf0  idThread, \cf3 SetWinEventHookFlags\cf0  dwflags);\par ??}
--&gt;&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN class=cb1&gt;internal&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;delegate&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;void&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;WinEventProc&lt;/SPAN&gt;(&lt;SPAN class=cb2&gt;IntPtr&lt;/SPAN&gt; hWinEventHook, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; iEvent, &lt;SPAN class=cb2&gt;IntPtr&lt;/SPAN&gt; hWnd, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; idObject, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; idChild, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; dwEventThread, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; dwmsEventTime);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;[&lt;SPAN style="COLOR: #2b91af"&gt;DllImport&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"user32.dll"&lt;/SPAN&gt;, SetLastError = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;)]&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;extern&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt; SetWinEventHook(&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; eventMin, &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; eventMax, &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt; hmodWinEventProc, &lt;SPAN style="COLOR: #2b91af"&gt;WinEventProc&lt;/SPAN&gt; lpfnWinEventProc, &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; idProcess, &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; idThread, &lt;SPAN style="COLOR: #2b91af"&gt;SetWinEventHookFlags&lt;/SPAN&gt; dwflags);&lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;[&lt;SPAN class=cb1&gt;DllImport&lt;/SPAN&gt;(&lt;SPAN class=cb2&gt;"user32.dll"&lt;/SPAN&gt;, SetLastError = &lt;SPAN class=cb3&gt;true&lt;/SPAN&gt;)]&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb3&gt;internal&lt;/SPAN&gt; &lt;SPAN class=cb3&gt;static&lt;/SPAN&gt; &lt;SPAN class=cb3&gt;extern&lt;/SPAN&gt; &lt;SPAN class=cb3&gt;int&lt;/SPAN&gt; UnhookWinEvent(&lt;SPAN class=cb1&gt;IntPtr&lt;/SPAN&gt; hWinEventHook);&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20     \cf3 internal\cf0  \cf3 delegate\cf0  \cf3 void\cf0  \cf4 WinEventProc\cf0 (\cf4 IntPtr\cf0  hWinEventHook, \cf3 int\cf0  iEvent, \cf4 IntPtr\cf0  hWnd, \cf3 int\cf0  idObject, \cf3 int\cf0  idChild, \cf3 int\cf0  dwEventThread, \cf3 int\cf0  dwmsEventTime);\par ??}
--&gt;
&lt;STYLE type=text/css&gt;









.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;DIV class=cf&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red163\green21\blue21;\red0\green0\blue255;}??\fs20 [\cf3 DllImport\cf0 (\cf4 "user32.dll"\cf0 , SetLastError = \cf5 true\cf0 )]\par ??\cf5 internal\cf0  \cf5 static\cf0  \cf5 extern\cf0  \cf5 int\cf0  UnhookWinEvent(\cf3 IntPtr\cf0  hWinEventHook);\par ??}
--&gt;
&lt;STYLE type=text/css&gt;








.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: #2b91af; }
.cb2 { color: #a31515; }
.cb3 { color: blue; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf1 private\cf0  \cf1 void\cf0  EventCallback(\cf4 IntPtr\cf0  hWinEventHook, \cf1 int\cf0  iEvent, \cf4 IntPtr\cf0  hWnd, \cf1 int\cf0  idObject, \cf1 int\cf0  idChild, \cf1 int\cf0  dwEventThread, \cf1 int\cf0  dwmsEventTime)\par ??\{\par ??    \cf5 //get accObj from handler\par ??\cf0     \cf5 //get accObj's name, role, etc...\par ??\cf0     ...\par ??    \cf1 switch\cf0  (iEvent)\par ??    \{\par ??         \cf1 case\cf0  0x10: \cf5 //WinEvent.EVENT_SYSTEM_DIALOGSTART\par ??\cf0              \cf1 if\cf0  (role.Equals(\cf4 localize\cf0 .ACC_ROLE_TEXT_WINDOW))\par ??             \{\par ??                  \cf1 if\cf0  (name.Length &amp;gt; 0)\par ??                  \{\par ??                      \cf5 //throw ControlChangedEvent\par ??\cf0                        \cf1 this\cf0 .ControlChanged(accObj, \cf1 new\cf0  \cf4 ControlChangedEventArgs\cf0 (\cf6 "DialogStart"\cf0 , controlName, \cf1 string\cf0 .Empty));\par ??                  \}\par ??             \}\par ??             \cf1 break\cf0 ;\par ??        ...\par ??    \}\par ??\}}
--&gt;
&lt;STYLE type=text/css&gt;





.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
.cb3 { color: green; }
.cb4 { color: #a31515; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;P&gt;Here's how we can subscribe to win events from our custom adapter:&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red43\green145\blue175;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue255;}??\fs20 \cf1 WinEventProc\cf0  wep = \cf4 new\cf0  \cf1 WinEventProc\cf0 (\cf4 this\cf0 .EventCallback);\par ??SetWinEventHook(1, 0x7fffffff, \cf1 IntPtr\cf0 .Zero, wep, 0, threadId, \cf1 SetWinEventHookFlags\cf0 .WINEVENT_OUTOFCONTEXT);\par ??}
--&gt;
&lt;STYLE type=text/css&gt;



.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: #2b91af; }
.cb2 { color: blue; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;WinEventProc&lt;/SPAN&gt; wep = &lt;SPAN class=cb2&gt;new&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;WinEventProc&lt;/SPAN&gt;(&lt;SPAN class=cb2&gt;this&lt;/SPAN&gt;.EventCallback);&lt;/P&gt;
&lt;P class=cl&gt;SetWinEventHook(1, 0x7fffffff, &lt;SPAN class=cb1&gt;IntPtr&lt;/SPAN&gt;.Zero, wep, 0, threadId, &lt;SPAN class=cb1&gt;SetWinEventHookFlags&lt;/SPAN&gt;.WINEVENT_OUTOFCONTEXT);&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And finally how to react to events in the event handler method: &lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;private&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;void&lt;/SPAN&gt; EventCallback(&lt;SPAN class=cb2&gt;IntPtr&lt;/SPAN&gt; hWinEventHook, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; iEvent, &lt;SPAN class=cb2&gt;IntPtr&lt;/SPAN&gt; hWnd, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; idObject, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; idChild, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; dwEventThread, &lt;SPAN class=cb1&gt;int&lt;/SPAN&gt; dwmsEventTime)&lt;/P&gt;
&lt;P class=cl&gt;{&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;//get accObj from handler&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;//get accObj's name, role, etc...&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;switch&lt;/SPAN&gt; (iEvent)&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;case&lt;/SPAN&gt; 0x10: &lt;SPAN class=cb3&gt;//EVENT_SYSTEM_DIALOGSTART&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;if&lt;/SPAN&gt; (role.Equals(&lt;SPAN class=cb2&gt;localize&lt;/SPAN&gt;.ACC_ROLE_TEXT_WINDOW))&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;if&lt;/SPAN&gt; (name.Length &amp;gt; 0)&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;//throw ControlChangedEvent&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;this&lt;/SPAN&gt;.ControlChanged(accObj, &lt;SPAN class=cb1&gt;new&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;ControlChangedEventArgs&lt;/SPAN&gt;(&lt;SPAN class=cb4&gt;"DialogStart"&lt;/SPAN&gt;, controlName, &lt;SPAN class=cb1&gt;string&lt;/SPAN&gt;.Empty));&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;break&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;}&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H4&gt;UIAutomation&lt;/H4&gt;
&lt;P&gt;Another option is to use the UIAutomation accessibility API, included on .Net framework 3.0 to hook to events from custom adapters. The Automation element provides the following static methods to hook to different event on different controls:&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;\red43\green145\blue175;}??\fs20         \cf3 // Summary:\par ??\cf0         \cf3 //     Registers a method that handles UI Automation events.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 // Parameters:\par ??\cf0         \cf3 //   scope:\par ??\cf0         \cf3 //     The scope of events to be handled; that is, whether they are on the element\par ??\cf0         \cf3 //     itself, or on its ancestors and descendants.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   eventHandler:\par ??\cf0         \cf3 //     The method to call when the specified event occurs.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   element:\par ??\cf0         \cf3 //     The UI Automation element to associate with the event handler.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   eventId:\par ??\cf0         \cf3 //     The identifier for the event the method will handle.\par ??\cf0         \cf4 public\cf0  \cf4 static\cf0  \cf4 void\cf0  AddAutomationEventHandler(\cf5 AutomationEvent\cf0  eventId, \cf5 AutomationElement\cf0  element, \cf5 TreeScope\cf0  scope, \cf5 AutomationEventHandler\cf0  eventHandler);\par ??        \cf3 //\par ??\cf0         \cf3 // Summary:\par ??\cf0         \cf3 //     Registers a method that will handle focus-changed events.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 // Parameters:\par ??\cf0         \cf3 //   eventHandler:\par ??\cf0         \cf3 //     The method to call when the event occurs.\par ??\cf0         \cf4 public\cf0  \cf4 static\cf0  \cf4 void\cf0  AddAutomationFocusChangedEventHandler(\cf5 AutomationFocusChangedEventHandler\cf0  eventHandler);\par ??        \cf3 //\par ??\cf0         \cf3 // Summary:\par ??\cf0         \cf3 //     Registers a method that will handle property-changed events.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 // Parameters:\par ??\cf0         \cf3 //   scope:\par ??\cf0         \cf3 //     The scope of events to be handled; that is, whether they are on the element\par ??\cf0         \cf3 //     itself, or on its ancestors and children.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   properties:\par ??\cf0         \cf3 //     The UI Automation properties of interest.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   eventHandler:\par ??\cf0         \cf3 //     The method to call when the event occurs.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   element:\par ??\cf0         \cf3 //     The UI Automation element with which to associate the event handler.\par ??\cf0         \cf4 public\cf0  \cf4 static\cf0  \cf4 void\cf0  AddAutomationPropertyChangedEventHandler(\cf5 AutomationElement\cf0  element, \cf5 TreeScope\cf0  scope, \cf5 AutomationPropertyChangedEventHandler\cf0  eventHandler, \cf4 params\cf0  \cf5 AutomationProperty\cf0 [] properties);\par ??        \cf3 //\par ??\cf0         \cf3 // Summary:\par ??\cf0         \cf3 //     Registers the method that will handle structure-changed events.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 // Parameters:\par ??\cf0         \cf3 //   scope:\par ??\cf0         \cf3 //     The scope of events to be handled; that is, whether they are on the element\par ??\cf0         \cf3 //     itself, or on its ancestors and descendants.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   eventHandler:\par ??\cf0         \cf3 //     The method to call when the structure-changed event occurs.\par ??\cf0         \cf3 //\par ??\cf0         \cf3 //   element:\par ??\cf0         \cf3 //     The UI Automation element with which to associate the event handler.\par ??\cf0         \cf4 public\cf0  \cf4 static\cf0  \cf4 void\cf0  AddStructureChangedEventHandler(\cf5 AutomationElement\cf0  element, \cf5 TreeScope\cf0  scope, \cf5 StructureChangedEventHandler\cf0  eventHandler);\par ??}
--&gt;
&lt;STYLE type=text/css&gt;

.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: green; }
.cb2 { color: blue; }
.cb3 { color: #2b91af; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;//Registers a method that handles UI Automation events.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb2&gt;public&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;static&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;void&lt;/SPAN&gt; AddAutomationEventHandler(&lt;SPAN class=cb3&gt;AutomationEvent&lt;/SPAN&gt; eventId, &lt;SPAN class=cb3&gt;AutomationElement&lt;/SPAN&gt; element, &lt;SPAN class=cb3&gt;TreeScope&lt;/SPAN&gt; scope, &lt;SPAN class=cb3&gt;AutomationEventHandler&lt;/SPAN&gt; eventHandler);&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;//Registers a method that will handle focus-changed events.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb2&gt;public&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;static&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;void&lt;/SPAN&gt; AddAutomationFocusChangedEventHandler(&lt;SPAN class=cb3&gt;AutomationFocusChangedEventHandler&lt;/SPAN&gt; eventHandler);&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;//Registers a method that will handle property-changed events.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb2&gt;public&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;static&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;void&lt;/SPAN&gt; AddAutomationPropertyChangedEventHandler(&lt;SPAN class=cb3&gt;AutomationElement&lt;/SPAN&gt; element, &lt;SPAN class=cb3&gt;TreeScope&lt;/SPAN&gt; scope, &lt;SPAN class=cb3&gt;AutomationPropertyChangedEventHandler&lt;/SPAN&gt; eventHandler, &lt;SPAN class=cb2&gt;params&lt;/SPAN&gt; &lt;SPAN class=cb3&gt;AutomationProperty&lt;/SPAN&gt;[] properties);&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;//Registers the method that will handle structure-changed events.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb2&gt;public&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;static&lt;/SPAN&gt; &lt;SPAN class=cb2&gt;void&lt;/SPAN&gt; AddStructureChangedEventHandler(&lt;SPAN class=cb3&gt;AutomationElement&lt;/SPAN&gt; element, &lt;SPAN class=cb3&gt;TreeScope&lt;/SPAN&gt; scope, &lt;SPAN class=cb3&gt;StructureChangedEventHandler&lt;/SPAN&gt; eventHandler);&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The UIAutomation API is much more friendly to use, but some times it takes too long for the event to reach the handler. You should be very precise when setting the element and scope to subscribe the event to. You can find more information about this API and sample code on my previous post about &lt;A href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx" mce_href="http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx"&gt;WPF Accessibility&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5605091" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/KkD8tnggki4" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/CCF/default.aspx">CCF</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2008/01/15/ccf-listening-to-external-application-events.aspx</feedburner:origLink></item><item><title>Hosting a Window Form Control in a SharePoint WebPart</title><link>http://feedproxy.google.com/~r/spano/~3/IY2X-EXKeko/hosting-a-window-form-control-in-a-sharepoint-webpart.aspx</link><pubDate>Fri, 07 Dec 2007 01:48:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5415151</guid><dc:creator>spano</dc:creator><slash:comments>1</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/12/06/hosting-a-window-form-control-in-a-sharepoint-webpart.aspx#comments</comments><description>&lt;P&gt;Some months ago I posted about &lt;A href="http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx" mce_href="http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx"&gt;Hosting a Windows Form Control in a web page&lt;/A&gt;. I explained there how we can run a WinForm control from Internet Explorer by hosting it in a web page using the &amp;lt;object&amp;gt; tag. Now suppose you want to use the same solution in a custom web part that is included in a Sharepoint site. I will describe here where the control library should be placed and how it can be referenced from the web part.&lt;/P&gt;
&lt;P&gt;When we develop a custom web part, we place its resources under the _wpresources web site, into a folder named &amp;lt;WebPartAssemblyName&amp;gt;/&amp;lt;WebPartAssemblyVersion&amp;gt;__&amp;lt;PublicKeyToken&amp;gt;. You can create there a subfolder (named "bin" por example) to place the win control assembly. This folder must have execute permissions set to Script Only (not Script and Executables as is the default under a SharePoint site). The picture bellow shows the resulting structure when placing the win form control assembly in a web part called MyCustomWebPart that is part of the MyCustomWebParts assembly: &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;IMG src="http://weblogs.asp.net/blogs/spano/sharepointWinControls.JPG" mce_src="http://weblogs.asp.net/blogs/spano/sharepointWinControls.JPG"&gt; &lt;/P&gt;
&lt;P&gt;Once the control assembly is placed in the correct place, the web part can render the &amp;lt;object&amp;gt; tag within the RenderWebPart method:&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red128\green128\blue128;\red0\green128\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 namespace\cf0  WorkbookCart\par ??\{\par ??    \cf4 ///\cf5  \cf4 &amp;lt;summary&amp;gt;\par ??\cf0     \cf4 ///\cf5  Web part que permite agregar al carrito, imprimir y exportar a Power Point la car\'e1tula u hoja Excel del sitio al que pertenece. \par ??\cf0     \cf4 ///\cf5  Deben setearse antes de ser usada las propiedades SheetTitle, WorkbookUrl y NamedItem. SheetTitle es obligatoria siempre. \par ??\cf0     \cf4 ///\cf5  Las dos \'faltimas son obligatorias si se trata de una hoja excel. Si se trata de una car\'e1tula se dejan en blanco.\par ??\cf0     \cf4 ///\cf5  Los botones dibujados en la web part permiten:\par ??\cf0     \cf4 ///\cf5  1- Agregar el sitio actual al carrito (se agrega a la lista del carrito un \'edtem con los valores de las properties seteadas a la web part el sitio actual.\par ??\cf0     \cf4 ///\cf5  2- Agregar el sitio actual y todos sus subsitios al carrito\par ??\cf0     \cf4 ///\cf5  3- Imprimir la hoja o car\'e1tula \par ??\cf0     \cf4 ///\cf5  4- Exportar a power point \par ??\cf0     \cf4 ///\cf5  \cf4 &amp;lt;/summary&amp;gt;\par ??\cf0     [\cf6 XmlRoot\cf0 (Namespace = \cf7 "WorkbookCart"\cf0 )]\par ??    \cf1 public\cf0  \cf1 class\cf0  \cf6 AddToCartWebPart\cf0  : \cf6 BaseCartWebPart\par ??\cf0     \{\par ??}
--&gt;&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; MyCustomWebParts&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp; [&lt;SPAN style="COLOR: #2b91af"&gt;XmlRoot&lt;/SPAN&gt;(Namespace = &lt;SPAN style="COLOR: #a31515"&gt;"MyCustomWebParts"&lt;/SPAN&gt;)]&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;MyCustomWebPart&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp; {&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;\red0\green128\blue0;}??\fs20         \cf3 protected\cf0  \cf3 override\cf0  \cf3 void\cf0  RenderWebPart(\cf4 HtmlTextWriter\cf0  output)\par ??        \{\par ??            EnsureChildControls();\par ??\par ??            \cf3 string\cf0  list = \cf4 String\cf0 .Format(\cf5 "\{0\}*\{1\}*\{2\}"\cf0 , _title, _workbookUrl, _namedItem);\par ??\par ??            output.Write(ReplaceTokens(GetCartScriptBlock(list)));\par ??            output.Write(ReplaceTokens(GetCartDefinitionBlock()));\par ??\par ??            \cf3 string\cf0  resourcePath = \cf4 SPWebPartManager\cf0 .GetClassResourcePath(\cf4 SPContext\cf0 .Current.Web, GetType());\par ??            output.Write( ReplaceTokens(\cf5 "&amp;lt;h1&amp;gt;Windows Form Control:&amp;lt;/h1&amp;gt;"\cf0  +\par ??                \cf5 "&amp;lt;object id='MyWinControl' classid='"\cf0  + resourcePath + \cf5 "/bin/WindowsControlLibrary1.dll#WindowsControlLibrary1.UserControl1'"\cf0  +\par ??                \cf5 "height='300' width='800' VIEWASTEXT&amp;gt;"\cf0  +\par ??                \cf5 "  &amp;lt;PARAM name='Prop1Str' value='blabla'  valuetype='data'&amp;gt;"\cf0  +\par ??                \cf5 "  &amp;lt;PARAM name='Prop2Int' value='2' valuetype='data'&amp;gt;"\cf0  +\par ??                \cf5 " &amp;lt;/object&amp;gt;"\cf0 ));\par ??\par ??\par ??  \cf6 //          SPWeb web = SPContext.Current.Web;\par ??\cf0   \cf6 //          string resourcePath = SPWebPartManager.GetClassResourcePath(web, GetType());\par ??\cf0   \cf6 //          output.Write(ReplaceTokens("&amp;lt;h1&amp;gt;Windows Form Control with param:&amp;lt;/h1&amp;gt;" +     \par ??\cf0   \cf6 //"&amp;lt;object id='MyWinControl' classid='"+resourcePath+"/bin/WindowsControlLibrary1.dll#WindowsControlLibrary1.UserControl1'"+            \par ??\cf0   \cf6 //        "height='300' width='800' VIEWASTEXT&amp;gt;"+\par ??\cf0   \cf6 //        "&amp;lt;PARAM name='Title' value='SOLE desde web part'  valuetype='data'&amp;gt;"+\par ??\cf0   \cf6 //        "&amp;lt;PARAM name='FontSize' value='0.2' valuetype='data'&amp;gt;"+\par ??\cf0   \cf6 //        "hola"+\par ??\cf0   \cf6 //        "&amp;lt;/object&amp;gt;"));\par ??\par ??\cf0             \cf3 base\cf0 .RenderWebPart(output);\par ??        \}\par ??}
--&gt;
&lt;STYLE type=text/css&gt;




.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
.cb3 { color: #a31515; }
.cb4 { color: green; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;protected&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;override&lt;/SPAN&gt; &lt;SPAN class=cb1&gt;void&lt;/SPAN&gt; RenderWebPart(&lt;SPAN class=cb2&gt;HtmlTextWriter&lt;/SPAN&gt; output)&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EnsureChildControls();&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;string&lt;/SPAN&gt; resourcePath = &lt;SPAN class=cb2&gt;SPWebPartManager&lt;/SPAN&gt;.GetClassResourcePath(&lt;SPAN class=cb2&gt;SPContext&lt;/SPAN&gt;.Current.Web, GetType());&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output.Write( ReplaceTokens(&lt;SPAN class=cb3&gt;"&amp;lt;h1&amp;gt;Windows Form Control:&amp;lt;/h1&amp;gt;"&lt;/SPAN&gt; +&lt;/P&gt;
&lt;P class=cl&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;"&amp;lt;object id='MyWinControl' classid='"&lt;/SPAN&gt; + resourcePath +&lt;SPAN class=cb3&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;STRONG&gt;&lt;SPAN class=cb3&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "/bin/WindowsControlLibrary1.dll#WindowsControlLibrary1.UserControl1'"&lt;/SPAN&gt; +&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;"height='300' width='800' VIEWASTEXT&amp;gt;"&lt;/SPAN&gt; +&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;"&amp;nbsp; &amp;lt;PARAM name='Prop1Str' value='blabla'&amp;nbsp; valuetype='data'&amp;gt;"&lt;/SPAN&gt; +&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;"&amp;nbsp; &amp;lt;PARAM name='Prop2Int' value='2' valuetype='data'&amp;gt;"&lt;/SPAN&gt; +&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb3&gt;" &amp;lt;/object&amp;gt;"&lt;/SPAN&gt;));&lt;/P&gt;
&lt;P class=cl mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=cb1&gt;base&lt;/SPAN&gt;.RenderWebPart(output);&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P class=cl&gt;} &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5415151" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/IY2X-EXKeko" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/Sharepoint/default.aspx">Sharepoint</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/12/06/hosting-a-window-form-control-in-a-sharepoint-webpart.aspx</feedburner:origLink></item><item><title>CCF HAT - Making use of DDAs from Legacy Adapters</title><link>http://feedproxy.google.com/~r/spano/~3/F3xK26_0Am0/ccf-hat-making-use-of-ddas-from-legacy-adapters.aspx</link><pubDate>Wed, 31 Oct 2007 01:34:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4841509</guid><dc:creator>spano</dc:creator><slash:comments>1</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/10/30/ccf-hat-making-use-of-ddas-from-legacy-adapters.aspx#comments</comments><description>&lt;P&gt;Although Data Driven Adapters (DDAs) are mainly designed for Automation Adapters in HAT, we can make use of them from legacy adapters, too. Here's an example of an external VB application, which is configured to use a legacy application adapter and a WinDataDrivenAdapter with the corresponding bindings:&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red255\green0\blue0;\red0\green0\blue0;}??\fs20 \cf1 &amp;lt;?\cf3 xml\cf1  \cf4 version\cf1 =\cf0 "\cf1 1.0\cf0 "\cf1  \cf4 encoding\cf1 =\cf0 "\cf1 utf-16\cf0 "\cf1 ?&amp;gt;\par ??&amp;lt;\cf3 initstring\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 interopAssembly\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 URL\cf1 &amp;gt;\cf0 C:\\MyApp.exe\cf1 &amp;lt;/\cf3 URL\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 WorkingDirectory\cf1 &amp;gt;\cf0 C:\\\cf1 &amp;lt;/\cf3 WorkingDirectory\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 hostInside\cf1  /&amp;gt;\par ??\tab &amp;lt;/\cf3 interopAssembly\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 UseTopLevelWindow\cf1  \cf4 class\cf1 =\cf0 "\cf1 ThunderRT6Form\cf0 "\cf1  /&amp;gt;\par ??\tab &amp;lt;\cf3 adapter\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 URL\cf1 &amp;gt;\cf0 C:\\MyApplicationAdapters.dll\cf1 &amp;lt;/\cf3 URL\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 type\cf1 &amp;gt;\cf0 Microsoft.Ccf.QuickStarts.MyExtVBAppAdapter\cf1 &amp;lt;/\cf3 type\cf1 &amp;gt;\par ??\tab &amp;lt;/\cf3 adapter\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 DataDrivenAdapterBindings\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 Type\cf1 &amp;gt;\cf0 Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter, \par ??\tab \tab \tab   Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter\cf1 &amp;lt;/\cf3 Type\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 Controls\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;\cf3 AccControl\cf1  \cf4 name\cf1 =\cf0 "\cf1 button1\cf0 "\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;\cf3 Path\cf1 &amp;gt;\par ??\tab \tab \tab \tab \tab &amp;lt;\cf3 Next\cf1 &amp;gt;\cf0 OK\cf1 &amp;lt;/\cf3 Next\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;/\cf3 Path\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;/\cf3 AccControl\cf1 &amp;gt;\par ??\tab \tab &amp;lt;/\cf3 Controls\cf1 &amp;gt;\par ??\tab &amp;lt;/\cf3 DataDrivenAdapterBindings\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 optimumSize\cf1  \cf4 x\cf1 =\cf0 "\cf1 800\cf0 "\cf1  \cf4 y\cf1 =\cf0 "\cf1 600\cf0 "\cf1  /&amp;gt;\par ??\tab &amp;lt;\cf3 minimumSize\cf1  \cf4 x\cf1 =\cf0 "\cf1 640\cf0 "\cf1  \cf4 y\cf1 =\cf0 "\cf1 480\cf0 "\cf1  /&amp;gt;\par ??&amp;lt;/\cf3 initstring\cf1 &amp;gt;}
--&gt;
&lt;STYLE type=text/css&gt;

.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #a31515; }
.cb3 { color: red; }&lt;/STYLE&gt;
&lt;/P&gt;
&lt;DIV class=cf&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;lt;?&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;xml&lt;/SPAN&gt;&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;version&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;1.0&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;encoding&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;utf-16&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;?&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;initstring&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;interopAssembly&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;URL&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;C:\MyApp.exe&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;URL&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;WorkingDirectory&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;C:\&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;WorkingDirectory&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;hostInside&lt;/SPAN&gt;&lt;SPAN class=cb1&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;interopAssembly&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;STRONG&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;UseTopLevelWindow&lt;/SPAN&gt;&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;class&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;ThunderRT6Form&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;adapter&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;URL&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;C:\MyApplicationAdapters.dll&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;URL&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;type&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;Microsoft.Ccf.QuickStarts.MyExtVBAppAdapter&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;type&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;adapter&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;DataDrivenAdapterBindings&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Type&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter, &lt;/P&gt;
&lt;P class=cl&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Type&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Controls&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;AccControl&lt;/SPAN&gt;&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;name&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;button1&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Path&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Next&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;OK&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Next&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Path&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;AccControl&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;Controls&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;DataDrivenAdapterBindings&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;optimumSize&lt;/SPAN&gt;&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;x&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;800&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;y&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;600&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;minimumSize&lt;/SPAN&gt;&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;x&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;640&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt; &lt;/SPAN&gt;&lt;SPAN class=cb3&gt;y&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;=&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt;480&lt;/SPAN&gt;"&lt;SPAN class=cb1&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=cl&gt;&lt;SPAN class=cb1&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=cb2&gt;initstring&lt;/SPAN&gt;&lt;SPAN class=cb1&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One thing to take into account is that, if the application uses an alternative top level window, the DDA must be instantiated with that top level window instead of the process MainWindowHandle. The picture shows how the alternate top level window configuration is seen in the Admin Console:&lt;/P&gt;
&lt;P&gt;&lt;IMG id=id src="http://weblogs.asp.net/blogs/spano/hat_useTopLevelWnd.JPG" mce_src="http://weblogs.asp.net/blogs/spano/hat_useTopLevelWnd.JPG"&gt; &lt;/P&gt;
&lt;P&gt;And here is the code of the legacy adapter making use of the data driven adapter to automate the hosted application's UI:&lt;/P&gt;
&lt;P&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red0\green128\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 using\cf0  System;\par ??\cf1 using\cf0  Microsoft.Ccf.Csr;\par ??\cf1 using\cf0  Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter;\par ??\par ??\cf1 namespace\cf0  Microsoft.Ccf.BancoGalicia.ApplicationAdapters\par ??\{\par ??    \cf1 public\cf0  \cf1 class\cf0  MyExtVBAppAdapter : ApplicationAdapter\par ??    \{\par ??        \cf1 protected\cf0  DataDrivenAdapterBase _dda;\par ??\par ??        \cf1 public\cf0  \cf1 override\cf0  \cf1 bool\cf0  Initialize()\par ??        \{\par ??            \cf4 //IntPtr topLevelWnd = Process.MainWindowHandle;//this won't work for a VB app \par ??\cf0             \cf5 IntPtr\cf0  topLevelWnd = GetTopLevelWndHandle();\par ??            \cf4 //Initialize Data Driven Adapter with proper top level window handle\par ??\cf0             _dda = DataDrivenAdapterBase.CreateInstance(ApplicationInitString, topLevelWnd);\par ??            \cf1 return\cf0  _dda != \cf1 null\cf0 ;\par ??        \}\par ??\par ??        \cf1 public\cf0  \cf1 override\cf0  \cf1 bool\cf0  DoAction(Action action, RequestActionEventArgs args)\par ??        \{\par ??            \cf1 switch\cf0  (args.Action)\par ??            \{\par ??                \cf1 case\cf0  \cf6 "DefaultAction"\cf0 :\par ??                    \cf1 break\cf0 ;\par ??                \cf1 case\cf0  \cf6 "PressButton"\cf0 :\par ??                    PressButton();\par ??                    \cf1 break\cf0 ;\par ??            \}\par ??            \cf1 return\cf0  \cf1 base\cf0 .DoAction(action, args);\par ??\par ??        \}\par ??\par ??        \cf1 private\cf0  \cf1 void\cf0  PressButton()\par ??        \{\par ??            \cf1 if\cf0  (_dda.FindControl(\cf6 "button1"\cf0 ))\par ??            \{\par ??                _dda.ExecuteControlAction(\cf6 "button1"\cf0 );\par ??            \}\par ??        \}\par ??\par ??        \cf4 //Find the top level window of the VB application (for example of class "ThunderRT6Form")\par ??\cf0         \cf1 private\cf0  \cf5 IntPtr\cf0  GetTopLevelWndHandle()\par ??        \{\par ??            \cf5 IntPtr\cf0  agentDesktopPtr = Win32API.FindWindow(\cf1 null\cf0 , \cf6 "Agent Desktio"\cf0 );\par ??            \cf1 if\cf0  (agentDesktopPtr != \cf5 IntPtr\cf0 .Zero)\par ??            \{\par ??                \cf5 IntPtr\cf0  tabWindowHandle = Win32API.FindWindowByText(agentDesktopPtr, \cf6 "MyApp"\cf0 );\par ??                \cf1 if\cf0  (tabWindowHandle != \cf5 IntPtr\cf0 .Zero)\par ??                \{\par ??                    \cf1 return\cf0  Win32API.FindWindowByText(tabWindowHandle, \cf6 "MyAppTopLevelWndCaption"\cf0 );\par ??                \}\par ??            \}\par ??            \cf1 return\cf0  \cf5 IntPtr\cf0 .Zero;\par ??        \}\par ??\par ??    \}\par ??\}\par ??}
--&gt;&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: courier new"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; Microsoft.Ccf.Csr;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; Microsoft.Ccf.BancoGalicia.ApplicationAdapters&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; MyExtVBAppAdapter : ApplicationAdapter&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;protected&lt;/SPAN&gt; DataDrivenAdapterBase _dda;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; Initialize()&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;//IntPtr topLevelWnd = Process.MainWindowHandle;//this won't work for a VB app &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt; topLevelWnd = GetTopLevelWndHandle();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;//Initialize Data Driven Adapter with proper top level window handle&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _dda = DataDrivenAdapterBase.CreateInstance(ApplicationInitString, topLevelWnd);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; _dda != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; DoAction(Action action, RequestActionEventArgs args)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;switch&lt;/SPAN&gt; (args.Action)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;case&lt;/SPAN&gt; &lt;SPAN style="COLOR: #a31515"&gt;"DefaultAction"&lt;/SPAN&gt;:&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;break&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;case&lt;/SPAN&gt; &lt;SPAN style="COLOR: #a31515"&gt;"PressButton"&lt;/SPAN&gt;:&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PressButton();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;break&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;.DoAction(action, args);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; PressButton()&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (_dda.FindControl(&lt;SPAN style="COLOR: #a31515"&gt;"button1"&lt;/SPAN&gt;))&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _dda.ExecuteControlAction(&lt;SPAN style="COLOR: #a31515"&gt;"button1"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;//Find the top level window of the VB application (for example of class "ThunderRT6Form")&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt; GetTopLevelWndHandle()&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt; agentDesktopPtr = Win32API.FindWindow(&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Agent Desktio"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (agentDesktopPtr != &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt;.Zero)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt; tabWindowHandle = Win32API.FindWindowByText(agentDesktopPtr, &lt;SPAN style="COLOR: #a31515"&gt;"MyApp"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (tabWindowHandle != &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt;.Zero)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; Win32API.FindWindowByText(tabWindowHandle, &lt;SPAN style="COLOR: #a31515"&gt;"MyAppTopLevelWndCaption"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IntPtr&lt;/SPAN&gt;.Zero;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&amp;nbsp; &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4841509" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/F3xK26_0Am0" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/CCF/default.aspx">CCF</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/10/30/ccf-hat-making-use-of-ddas-from-legacy-adapters.aspx</feedburner:origLink></item><item><title>CCF 2008 Hosted Application Toolkit</title><link>http://feedproxy.google.com/~r/spano/~3/V1L38Zh-PtI/ccf-2008-hosted-application-toolkit.aspx</link><pubDate>Fri, 26 Oct 2007 03:40:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4755817</guid><dc:creator>spano</dc:creator><slash:comments>3</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/10/26/ccf-2008-hosted-application-toolkit.aspx#comments</comments><description>&lt;p&gt;The Hosted Application Toolkit (HAT) is a new component of CCF 2.6 (2008) that facilitates the task of automating the UI of the hosted applications. It consists of two main parts: the Data Driven Adapters (DDA) and the Automations (WF workflows) that automates the hosted application using the DDAs.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Data Driven Adapters&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;DDAs must inherit from DataDrivenAdapterBase in Microsoft.Ccf.HostedApplicationToolkit. CCF supports two implementations out of the box: WinDataDrivenAdapter and WebDataDrivenAdapter. We can inherit from any of the three to extend the DDA as necessary. The methods the DDAs expose to manipulate the hosted application UI are ExecuteControlAction, FindControl, GetControlValue and SetControlValue. These methods take a friendly name as parameter and lets the application adapters interact with the hosted application UI abstracting from the details of how to obtain the control from that friendly name. The mapping between the controls' friendly names and the directions for the DDA to finding them is called Data Driven Adapter Binding and is part of the hosted app initialization string:&lt;/p&gt;  &lt;p&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;}??\fs20 \cf1 &amp;lt;\cf3 DataDrivenAdapterBindings\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 Type\cf1 &amp;gt;\cf0 Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter\cf1 &amp;lt;/\cf3 Type\cf1 &amp;gt;\par ??\tab &amp;lt;\cf3 Controls\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 AccControl\cf1  \cf5 name\cf1 =\cf0 "\cf1 okButton\cf0 "\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;\cf3 Path\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;\cf3 FindWindow\cf1 &amp;gt;\par ??\tab \tab \tab \tab \tab &amp;lt;\cf3 ControlID\cf1 &amp;gt;\cf0 15\cf1 &amp;lt;/\cf3 ControlID\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;/\cf3 FindWindow\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;/\cf3 Path\cf1 &amp;gt;\par ??\tab \tab &amp;lt;/\cf3 AccControl\cf1 &amp;gt;\par ??\tab \tab &amp;lt;\cf3 AccControl\cf1  \cf5 name\cf1 =\cf0 "\cf1 cancelButton\cf0 "\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;\cf3 Path\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;\cf3 FindWindow\cf1 &amp;gt;\par ??\tab \tab \tab \tab \tab &amp;lt;\cf3 ControlID\cf1 &amp;gt;\cf0 15\cf1 &amp;lt;/\cf3 ControlID\cf1 &amp;gt;\par ??\tab \tab \tab \tab &amp;lt;/\cf3 FindWindow\cf1 &amp;gt;\par ??\tab \tab \tab &amp;lt;/\cf3 Path\cf1 &amp;gt;\par ??\tab \tab &amp;lt;/\cf3 AccControl\cf1 &amp;gt;\par ??\tab &amp;lt;/\cf3 Controls\cf1 &amp;gt;\par ??&amp;lt;/\cf3 DataDrivenAdapterBindings\cf1 &amp;gt;\par ??}
--&gt;&lt;/p&gt;  &lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt;   &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;DataDrivenAdapterBindings&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Controls&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;AccControl&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;okButton&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Path&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;FindWindow&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ControlID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;15&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ControlID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;FindWindow&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Path&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;AccControl&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;AccControl&lt;/span&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;cancelButton&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Path&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;FindWindow&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ControlID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;15&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ControlID&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;FindWindow&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Path&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;AccControl&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Controls&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;DataDrivenAdapterBindings&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Note: It is a known issue that the initialization string of a hosted application is limited to 3902 characters. This may result a problem if several controls must be listed.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;Although DDAs can be used from any custom adapter (and even outside CCF), they were mainly thought to support Automations in HAT. &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Automations&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;In previous versions of CCF we could choose to use an Application Adapter to implement the actions' logic. In version 2.6 we can choose between Automation Adapter, Legacy Adapter, or no adapter at all. The Legacy Adapter is the Application Adapter from the previous versions. We can implement our own Legacy Adapter inheriting from the [Web]ApplicationAdapter class. The Automation Adapter is the adapter that makes use of the new Workflow Foundation (WF) feature. The AutomationAdapter implements the IAutomationAdapter interface. However, if we choose AutomationAdapter in the hosted app configuration in the AdminConsole, we can't choose our own implementation of IAutomationAdapter.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://weblogs.asp.net/blogs/spano/hat_adapterConfig.jpg" id="id" mce_src="http://weblogs.asp.net/blogs/spano/hat_adapterConfig.jpg"&gt; &lt;/p&gt;  &lt;p&gt;If a hosted application is configured to use the AutomationAdapter, we can specify a WF workflow to implement an action's logic. Workflows in HAT are called Automations. &lt;/p&gt;  &lt;p&gt;&lt;img src="http://weblogs.asp.net/blogs/spano/hat_actionConfig.JPG" id="id" mce_src="http://weblogs.asp.net/blogs/spano/hat_actionConfig.JPG"&gt; &lt;/p&gt;  &lt;p&gt;In order to orchestrate an action automation, a set of WF Activities are provided by CCF that interact with the DDAs to access the UI controls. There are activities for calling an action in a hosted application, setting or getting a control's value, accessing the context, register for an application event, etc. &lt;/p&gt;  &lt;p&gt;&lt;img src="http://weblogs.asp.net/blogs/spano/hatCCFActivities.JPG" id="id" mce_src="http://weblogs.asp.net/blogs/spano/hatCCFActivities.JPG"&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;All together&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The connection between the Automations and the DDAs is achieved by the AutomationBridgeService, which is in turn connected to the AutomationAdapter. As the bridge service is added to the WF runtime, it is accessible from the CCF WF activities. We can extend the set of activities and make use of this server, too.&lt;/p&gt;  &lt;p&gt;The following diagram depicts the relationship between the components mentioned above:&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;img src="http://weblogs.asp.net/blogs/spano/HAT_uml2.jpg" id="id" mce_src="http://weblogs.asp.net/blogs/spano/HAT_uml2.jpg"&gt; &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;More detailed documentation can be found in chapter 9 of the CCF 2008 Development Guide.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4755817" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/V1L38Zh-PtI" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/CCF/default.aspx">CCF</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/10/26/ccf-2008-hosted-application-toolkit.aspx</feedburner:origLink></item><item><title>Silverlight article published this month</title><link>http://feedproxy.google.com/~r/spano/~3/kVbvEZQnLHE/silverlight-article-published-this-month.aspx</link><pubDate>Mon, 08 Oct 2007 02:23:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4480886</guid><dc:creator>spano</dc:creator><slash:comments>1</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/10/08/silverlight-article-published-this-month.aspx#comments</comments><description>&lt;P align=left&gt;My colleagues &lt;A href="http://weblogs.asp.net/arielneisen" mce_href="http://weblogs.asp.net/arielneisen"&gt;Ariel Neisen&lt;/A&gt;, Federico García, &lt;A href="http://weblogs.shockbyte.com.ar/rodolfof" mce_href="http://weblogs.shockbyte.com.ar/rodolfof"&gt;Rodolfo Finochietti&lt;/A&gt; and I wrote the cover article of the &lt;A href="http://www.redusers.com/noticias/code-42" mce_href="http://www.redusers.com/noticias/code-42"&gt;#42 edition of the .Code Magazine&lt;/A&gt; (in Spanish) about &lt;STRONG&gt;Silverlight&lt;/STRONG&gt;. The article talks about this new technology's fundamentals, architecture, programming tools, advanced features, code samples and a lot more. &lt;/P&gt;
&lt;P align=center&gt;&lt;IMG id=id src="http://weblogs.asp.net/blogs/spano/tapa-code-42.gif"&gt; &lt;/P&gt;
&lt;P align=left mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4480886" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/kVbvEZQnLHE" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/10/08/silverlight-article-published-this-month.aspx</feedburner:origLink></item><item><title>Choosing the right WCF binding</title><link>http://feedproxy.google.com/~r/spano/~3/V322_aaiPMw/choosing-the-right-wcf-binding.aspx</link><pubDate>Tue, 02 Oct 2007 02:43:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4284438</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/10/02/choosing-the-right-wcf-binding.aspx#comments</comments><description>&lt;P&gt;A WCF binding is the endpoint component that defines &lt;EM&gt;how&lt;/EM&gt; the client needs to communicate with the service. It groups settings such as underlying transport protocol, security requirements, and message encoding.&lt;/P&gt;
&lt;P&gt;WCF provides nine built-in bindings: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;BasicHttpBinding&lt;/STRONG&gt;: Basic web service communication. Exposes WCF services as legacy ASMX web services. Used for interoperability. No security by default.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;WSHttpBinding&lt;/STRONG&gt;: Web services with WS-* support. Supports transactions and reliable messaging.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;WSDualHttpBinding&lt;/STRONG&gt;: Web services with duplex contract and transaction support.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;WSFederationHttpBinding&lt;/STRONG&gt;: Web services with federated security. Supports transactions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;MsmqIntegrationBinding&lt;/STRONG&gt;: Communication directly with MSMQ applications. Supports transactions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NetMsmqBinding&lt;/STRONG&gt;: Communication between WCF applications by using queuing. Supports transactions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NetNamedPipeBinding&lt;/STRONG&gt;: Communication between WCF applications on same computer. Supports duplex contracts and transactions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NetPeerTcpBinding&lt;/STRONG&gt;: Communication between computers across peer-to-peer services. Supports duplex contracts.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NetTcpBinding&lt;/STRONG&gt;: Communication between WCF applications across computers. Supports duplex contracts and transactions.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Although most bindings will work on scenarios they are not designed for, it's a good practice to choose the right binding for a given endpoint. In chapter one of the "&lt;A href="http://safari.oreilly.com/0596526997" mce_href="http://safari.oreilly.com/0596526997"&gt;Programming WCF Services&lt;/A&gt;" book, Juval Lowy provides a very useful decision-activity diagram for choosing the right binding:&lt;/P&gt;
&lt;P&gt;&lt;IMG id=id src="http://weblogs.asp.net/blogs/spano/WCFBindings.JPG" mce_src="http://weblogs.asp.net/blogs/spano/WCFBindings.JPG"&gt; &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;"The first question you should ask yourself is whether your service needs to interact with non-WCF clients. If the answer is yes, and if the client is a legacy MSMQ client, choose the &lt;STRONG&gt;MsmqIntegrationBinding&lt;/STRONG&gt; that enables your service to interoperate over MSMQ with such a client. If you need to interoperate with a non-WCF client and that client expects basic web service protocol (ASMX web services), choose the &lt;STRONG&gt;BasicHttpBinding&lt;/STRONG&gt;, which exposes your WCF service to the outside world as if it were an ASMX web service (that is, a WSI-basic profile). The downside is that you cannot take advantage of most of the modern WS-* protocols. However, if the non-WCF client can understand these standards, choose one of the WS bindings, such as &lt;STRONG&gt;WSHttpBinding&lt;/STRONG&gt;, &lt;STRONG&gt;WSFederationHttpBinding&lt;/STRONG&gt;, or &lt;STRONG&gt;WSDualHttpBinding&lt;/STRONG&gt;. If you can assume that the client is a WCF client, yet it requires offline or disconnected interaction, choose the &lt;STRONG&gt;NetMsmqBinding &lt;/STRONG&gt;that uses MSMQ for transporting the messages. If the client requires connected communication, but could be calling across machine boundaries, choose the &lt;STRONG&gt;NetTcpBinding &lt;/STRONG&gt;that communicates over TCP. If the client is on the same machine as the service, choose the &lt;STRONG&gt;NetNamedPipeBinding &lt;/STRONG&gt;that uses named pipes to maximize performance. You may fine-tune binding selections based on additional criteria such as the need for callbacks (&lt;STRONG&gt;WSDualHttpBinding&lt;/STRONG&gt;)&lt;/EM&gt;&lt;A&gt;&lt;/A&gt;&lt;EM&gt; or federated security (&lt;STRONG&gt;WSFederationHttpBinding&lt;/STRONG&gt;)."&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;You&amp;nbsp;can download the book's &lt;A class="" href="http://www.oreilly.com/catalog/9780596526993/chapter/index.html" mce_href="http://www.oreilly.com/catalog/9780596526993/chapter/index.html"&gt;sample chapter&lt;/A&gt; to read more on this subject.&amp;nbsp;You&amp;nbsp;would also&amp;nbsp;find the diagram&amp;nbsp;in&amp;nbsp;Juval's article&amp;nbsp;&lt;A class="" href="http://www.code-magazine.com/article.aspx?quickid=0605051&amp;amp;page=3" mce_href="http://www.code-magazine.com/article.aspx?quickid=0605051&amp;amp;page=3"&gt;WCF Essentials - A Developer's Primer&lt;/A&gt;&amp;nbsp;on the&amp;nbsp;CoDe Magazine.&amp;nbsp;&lt;SPAN id=article_content&gt;&lt;FONT face=Verdana&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4284438" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/V322_aaiPMw" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/WCF/default.aspx">WCF</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/10/02/choosing-the-right-wcf-binding.aspx</feedburner:origLink></item><item><title>CCF 2008 New Features</title><link>http://feedproxy.google.com/~r/spano/~3/NAORKzgYk9k/ccf-2008-new-features.aspx</link><pubDate>Fri, 28 Sep 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4231872</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/09/28/ccf-2008-new-features.aspx#comments</comments><description>&lt;P&gt;The 3.0 version of the Customer Care Framework (CCF) is out! Among its &lt;A href="http://blogs.msdn.com/ypitsch/archive/2007/09/21/ccf-2008-is-there.aspx" mce_href="http://blogs.msdn.com/ypitsch/archive/2007/09/21/ccf-2008-is-there.aspx"&gt;new features&lt;/A&gt; we'll find: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;CCF web services migrated to Windows Communication Foundation (WCF). &lt;/LI&gt;
&lt;LI&gt;Agent Desktop use of Composite Application Block (CAB). &lt;/LI&gt;
&lt;LI&gt;Hosted Application Toolkit (HAT): new sub-system for providing UI automation, that makes use of Workflow Foundation (WF) and Active Accessibility. &lt;/LI&gt;
&lt;LI&gt;ClickOnce support. &lt;/LI&gt;
&lt;LI&gt;Dynamic Applications: 3rd category of hosted applications that allow an agent to dynamically launch or close a hosted application on-demand, via the UI or programmatically in code. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I found the HAT to be the most interesting feature, allowing to decouple accessibility implementation details from automation logic and making use of WF to represent this automation logic in a friendly, declarative way. I guess I will be posting more on this subject later. &lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4231872" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/NAORKzgYk9k" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/CCF/default.aspx">CCF</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/09/28/ccf-2008-new-features.aspx</feedburner:origLink></item><item><title>Hosting a Windows Form Control in a web page</title><link>http://feedproxy.google.com/~r/spano/~3/jEKIh-l6Tg8/hosting-a-windows-form-control-in-a-web-page.aspx</link><pubDate>Wed, 19 Sep 2007 17:56:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3969036</guid><dc:creator>spano</dc:creator><slash:comments>23</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Although it is not the most common use of it, it is possible to host a Windows Form Control in a Web Page and run it from within Internet Explorer. This allows to build powerful client side functionality with all the advantages of using the .Net framework and executing the control in the client side. Of course there are some restrictions that cannot be left aside. At least the .Net framework must be installed on the client for the control to run. In addition, it is possible that some permission must be granted to the control, too, depending on the actions the control will take on the client machine. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Let’s build an example to see how this works:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;&lt;STRONG&gt;1. Create the Windows Form Control&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Create a “Windows Control Library” project in Visual Studio. For this simple example we will add a label to the control and a public “SendMessage” method to change the label’s text. In order to be able to call the method from IE, we will set the control’s COMVisible attribute to true.&lt;/FONT&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Windows.Forms;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Runtime.InteropServices;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; WindowsControlLibrary1&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;{&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;SPAN style="COLOR: teal"&gt;ComVisible&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;)]&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;partial&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;UserControl1&lt;/SPAN&gt; : &lt;SPAN style="COLOR: teal"&gt;UserControl&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; UserControl1()&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeComponent();&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; SendMessage(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; msg){&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _lblMessage.Text = msg;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New"&gt;}&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;STRONG&gt;2. Create&amp;nbsp;the hosting HTML document&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri&gt;&lt;FONT size=3&gt;&lt;SPAN style="COLOR: black; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Courier New'"&gt;The control will be hosted using the HTML &lt;STRONG&gt;&lt;SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-bidi-font-family: 'Courier New'"&gt;&amp;lt;object&amp;gt;&lt;/SPAN&gt;&lt;/STRONG&gt; element. In its classid attribute we will place the control's reference in the following &lt;/SPAN&gt;manner: classid="http:[relativePath/]&amp;lt;winControlAssemblyName&amp;gt;.dll#&amp;lt;ControlNamespace&amp;gt;.&amp;lt;ControlClassName&amp;gt;". &lt;/FONT&gt;&lt;FONT size=3&gt;For this example we will have an HTML page (index.html) with the following code:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;!&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;DOCTYPE&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: red"&gt;html&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;PUBLIC&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;html&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://www.w3.org/1999/xhtml"&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;head&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;Windows Form Control Test Page&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;script&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="text/javascript"&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; SendMessageToWinControl()&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; winCtrl = document.getElementById(&lt;SPAN style="COLOR: maroon"&gt;"MyWinControl"&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;winCtrl.SendMessage(&lt;SPAN style="COLOR: maroon"&gt;"Message sent from the HTML page!!"&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;script&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;head&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;body&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;h1&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;Windows Form Control:&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;h1&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;object&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="MyWinControl"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;classid&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http:WindowsControlLibrary1.dll#WindowsControlLibrary1.UserControl1"&lt;/SPAN&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;STRONG&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: red"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="100"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="300"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;VIEWASTEXT&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;br&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;br&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;input&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="button"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;onclick&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="SendMessageToWinControl()"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Send Message"&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;body&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;html&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt; &lt;/DIV&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;STRONG&gt;3. Deploy the sample&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;Copy both the index.html page and the control library WindowControlLibrary1.dll to a directory (we will name it WinControlTest). In the “Web Sharing” dir properties select &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;Share this folder&lt;/B&gt;, leave the default alias and application permissions to Scripts and make sure not to select &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;the Execute permission).&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;STRONG&gt;4. Try it in Internet Explorer&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;Open the page &lt;A href="http://localhost/WinControlTest/index.html" mce_href="http://localhost/WinControlTest/index.html"&gt;http://localhost/WinControlTest/index.html&lt;/A&gt;&amp;nbsp;in Internet Explorer. We can see the control hosted in the html page:&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;IMG style="WIDTH: 641px; HEIGHT: 387px" height=387 src="http://weblogs.asp.net/blogs/spano/WinControlTest2.JPG" width=641 mce_src="http://weblogs.asp.net/blogs/spano/WinControlTest2.JPG"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;By clicking the Send Message button,&amp;nbsp;we will call the Control's SendMessage method from javscript. Resulting in the&amp;nbsp;label's text changed:&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;IMG src="http://weblogs.asp.net/blogs/spano/WinControlTest3.JPG" mce_src="http://weblogs.asp.net/blogs/spano/WinControlTest3.JPG"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;If you modify the control after its first use, you will need to close IE, replace the control's dll in the virtual directory and clean the contents of the download cache. You do this cleaning using the following command:&lt;/FONT&gt; "gacutil /cdl".&lt;FONT face=Calibri size=3&gt;To&amp;nbsp;list the contents of the download cache use &lt;/FONT&gt;"gacutil /ldl".&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;This solution is not intended to replace a WebControl or any common web artifact. But is good to know it can be use in&amp;nbsp;an uncommon scenario if needed.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;Sole&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; BACKGROUND: white; MARGIN: 0px; COLOR: black; FONT-FAMILY: Courier New" mce_keep="true"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;!--EndFragment--&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3969036" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/jEKIh-l6Tg8" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/Windows+Forms/default.aspx">Windows Forms</category><category domain="http://weblogs.asp.net/spano/archive/tags/IIS/default.aspx">IIS</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/09/19/hosting-a-windows-form-control-in-a-web-page.aspx</feedburner:origLink></item><item><title>WPF Accessibility</title><link>http://feedproxy.google.com/~r/spano/~3/gwoDd3rmf24/wpf-accessibility.aspx</link><pubDate>Fri, 07 Sep 2007 15:55:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3780239</guid><dc:creator>spano</dc:creator><slash:comments>7</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx#comments</comments><description>&lt;P&gt;Windows Presentation Foundation (WPF) provides a very interesting API for Accessibility called &lt;STRONG&gt;Microsoft UI Automation&lt;/STRONG&gt;.&amp;nbsp;It allows programmatic access to most user interface elements on the desktop, addressing the needs of assistive technology products and also for User Interface (UI) tests automation. 
&lt;P&gt;The framework provides solutions for both accessibility providers and clients, and&amp;nbsp;it is conformed of&amp;nbsp;four main components (see &lt;A href="http://msdn2.microsoft.com/en-us/library/ms747327.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms747327.aspx"&gt;&lt;FONT color=#669966&gt;UI Automation Overview&lt;/FONT&gt;&lt;/A&gt;): 
&lt;OL&gt;
&lt;LI&gt;The &lt;STRONG&gt;Provider API&lt;/STRONG&gt; (UIAutomationProvider.dll and UIAutomationTypes.dll) defines a set of interfaces that are implemented by UI Automation providers, objects that provide information about UI elements and respond to programmatic input. 
&lt;LI&gt;The &lt;STRONG&gt;Client API&lt;/STRONG&gt; (UIAutomationClient.dll and UIAutomationTypes.dll) is a set of types for managed code that enables UI Automation client applications to obtain information about the UI and to send input to controls. 
&lt;LI&gt;The &lt;STRONG&gt;UI Automation Core&lt;/STRONG&gt; (UiAutomationCore.dll)&amp;nbsp;has the&amp;nbsp;underlying code that handles communication between providers and clients. 
&lt;LI&gt;The&amp;nbsp;&lt;STRONG&gt;UIAutomationClientsideProviders.dll&lt;/STRONG&gt; that has a set of UI Automation providers for standard legacy controls. (WPF controls have native support for UI Automation.) This support is automatically available to client applications. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;We will typically&amp;nbsp;use the Provider API to create support for our WPF custom controls, since they don't provide accessibility support by default. We will use the Client API for creating applications that need to communicate with UI elements and eventually automate the use of other program's UI. &lt;/P&gt;
&lt;P&gt;You can find good documentation in the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms753388.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms753388.aspx"&gt;&lt;FONT color=#669966&gt;WPF Accessibility&lt;/FONT&gt;&lt;/A&gt; section on MSDN, and several code samples in the&amp;nbsp;&lt;A href="http://msdn2.microsoft.com/en-us/library/ms771315.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms771315.aspx"&gt;&lt;FONT color=#669966&gt;SDK Sample Applications&lt;/FONT&gt;&lt;/A&gt;.&amp;nbsp; 
&lt;P&gt;Just to mention, Microsoft’s earlier solution for Accessibility was &lt;STRONG&gt;Active Accessibility&lt;/STRONG&gt;. The main advantage&amp;nbsp;of UI Automation over Active Accessibility&amp;nbsp;is the technology in which it is based on (managed code vs COM)&amp;nbsp;and, as a consequence,&amp;nbsp;the&amp;nbsp;programming languages that can be used. You can read more of the differences in &lt;A href="http://msdn2.microsoft.com/en-us/library/ms788733.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms788733.aspx"&gt;&lt;FONT color=#669966&gt;UI Automation and Microsoft Active Accessibility&lt;/FONT&gt;&lt;/A&gt;. 
&lt;P&gt;A few words about the API's &lt;STRONG&gt;Object Model&lt;/STRONG&gt;: Every piece of UI, such as a window, a button, etc, is represented by the &lt;STRONG&gt;AutomationElement&lt;/STRONG&gt; class in the System.Windows.Automation namespace&amp;nbsp;of the&amp;nbsp;UIAutomationClient assembly. An AutomationElement corresponds to a piece of UI regardless of the underlying implementation (WPF or Win32). All automation elements are part of a tree, in which the root element&amp;nbsp;is the Desktop. Through the AutomationElement.RootElement static property you can obtain a reference to the Desktop and find any child piece of UI from there to access. 
&lt;P&gt;AutomationElements expose &lt;STRONG&gt;Control Patterns&lt;/STRONG&gt; that provide properties specific to their Control Types (window, button, checkbox, etc). Control Patterns also expose methods that enable clients to get further information about the element and to provide input. We are going to see how this works in the examples below.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A very useful tool for finding the element's properties in the&amp;nbsp;tree is &lt;STRONG&gt;UISpy&lt;/STRONG&gt;, which comes with the Windows SDK. It lets you see all the UI tree and each element's properties. In the Focus Tracking mode, you can select the real UI element in the Desktop&amp;nbsp;and UISpy will automatically show its properties in the tree view.&lt;/P&gt;
&lt;P&gt;&lt;A href="file:///C:/Documents%20and%20Settings/soledad/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/fc77ec4c-c006-40da-9287-e155681e887d/image1.png" atomicselection="true" mce_href="file:///C:/Documents%20and%20Settings/soledad/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/fc77ec4c-c006-40da-9287-e155681e887d/image1.png"&gt;&lt;/A&gt;&lt;IMG title=UISpy style="WIDTH: 813px; HEIGHT: 372px" height=372 alt=UISpy src="http://weblogs.asp.net/blogs/spano/Accessibility_UISpy.JPG" width=813 mce_src="http://weblogs.asp.net/blogs/spano/Accessibility_UISpy.JPG"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;/B&gt;
&lt;H3&gt;&lt;B&gt;Code sample&lt;/B&gt;&lt;/H3&gt;
&lt;P&gt;This is an example of a client application for automating a win32 application (in this case the Windows Address Book). For this example, we only need a Windows Console Application and references to&amp;nbsp;the &lt;STRONG&gt;UIAutomationClient&lt;/STRONG&gt; and &lt;STRONG&gt;UIAutomationTypes&lt;/STRONG&gt; assemblies. From the code it can be seen how to match a control to a given pattern depending on what we want to do with the control. 
&lt;P&gt;The controls' names and/or ids where obtained using UISpy. 
&lt;P&gt;These are the UI artifacts that we want to automate: 
&lt;P&gt;&lt;A href="file:///C:/Documents%20and%20Settings/soledad/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/fc77ec4c-c006-40da-9287-e155681e887d/image3.png" atomicselection="true" mce_href="file:///C:/Documents%20and%20Settings/soledad/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/fc77ec4c-c006-40da-9287-e155681e887d/image3.png"&gt;&lt;/A&gt;&lt;IMG title="Address Book Application" style="WIDTH: 493px; HEIGHT: 335px" height=335 alt="Address Book Application" src="http://weblogs.asp.net/blogs/spano/Accessibility_AddressBook.JPG" width=493 align=middle mce_src="http://weblogs.asp.net/blogs/spano/Accessibility_AddressBook.JPG"&gt;&amp;nbsp;&lt;A href="file:///C:/Documents%20and%20Settings/soledad/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/fc77ec4c-c006-40da-9287-e155681e887d/image5.png" atomicselection="true" mce_href="file:///C:/Documents%20and%20Settings/soledad/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/fc77ec4c-c006-40da-9287-e155681e887d/image5.png"&gt;&lt;/A&gt; 
&lt;P&gt;&lt;IMG title="Find People Dialog" style="WIDTH: 483px; HEIGHT: 263px" height=263 alt="Find People Dialog" src="http://weblogs.asp.net/blogs/spano/Accessibility_FindPeople.JPG" width=483 mce_src="http://weblogs.asp.net/blogs/spano/Accessibility_FindPeople.JPG"&gt; 
&lt;P&gt;And here is the code to: 
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;
&lt;P&gt;&lt;STRONG&gt;- Get a reference to the Address Book application main window: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Windows.Automation; 
&lt;P&gt;... 
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; mainWindow = FindWindowByName(&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt;.RootElement, &lt;SPAN style="COLOR: #a31515"&gt;"Address Book - Main Identity"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;...&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; FindWindowByName(&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; rootElement, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; name)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: #2b91af"&gt;PropertyCondition&lt;/SPAN&gt; nameCondition = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyCondition&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt;.NameProperty, name);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: #2b91af"&gt;PropertyCondition&lt;/SPAN&gt; typeCondition = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyCondition&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt;.ControlTypeProperty, &lt;SPAN style="COLOR: #2b91af"&gt;ControlType&lt;/SPAN&gt;.Window);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: #2b91af"&gt;AndCondition&lt;/SPAN&gt; andCondition = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;AndCondition&lt;/SPAN&gt;(nameCondition,typeCondition);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; rootElement.FindFirst(&lt;SPAN style="COLOR: #2b91af"&gt;TreeScope&lt;/SPAN&gt;.Element | &lt;SPAN style="COLOR: #2b91af"&gt;TreeScope&lt;/SPAN&gt;.Descendants, andCondition);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;- Press the Find People button:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; findPeopleButton = FindElementById(mainWindow, &lt;SPAN style="COLOR: #a31515"&gt;"Item 8084"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (findPeopleButton != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;InvokePattern&lt;/SPAN&gt; invPattern = findPeopleButton.GetCurrentPattern(&lt;SPAN style="COLOR: #2b91af"&gt;InvokePattern&lt;/SPAN&gt;.Pattern) &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;InvokePattern&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (invPattern != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; invPattern.Invoke();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P&gt;...&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; FindElementById(&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; parentElement, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; automationID)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyCondition&lt;/SPAN&gt; propertyCondition = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;PropertyCondition&lt;/SPAN&gt;( &lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt;.AutomationIdProperty, automationID);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; parentElement.FindFirst(&lt;SPAN style="COLOR: #2b91af"&gt;TreeScope&lt;/SPAN&gt;.Element | &lt;SPAN style="COLOR: #2b91af"&gt;TreeScope&lt;/SPAN&gt;.Descendants, propertyCondition);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;- Attach to the Find People dialog Closed event:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; dialog = FindWindowByName(&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt;.RootElement, &lt;SPAN style="COLOR: #a31515"&gt;"Find People"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (dialog != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Automation&lt;/SPAN&gt;.AddAutomationEventHandler(&lt;SPAN style="COLOR: #2b91af"&gt;WindowPattern&lt;/SPAN&gt;.WindowClosedEvent, dialog, &lt;SPAN style="COLOR: #2b91af"&gt;TreeScope&lt;/SPAN&gt;.Element,&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dialogEventHandler = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;AutomationEventHandler&lt;/SPAN&gt;(OnWindowClosedEvent));&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;...&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; OnWindowClosedEvent(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; src, &lt;SPAN style="COLOR: #2b91af"&gt;AutomationEventArgs&lt;/SPAN&gt; e)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"On window closed event"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;- Attach to&amp;nbsp;the Dialog's Close&amp;nbsp;Button Clicked event:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; closeButton = FindElementById(dialog, &lt;SPAN style="COLOR: #a31515"&gt;"68"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (closeButton != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Automation&lt;/SPAN&gt;.AddAutomationEventHandler(&lt;SPAN style="COLOR: #2b91af"&gt;InvokePattern&lt;/SPAN&gt;.InvokedEvent,closeButton, &lt;SPAN style="COLOR: #2b91af"&gt;TreeScope&lt;/SPAN&gt;.Element,&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clickedEventHandler = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;AutomationEventHandler&lt;/SPAN&gt;(OnCloseButtonClickedEvent));&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;...&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; OnCloseButtonClickedEvent(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; src, &lt;SPAN style="COLOR: #2b91af"&gt;AutomationEventArgs&lt;/SPAN&gt; e)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"On button clicked event"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;STRONG&gt;- Get and set the value of the Name text box of the Find People dialog:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; text = FindElementById(mainWindow, &lt;SPAN style="COLOR: #a31515"&gt;"1152"&lt;/SPAN&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;//Automation Id = 1152 of Name text box find&amp;nbsp;with UISpy&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (text != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;//get content&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;TextPattern&lt;/SPAN&gt; txtPattern = text.GetCurrentPattern(&lt;SPAN style="COLOR: #2b91af"&gt;TextPattern&lt;/SPAN&gt;.Pattern) &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;TextPattern&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (txtPattern != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) &lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; content = txtPattern.DocumentRange.GetText(-1);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Out.WriteLine(content);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: green"&gt;//write content&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: #2b91af"&gt;ValuePattern&lt;/SPAN&gt; valuePattern = text.GetCurrentPattern(&lt;SPAN style="COLOR: #2b91af"&gt;ValuePattern&lt;/SPAN&gt;.Pattern) &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ValuePattern&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;valuePattern.SetValue(&lt;SPAN style="COLOR: #a31515"&gt;"new value"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;- Set a combo box value:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; combo = FindElementById(dialog, &lt;SPAN style="COLOR: #a31515"&gt;"99"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (combo != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;AutomationElement&lt;/SPAN&gt; item = FindListItemByName(combo,&lt;SPAN style="COLOR: #a31515"&gt;"Active Directory"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;SelectionItemPattern&lt;/SPAN&gt; itemPattern = item.GetCurrentPattern(&lt;SPAN style="COLOR: #2b91af"&gt;SelectionItemPattern&lt;/SPAN&gt;.Pattern) &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SelectionItemPattern&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; itemPattern.Select();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Well...that's it. I hope this helps for a start. Enjoy!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Sole&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3780239" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/gwoDd3rmf24" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/WPF/default.aspx">WPF</category><category domain="http://weblogs.asp.net/spano/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/spano/archive/tags/.NET/default.aspx">.NET</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/09/07/wpf-accessibility.aspx</feedburner:origLink></item><item><title>New @ weblogs</title><link>http://feedproxy.google.com/~r/spano/~3/iK7SEQhLevY/foreword.aspx</link><pubDate>Fri, 07 Sep 2007 15:33:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3780214</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/09/07/foreword.aspx#comments</comments><description>&lt;FONT face="Times New Roman" size=3&gt;HI! this is my first post @ weblogs.asp.net. I'm moving from &lt;/FONT&gt;&lt;A href="mailto:solepano@blogspot.com" mce_href="mailto:solepano@blogspot.com"&gt;&lt;SPAN style="COLOR: #669966; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin"&gt;&lt;FONT face="Times New Roman" size=3&gt;http://solepano.blogspot.com&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;,&amp;nbsp;where I've been blogging since last year. I would like to introduce myself with a few words:&amp;nbsp;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Times New Roman" size=3&gt;My name is Soledad Pano, I live in Buenos Aires - Argentina, have a degree in Electronic Engineer from the University of Buenos Aires, and work as a software consultant&amp;nbsp;at &lt;/FONT&gt;&lt;A href="http://www.lagash.com/" mce_href="http://www.lagash.com/"&gt;&lt;SPAN style="COLOR: #669966; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin"&gt;&lt;FONT face="Times New Roman" size=3&gt;Lagash Systems&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;. I’ve been working with the .Net technology for the last&amp;nbsp;four years, and the purpose of this blog is to&amp;nbsp;share thoughts, news,&amp;nbsp;code samples, etc,&amp;nbsp;about&amp;nbsp;several&amp;nbsp;.Net technologies and products. I'm also interested in more&amp;nbsp;general topics, such as software quality, metrics, testing, agile, technical tools, etc. &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;You are totally welcome to contribute&amp;nbsp;with any comments, questions, answers, suggestions, whatever. I will really appreciate your participation. &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Have fun! &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Sole&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3780214" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/iK7SEQhLevY" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/09/07/foreword.aspx</feedburner:origLink></item><item><title>Working around VSTO SE's lack of document-customization for Excel 2007</title><link>http://feedproxy.google.com/~r/spano/~3/lQVVOma22r0/working-around-vsto-se-s-lack-of-document-customization-for-excel-2007.aspx</link><pubDate>Sun, 10 Jun 2007 22:42:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3810346</guid><dc:creator>spano</dc:creator><slash:comments>0</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/06/10/working-around-vsto-se-s-lack-of-document-customization-for-excel-2007.aspx#comments</comments><description>&lt;p&gt;&lt;i&gt;&lt;font color="#808080"&gt;This post was originally published at &lt;/font&gt;&lt;/i&gt;&lt;a href="http://solepano.blogspot.com/"&gt;&lt;i&gt;&lt;font color="#808080"&gt;http://solepano.blogspot.com&lt;/font&gt;&lt;/i&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I've been doing some research on &lt;a href="http://msdn2.microsoft.com/en-us/office/aa905533.aspx" mce_href="http://msdn2.microsoft.com/en-us/office/aa905533.aspx"&gt;Visual Studio Tools for Office (VSTO)&lt;/a&gt;  and Excel 2007 recently and found out that some very interesting features available in previous versions of VSTO for Excel 2003 are not available for Excel 2007. Here's a summary of the current situation and the workarounds I figured out. &lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt; &lt;/p&gt; &lt;p&gt;&lt;b&gt;State of the Art&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;VSTO has basically two kinds of Excel add-ins: document-level customization an application-level add-ins. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The &lt;b&gt;document-level customization&lt;/b&gt; lets you customize an Excel workbook and also reference the Application to add buttons to the command bar and so forth. The resulting add-in will be only available to the customized workbook. The great benefit of document-level customization is that you can add controls to the spreadsheets within Visual Studio, being these controls part of the VSTO object model. The VSTO objects are wrappers around the Interop ones and they add very interesting functionality, like events and databinding. The VSTO controls are in the Microsoft.Office.Tools.Excel namespace whereas the Interop ones are in Microsoft.Office.Interop.Excel.&lt;/p&gt; &lt;p face="arial" style="text-align: center; font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s1600-h/excelWorkbook1.JPG" mce_href="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s1600-h/excelWorkbook1.JPG"&gt;&lt;img src="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s320/excelWorkbook1.JPG" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" mce_src="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPTtkDxgI/AAAAAAAAABI/D_MAjuk0EWE/s320/excelWorkbook1.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588448950830594" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center; font-family: arial; font-weight: bold;"&gt;&lt;span style="font-weight: bold; font-size: 78%;"&gt;Document-level customization project template&lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="text-align: center; font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPfdkDxhI/AAAAAAAAABQ/rgEnBD0Nq7I/s1600-h/excelWorkbook2.JPG" mce_href="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPfdkDxhI/AAAAAAAAABQ/rgEnBD0Nq7I/s1600-h/excelWorkbook2.JPG"&gt;&lt;img src="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPfdkDxhI/AAAAAAAAABQ/rgEnBD0Nq7I/s320/excelWorkbook2.JPG" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" mce_src="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPfdkDxhI/AAAAAAAAABQ/rgEnBD0Nq7I/s320/excelWorkbook2.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588650814293522" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;span style="font-size: 78%;"&gt;&lt;span style="font-weight: bold;"&gt;Document-level customization project&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;On the other and, an &lt;b&gt;application-level add-in&lt;/b&gt; is, as its name implies, always visible for the host Application regardless of the opened workbook. The only class added by Visual Studio is the TheAddin one, no workbook or worksheet editors are provided. The VSTO controls are not available neither. All Excel objects that we can get access through TheAddin class are from the Microsoft.Office.Interop.Excel API.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPqdkDxiI/AAAAAAAAABY/Xc-ep1cZVoI/s1600-h/exceladdin1.JPG" mce_href="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPqdkDxiI/AAAAAAAAABY/Xc-ep1cZVoI/s1600-h/exceladdin1.JPG"&gt;&lt;img src="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPqdkDxiI/AAAAAAAAABY/Xc-ep1cZVoI/s320/exceladdin1.JPG" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" mce_src="http://bp2.blogger.com/_vRmmMCC9gL0/RmyPqdkDxiI/AAAAAAAAABY/Xc-ep1cZVoI/s320/exceladdin1.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588839792854562" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center; font-weight: bold;"&gt;&lt;span style="font-size: 78%;"&gt;Application-level add-in project template&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPvtkDxjI/AAAAAAAAABg/Mls4ceGD-80/s1600-h/exceladdin2.JPG" mce_href="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPvtkDxjI/AAAAAAAAABg/Mls4ceGD-80/s1600-h/exceladdin2.JPG"&gt;&lt;img src="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPvtkDxjI/AAAAAAAAABg/Mls4ceGD-80/s320/exceladdin2.JPG" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" mce_src="http://bp3.blogger.com/_vRmmMCC9gL0/RmyPvtkDxjI/AAAAAAAAABg/Mls4ceGD-80/s320/exceladdin2.JPG" alt="" id="BLOGGER_PHOTO_ID_5074588929987167794" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="font-weight: bold; text-align: center;"&gt;&lt;span style="font-size: 78%;"&gt;Application-level add-in project&lt;br&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The problem is that, whereas document-level customization is available for Excel2003, is not yet available for Excel 2007. So, the spreadsheet editor is not available within Visual Studio and the VSTO extended controls cannot be used. The table below shows which kinds of add-in are available for each product combination (see &lt;a href="http://msdn2.microsoft.com/en-us/library/aa942839%28VS.80%29.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa942839%28VS.80%29.aspx"&gt;Features available by product combination&lt;/a&gt; for the complete table listing all Office applications).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;br&gt;&lt;/td&gt; &lt;td&gt;VSTO 2005 or Visual Studio Team System&lt;/td&gt; &lt;td&gt;VSTO 2005 SE installed with VSTO 2005 or Visual Studio Team System&lt;/td&gt; &lt;td&gt;VSTO 2005 SE installed with Visual Studio 2005 Professional Edition&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Document-level customizations&lt;/td&gt; &lt;td&gt;Excel 2003&lt;/td&gt; &lt;td&gt;Excel 2003&lt;/td&gt; &lt;td&gt;Not available&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Application-level add-ins&lt;/td&gt; &lt;td&gt;Not available&lt;/td&gt; &lt;td&gt; &lt;p&gt;Excel 2003 &lt;/p&gt; &lt;p&gt;Excel 2007&lt;/p&gt;&lt;/td&gt; &lt;td&gt; &lt;p&gt;Excel 2003 &lt;/p&gt; &lt;p&gt;Excel 2007&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;Workarounds&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;In order to make a document-level customization (or at least something similar) to target Excel 2007 I found out that some of the following things can be done:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1- Develop for Excel 2003 and deploy in Excel 2007&lt;/p&gt; &lt;p&gt;It is possible to develop a document-level customization in Visual Studio for Excel 2003 using VSTO 2005. The resulting customized document can then be opened in Excel 2007 in compatibility mode with the same functionality. The drawbacks of this approach is that Excel 2003 needs to be installed in the developer's machine and that you won't have Office 2007 features like custom panes and ribbon extensibility available.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;2- Develop for Excel 2007 with VSTO SE and try to emulate the document-level customization.&lt;/p&gt; &lt;p&gt; In order to target Excel 2007, VSTO SE is needed and the only option by the moment is to create an application level add-in. For emulating the document customization you can create an Excel's template file within Excel application, add the desired named ranges, tables, graphics, etc...and then access these controls trough the add-in's code to make custom automation. The drawback of this approach is that the extended functionality of VSTO's controls is not available. For example, you won't be able to use the ListObject databinding support. In order to access the workbook controls, the Interop API must be used. Another drawback, is that the Interop API is not as well documented as the VSTO's.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;3- Develop an application-level add-in for Excel 2007 and create the VSTO's objects from code.&lt;/p&gt; &lt;p&gt;Actually I'm not sure wheter this is really a choice, since I couldn't make it work. What I tried here was to create a new instance of a VSTO worksheet to wrap an Interop worksheet. In ThisAddin class I have the following code:&lt;/p&gt; &lt;p&gt;&lt;!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 using\cf0  Excel = Microsoft.Office.Interop.Excel;\par ??\cf2 using\cf0  Vsto = Microsoft.Office.Tools.Excel;\par ??\par ??\cf2 namespace\cf0  ExcelAddIn1\par ??\{\par ??    \cf2 public\cf0  \cf2 partial\cf0  \cf2 class\cf0  \cf10 ThisAddIn\par ??\cf0     \{\par ??        \cf2 private\cf0  \cf2 void\cf0  ThisAddIn_Startup(\cf2 object\cf0  sender, System.\cf10 EventArgs\cf0  e)\par ??        \{\par ??\cf2             #region\cf0  VSTO generated code\par ??\par ??            \cf2 this\cf0 .Application = (Excel.\cf10 Application\cf0 )Microsoft.Office.Tools.Excel.\cf10 ExcelLocale1033Proxy\cf0 .Wrap(\cf2 typeof\cf0 (Excel.\cf10 Application\cf0 ), \cf2 this\cf0 .Application);\par ??\par ??\cf2             #endregion\par ??\par ??\cf0             \cf2 try\par ??\cf0             \{\par ??                Excel.\cf10 Worksheet\cf0  newSheet = (Excel.\cf10 Worksheet\cf0 )\cf2 this\cf0 .Application.ActiveWorkbook.Worksheets.Add(\cf10 Type\cf0 .Missing, \cf10 Type\cf0 .Missing, \cf10 Type\cf0 .Missing, \cf10 Type\cf0 .Missing);\par ??                Microsoft.Office.Tools.Excel.\cf10 Worksheet\cf0  extendedSheet = GetExtendedWorksheet(newSheet);\par ??                extendedSheet.Controls.AddNamedRange(extendedSheet.Range[\cf13 "A1"\cf0 ,\cf13 "C2"\cf0 ], \cf13 "NamedRange"\cf0 );\par ??            \}\par ??            \cf2 catch\cf0  (\cf10 Exception\cf0  ex) \{\par ??                \cf10 MessageBox\cf0 .Show(ex.ToString());\par ??            \}\par ??        \}\par ??\par ??        \cf2 private\cf0  Vsto.\cf10 Worksheet\cf0  GetExtendedWorksheet(Excel.\cf10 Worksheet\cf0  nativeWorksheet)\par ??        \{\par ??            \cf11 //Get the IHostItemProvider instance.\par ??\cf0             Microsoft.VisualStudio.Tools.Applications.Runtime.\cf10 IHostItemProvider\cf0  hostItemProvider = (Microsoft.VisualStudio.Tools.Applications.Runtime.\cf10 IHostItemProvider\cf0 )\par ??                RuntimeCallback.GetService(\cf2 typeof\cf0 (Microsoft.VisualStudio.Tools.Applications.Runtime.\cf10 IHostItemProvider\cf0 ));\par ??            \cf11 //Create the new worksheet and return it to calling function.\par ??\cf0             \cf2 return\cf0  \cf2 new\cf0  Vsto.\cf10 Worksheet\cf0 (hostItemProvider, RuntimeCallback, nativeWorksheet.CodeName,\par ??               \cf2 null\cf0 , nativeWorksheet.Name);\par ??        \}} --&gt; &lt;/p&gt;&lt;div style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-family: courier new; font-size: 10pt; color: black;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; Excel = Microsoft.Office.Interop.Excel;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt; Vsto = Microsoft.Office.Tools.Excel;&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; ExcelAddIn1&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;partial&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;ThisAddIn&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;    {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ThisAddIn_Startup(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: teal;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;            #region&lt;/span&gt; VSTO generated code&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Application = (Excel.&lt;span style="color: teal;"&gt;Application&lt;/span&gt;)Microsoft.Office.Tools.Excel.&lt;span style="color: teal;"&gt;ExcelLocale1033Proxy&lt;/span&gt;.Wrap(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(Excel.&lt;span style="color: teal;"&gt;Application&lt;/span&gt;), &lt;span style="color: blue;"&gt;this&lt;/span&gt;.Application);&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;            #endregion&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                Excel.&lt;span style="color: teal;"&gt;Worksheet&lt;/span&gt; newSheet = (Excel.&lt;span style="color: teal;"&gt;Worksheet&lt;/span&gt;)&lt;span style="color: blue;"&gt;this&lt;/span&gt;.Application.ActiveWorkbook.Worksheets.Add(&lt;span style="color: teal;"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: teal;"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: teal;"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: teal;"&gt;Type&lt;/span&gt;.Missing);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                Microsoft.Office.Tools.Excel.&lt;span style="color: teal;"&gt;Worksheet&lt;/span&gt; extendedSheet = GetExtendedWorksheet(newSheet);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                extendedSheet.Controls.AddNamedRange(extendedSheet.Range[&lt;span style="color: maroon;"&gt;"A1"&lt;/span&gt;,&lt;span style="color: maroon;"&gt;"C2"&lt;/span&gt;], &lt;span style="color: maroon;"&gt;"NamedRange"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;catch&lt;/span&gt; (&lt;span style="color: teal;"&gt;Exception&lt;/span&gt; ex) {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                &lt;span style="color: teal;"&gt;MessageBox&lt;/span&gt;.Show(ex.ToString());&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        }&lt;/p&gt; &lt;p style="margin: 0px;"&gt; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;        &lt;span style="color: blue;"&gt;private&lt;/span&gt; Vsto.&lt;span style="color: teal;"&gt;Worksheet&lt;/span&gt; GetExtendedWorksheet(Excel.&lt;span style="color: teal;"&gt;Worksheet&lt;/span&gt; nativeWorksheet)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color: green;"&gt;//Get the IHostItemProvider instance.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            Microsoft.VisualStudio.Tools.Applications.Runtime.&lt;span style="color: teal;"&gt;IHostItemProvider&lt;/span&gt; hostItemProvider = (Microsoft.VisualStudio.Tools.Applications.Runtime.&lt;span style="color: teal;"&gt;IHostItemProvider&lt;/span&gt;)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;                RuntimeCallback.GetService(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(Microsoft.VisualStudio.Tools.Applications.Runtime.&lt;span style="color: teal;"&gt;IHostItemProvider&lt;/span&gt;));&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color: green;"&gt;//Create the new worksheet and return it to calling function.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;            &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; Vsto.&lt;span style="color: teal;"&gt;Worksheet&lt;/span&gt;(hostItemProvider, RuntimeCallback, nativeWorksheet.CodeName,&lt;/p&gt; &lt;p style="margin: 0px;"&gt;               &lt;span style="color: blue;"&gt;null&lt;/span&gt;, nativeWorksheet.Name);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;        }&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;But, when trying to add the NamedRange to the extended worksheet this Exception is thrown:&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: Courier New; font-size: 85%;"&gt;&lt;i&gt;This document might not function as expected because the following control is missing: Sheet4. Data that relies on this control will not be automatically displayed or updated, and other custom functionality will not be available. Contact your administrator or the author of this document for further assistance.&lt;br&gt;at Microsoft.Office.Tools.Excel.Worksheet.GetObjects()&lt;br&gt;at Microsoft.Office.Tools.Excel.Worksheet.GetPrimaryControl()&lt;br&gt;at Microsoft.Office.Tools.Excel.Worksheet.get_Range()&lt;br&gt;at ExcelAddIn1.ThisAddIn.ThisAddIn_Startup(Object sender, EventArgs e) in C:\...\Projects\ExcelAddIn1\ExcelAddIn1\ThisAddIn.cs:line 26&lt;/i&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Although VSTO's document-level customization is not available for Excel 2007 yet, there still are some choices for developing add-ins targeting this application version. Besides, the good news is that this lack will be supplied soon. VSTO "Orcas" will provide document-level customization for Excel 2007 within its new features. So, anyway, it's just a matter of time...&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3810346" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/lQVVOma22r0" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/spano/archive/tags/Office/default.aspx">Office</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/06/10/working-around-vsto-se-s-lack-of-document-customization-for-excel-2007.aspx</feedburner:origLink></item><item><title>Developing a Custom Property Comparison Validator using Entlib's VAP</title><link>http://feedproxy.google.com/~r/spano/~3/aFFU9zPLO4c/developing-a-custom-property-comparison-validator-using-entlib-s-vap.aspx</link><pubDate>Wed, 16 May 2007 16:03:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3810397</guid><dc:creator>spano</dc:creator><slash:comments>1</slash:comments><comments>http://weblogs.asp.net/spano/archive/2007/05/16/developing-a-custom-property-comparison-validator-using-entlib-s-vap.aspx#comments</comments><description>&lt;p&gt;&lt;em&gt;&lt;font color="#808080"&gt;This post was originally published at &lt;/font&gt;&lt;/em&gt;&lt;a href="http://solepano.blogspot.com/"&gt;&lt;em&gt;&lt;font color="#808080"&gt;http://solepano.blogspot.com&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Here's a sample scenario where, in an application using Entlib's Validation Application Block (VAP), the validation of an entity's member depends on the value of &amp;nbsp;another property. In this case the entity I want to validate has two properties. Using the attributes approach to support validation, the entity's code looks like this:&lt;/p&gt; &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 public\cf0  \cf2 class\cf0  \cf10 MyEntity\par ??\cf0 \{\par ??    \cf2 private\cf0  \cf2 string\cf0  myVar1;\par ??\par ??    [\cf10 NotNullValidator\cf0 ()]\par ??    [\cf10 StringLengthValidator\cf0 (0, 20, MessageTemplate = \cf13 "MyProperty1 must be less than 20 characters length"\cf0 )]\par ??    \cf2 public\cf0  \cf2 string\cf0  MyProperty1\par ??    \{\par ??        \cf2 get\cf0  \{ \cf2 return\cf0  myVar1; \}\par ??        \cf2 set\cf0  \{ myVar1 = \cf2 value\cf0 ; \}\par ??    \}\par ??\par ??    \cf2 private\cf0  \cf2 string\cf0  myVar2;\par ??\par ??    [\cf10 MyProp2Validator\cf0 ()]\par ??    \cf2 public\cf0  \cf2 string\cf0  MyProperty2\par ??    \{\par ??        \cf2 get\cf0  \{ \cf2 return\cf0  myVar2; \}\par ??        \cf2 set\cf0  \{ myVar2 = \cf2 value\cf0 ; \}\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;/p&gt;&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;MyEntity&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; myVar1;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: teal;"&gt;NotNullValidator&lt;/span&gt;()]&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: teal;"&gt;StringLengthValidator&lt;/span&gt;(0, 20, MessageTemplate = &lt;span style="color: maroon;"&gt;"MyProperty1 must be less than 20 characters length"&lt;/span&gt;)]&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; MyProperty1&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; myVar1; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt; { myVar1 = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; myVar2;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: teal;"&gt;MyProp2Validator&lt;/span&gt;()]&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; MyProperty2&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; myVar2; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt; { myVar2 = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The validators for Property1 are built in validators, no big deal with that. The thing here is that I want the second property to be validated against the value of the first one. Let’s say, for example, that Property2 is valid if it begins with the value of Property1. &lt;/p&gt; &lt;p&gt;Although the VAP ships with a &lt;b&gt;PropertyComparisonValidator&lt;/b&gt;, it is limited to comparisons of type =, !=, &amp;gt;, &amp;gt;=, &amp;lt;&amp;gt;. So it seems that a custom validator has to be made. But how to obtain the actual value of Property1 from the Property2's custom validator?  &lt;/p&gt;&lt;p&gt;One approach is to use reflection. Using reflection the DoValidate method of MyProperty2Validator would look something like this:  &lt;/p&gt;&lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 protected\cf0  \cf2 override\cf0  \cf2 void\cf0  DoValidate(\cf2 string\cf0  objectToValidate, \cf2 object\cf0  currentTarget, \cf2 string\cf0  key, ValidationResults validationResults)\{\par ??    \cf11 //obtain the other property value through reflection\par ??\cf0     PropertyInfo prop = currentTarget.GetType().GetProperty(\cf13 "MyProperty1"\cf0 );\par ??    \cf2 string\cf0  myProp1Value = prop.GetValue(currentTarget, \cf2 null\cf0 ) \cf2 as\cf0  \cf2 string\cf0 ;\par ??    \cf11 //some custom logic here\par ??\cf0     \cf2 if\cf0  (! objectToValidate.StartsWith( myProp1Value )\{\par ??         LogValidationResult(validationResults,\cf13 "msg"\cf0 ,currentTarget,key);\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;/p&gt;&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; DoValidate(&lt;span style="color: blue;"&gt;string&lt;/span&gt; objectToValidate, &lt;span style="color: blue;"&gt;object&lt;/span&gt; currentTarget, &lt;span style="color: blue;"&gt;string&lt;/span&gt; key, ValidationResults validationResults){&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//obtain the other property value through reflection&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyInfo prop = currentTarget.GetType().GetProperty(&lt;span style="color: maroon;"&gt;"MyProperty1"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; myProp1Value = prop.GetValue(currentTarget, &lt;span style="color: blue;"&gt;null&lt;/span&gt;) &lt;span style="color: blue;"&gt;as&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//some custom logic here&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (! objectToValidate.StartsWith( myProp1Value ){&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; LogValidationResult(validationResults,&lt;span style="color: maroon;"&gt;"msg"&lt;/span&gt;,currentTarget,key);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;But the dropdown of using reflection is that it wouldn't work with UI integration.  &lt;/p&gt;&lt;p&gt;What do work with integration is what the built-in PropertyComparisonValidator does, and that is using the &lt;b&gt;ValueAccess&lt;/b&gt; class. The ValueAccess class allow us to find other members in an integration friendly way throuhg its GetValue method. See how this is done in our Property2 valdiator:  &lt;/p&gt;&lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 [\cf10 ConfigurationElementType\cf0 (\cf2 typeof\cf0 (\cf10 MyProp2ValidatorData\cf0 ))]\par ??\cf2 class\cf0  \cf10 MyProp2Validator\cf0  : \cf10 Validator\cf0 &amp;lt;\cf2 string\cf0 &amp;gt; \{\par ??    \cf2 private\cf0  \cf10 ValueAccess\cf0  valueAccess;\par ??    \cf2 internal\cf0  \cf2 const\cf0  \cf2 string\cf0  OtherPropName = \cf13 "MyProperty1"\cf0 ;\par ??\par ??    \cf2 public\cf0  MyProp2Validator(\cf10 ValueAccess\cf0  valueAccess):\cf2 base\cf0  (\cf10 Resources\cf0 .MyProp2ValidatorMessageTemplate,\cf2 null\cf0 )\{\par ??        \cf2 this\cf0 .valueAccess = valueAccess;\par ??    \}\par ??\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf2 void\cf0  DoValidate(\cf2 string\cf0  objectToValidate, \cf2 object\cf0  currentTarget, \cf2 string\cf0  key, \cf10 ValidationResults\cf0  validationResults)\{\par ??        \cf2 object\cf0  myProp1;\par ??        \cf2 string\cf0  valueAccessFailureMessage;\par ??        \cf11 //try to obtain the value of property 1.\par ??\cf0         \cf2 if\cf0  (!\cf2 this\cf0 .valueAccess.GetValue(currentTarget, \cf2 out\cf0  myProp1, \cf2 out\cf0  valueAccessFailureMessage)) \{\par ??            \cf2 base\cf0 .LogValidationResult(validationResults, \cf2 string\cf0 .Format(\cf10 CultureInfo\cf0 .CurrentUICulture, \cf10 Resources\cf0 .MyProp2ValidatorFailureToRetrieveProp1, \cf2 new\cf0  \cf2 object\cf0 [] \{ \cf2 this\cf0 .valueAccess.Key, valueAccessFailureMessage \}), currentTarget, key);\par ??        \}\par ??        \cf2 else\cf0  \{\par ??            \cf11 //custom validation logic between prop1 and prop2\par ??\cf0             \cf2 if\cf0  (!objectToValidate.StartsWith((\cf2 string\cf0 )myProp1)) \{ \par ??                \cf2 base\cf0 .LogValidationResult(validationResults, \cf2 string\cf0 .Format(\cf10 CultureInfo\cf0 .CurrentUICulture, \cf2 this\cf0 .MessageTemplate, \cf2 new\cf0  \cf2 object\cf0 [] \{ objectToValidate, myProp1 \}), currentTarget, key);\par ??            \}\par ??        \}\par ??    \}\par ??\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf2 string\cf0  DefaultMessageTemplate \{\par ??        \cf2 get\cf0  \{ \cf2 return\cf0  \cf10 Resources\cf0 .MyProp2ValidatorDefaultMessageTemplate; \}\par ??    \}\par ??\}\par ??}&lt;br /&gt;--&gt; &lt;/p&gt;&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt; &lt;p style="margin: 0px;"&gt;[&lt;span style="color: teal;"&gt;ConfigurationElementType&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: teal;"&gt;MyProp2ValidatorData&lt;/span&gt;))]&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;MyProp2Validator&lt;/span&gt; : &lt;span style="color: teal;"&gt;Validator&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;ValueAccess&lt;/span&gt; valueAccess;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;internal&lt;/span&gt; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; OtherPropName = &lt;span style="color: maroon;"&gt;"MyProperty1"&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; MyProp2Validator(&lt;b&gt;&lt;span style="color: teal;"&gt;ValueAccess&lt;/span&gt; valueAccess&lt;/b&gt;):&lt;span style="color: blue;"&gt;base&lt;/span&gt; (&lt;span style="color: teal;"&gt;Resources&lt;/span&gt;.MyProp2ValidatorMessageTemplate,&lt;span style="color: blue;"&gt;null&lt;/span&gt;){&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.valueAccess = valueAccess;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; DoValidate(&lt;span style="color: blue;"&gt;string&lt;/span&gt; objectToValidate, &lt;span style="color: blue;"&gt;object&lt;/span&gt; currentTarget, &lt;span style="color: blue;"&gt;string&lt;/span&gt; key, &lt;span style="color: teal;"&gt;ValidationResults&lt;/span&gt; validationResults){&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;object&lt;/span&gt; myProp1;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; valueAccessFailureMessage;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//try to obtain the value of property 1.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (!&lt;span style="color: blue;"&gt;this&lt;/span&gt;.&lt;b&gt;valueAccess.GetValue&lt;/b&gt;(currentTarget, &lt;span style="color: blue;"&gt;out&lt;/span&gt; myProp1, &lt;span style="color: blue;"&gt;out&lt;/span&gt; valueAccessFailureMessage)) {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;base&lt;/span&gt;.LogValidationResult(validationResults, &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color: teal;"&gt;CultureInfo&lt;/span&gt;.CurrentUICulture, &lt;span style="color: teal;"&gt;Resources&lt;/span&gt;.MyProp2ValidatorFailureToRetrieveProp1, &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;object&lt;/span&gt;[] { &lt;span style="color: blue;"&gt;this&lt;/span&gt;.valueAccess.Key, valueAccessFailureMessage }), currentTarget, key);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//custom validation logic between prop1 and prop2&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (!objectToValidate.StartsWith((&lt;span style="color: blue;"&gt;string&lt;/span&gt;)myProp1)) { &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;base&lt;/span&gt;.LogValidationResult(validationResults, &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color: teal;"&gt;CultureInfo&lt;/span&gt;.CurrentUICulture, &lt;span style="color: blue;"&gt;this&lt;/span&gt;.MessageTemplate, &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;object&lt;/span&gt;[] { objectToValidate, myProp1 }), currentTarget, key);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; DefaultMessageTemplate {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: teal;"&gt;Resources&lt;/span&gt;.MyProp2ValidatorDefaultMessageTemplate; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;What’s left is to provide the ValueAccess to the validator’s constructor. This is done in the MyProp2ValidatorAttribute class, if using attributes to place validators, or in the MyProp2ValidatorData if using configuration files. MyProp2ValidatorAttribute would look like this:  &lt;/p&gt;&lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 public\cf0  \cf2 class\cf0  \cf10 MyProp2ValidatorAttribute\cf0  : \cf10 ValueValidatorAttribute\par ??\cf0 \{\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf10 Validator\cf0  DoCreateValidator(\cf10 Type\cf0  targetType)\par ??    \{\par ??        \cf2 throw\cf0  \cf2 new\cf0  \cf10 InvalidOperationException\cf0 (\cf13 "se debe crear con con value access builder"\cf0 );\par ??    \}\par ??\par ??    \cf2 protected\cf0  \cf2 override\cf0  \cf10 Validator\cf0  DoCreateValidator(\cf10 Type\cf0  targetType, \cf10 Type\cf0  ownerType, \cf10 MemberValueAccessBuilder\cf0  memberValueAccessBuilder)\par ??    \{\par ??        \cf10 PropertyInfo\cf0  propertyInfo = ownerType.GetProperty(\cf10 MyProp2Validator\cf0 .OtherPropName);\par ??        \cf2 if\cf0  (propertyInfo == \cf2 null\cf0 )\par ??        \{\par ??            \cf2 throw\cf0  \cf2 new\cf0  \cf10 InvalidOperationException\cf0 (\cf10 String\cf0 .Format(\cf10 Resources\cf0 .MyProp2ValidatorAttributeCouldNotFindProperty, \cf2 new\cf0  \cf2 string\cf0 [] \{ ownerType.Name, \cf10 MyProp2Validator\cf0 .OtherPropName \}));\par ??        \}\par ??        \cf2 return\cf0  \cf2 new\cf0  \cf10 MyProp2Validator\cf0 (memberValueAccessBuilder.GetPropertyValueAccess(propertyInfo));\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;/p&gt;&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;MyProp2ValidatorAttribute&lt;/span&gt; : &lt;span style="color: teal;"&gt;ValueValidatorAttribute&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: teal;"&gt;Validator&lt;/span&gt; DoCreateValidator(&lt;span style="color: teal;"&gt;Type&lt;/span&gt; targetType)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: maroon;"&gt;"A member value access builder is needed."&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: teal;"&gt;Validator&lt;/span&gt; DoCreateValidator(&lt;span style="color: teal;"&gt;Type&lt;/span&gt; targetType, &lt;span style="color: teal;"&gt;Type&lt;/span&gt; ownerType, &lt;span style="color: teal;"&gt;MemberValueAccessBuilder&lt;/span&gt; memberValueAccessBuilder)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal;"&gt;PropertyInfo&lt;/span&gt; propertyInfo = ownerType.GetProperty(&lt;span style="color: teal;"&gt;MyProp2Validator&lt;/span&gt;.OtherPropName);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (propertyInfo == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: teal;"&gt;String&lt;/span&gt;.Format(&lt;span style="color: teal;"&gt;Resources&lt;/span&gt;.MyProp2ValidatorAttributeCouldNotFindProperty, &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt;[] { ownerType.Name, &lt;span style="color: teal;"&gt;MyProp2Validator&lt;/span&gt;.OtherPropName }));&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;MyProp2Validator&lt;/span&gt;(memberValueAccessBuilder.GetPropertyValueAccess(propertyInfo));&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Finally, you can test the validation logic using the following code:&lt;/p&gt; &lt;p&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf2 private\cf0  \cf2 void\cf0  buttonValidate_Click(\cf2 object\cf0  sender, \cf10 EventArgs\cf0  e)\par ??\{\par ??    \cf10 MyEntity\cf0  ent = \cf2 new\cf0  \cf10 MyEntity\cf0 ();\par ??    ent.MyProperty1 = textBoxProp1.Text;\par ??    ent.MyProperty2 = textBoxProp2.Text;\par ??    \cf10 ValidationResults\cf0  r = \cf10 Validation\cf0 .Validate&amp;lt;\cf10 MyEntity\cf0 &amp;gt;(ent);        \par ??    \cf2 if\cf0  (!r.IsValid)\par ??    \{\par ??        DisplayValidationResults(r);\par ??    \}\par ??    \cf2 else\cf0  \{\par ??        \cf10 MessageBox\cf0 .Show(\cf13 "ok"\cf0 );\par ??    \}\par ??\}}&lt;br /&gt;--&gt; &lt;/p&gt;&lt;div style="background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt; &lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; buttonValidate_Click(&lt;span style="color: blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color: teal;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;{&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal;"&gt;MyEntity&lt;/span&gt; ent = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;MyEntity&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ent.MyProperty1 = textBoxProp1.Text;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ent.MyProperty2 = textBoxProp2.Text;&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal;"&gt;ValidationResults&lt;/span&gt; r = &lt;span style="color: teal;"&gt;Validation&lt;/span&gt;.Validate&amp;lt;&lt;span style="color: teal;"&gt;MyEntity&lt;/span&gt;&amp;gt;(ent);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (!r.IsValid)&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DisplayValidationResults(r);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt; {&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: teal;"&gt;MessageBox&lt;/span&gt;.Show(&lt;span style="color: maroon;"&gt;"ok"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;It's only left to provide the UI integration for the custom validator to assure averything's working right. I hope to be posting this in a&amp;nbsp;second part soon.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3810397" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/spano/~4/aFFU9zPLO4c" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/spano/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/spano/archive/tags/Entlib/default.aspx">Entlib</category><feedburner:origLink>http://weblogs.asp.net/spano/archive/2007/05/16/developing-a-custom-property-comparison-validator-using-entlib-s-vap.aspx</feedburner:origLink></item></channel></rss>
