<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://community.devexpress.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Mark Miller</title><subtitle type="html" /><id>http://community.devexpress.com/blogs/markmiller/atom.aspx</id><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/default.aspx" /><link rel="self" type="application/atom+xml" href="http://community.devexpress.com/blogs/markmiller/atom.aspx" /><generator uri="http://communityserver.org" version="3.1.30415.43">Community Server</generator><updated>2008-09-08T16:08:00Z</updated><entry><title>Announcing CodeRush Xpress for C#</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/10/27/announcing-coderush-express-for-c.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/10/27/announcing-coderush-express-for-c.aspx</id><published>2008-10-27T20:15:00Z</published><updated>2008-10-27T20:15:00Z</updated><content type="html">&lt;p&gt;Developer Express and Microsoft are proud to announce a new version of CodeRush licensed exclusively for C# developers working in Visual Studio. The new product is called CodeRush Xpress, and it includes a fresh selection of hand-picked features taken from &lt;a target="_blank" href="http://www.devexpress.com/CodeRush"&gt;CodeRush&lt;/a&gt; and &lt;a target="_blank" href="http://www.devexpress.com/Refactor"&gt;Refactor! Pro&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s a sampling of what you get:&lt;/p&gt;
&lt;h3&gt;Find any File or Symbol...&lt;/h3&gt;
&lt;p&gt;Go to any file or symbol in the solution efficiently.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="304" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/Quick%20File%20Navigation_ead6a622-37d5-4e6a-9f64-1b9cdcd0502f.png" alt="Quick File Navigation" height="234" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Type in a few letters of the name to filter...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="304" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/Quick%20File%20Navigation-call_8fdea9bd-6e70-47bf-bc50-7d97f0567353.png" alt="Quick File Navigation-call" height="134" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;Or hold down the shift key to filter only on uppercase letters...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="304" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/Quick%20File%20Navigation-R_2525b2ff-32d0-4159-9d0c-b0dd052c569b.png" alt="Quick File Navigation-R" height="174" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;Uppercase characters can appear anywhere. Any uppercase characters not specified in the filter are highlighted in blue...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="304" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/Quick%20File%20Navigation-RC_0f32ca5a-ad3c-4a15-8a56-fee15e9e6792.png" alt="Quick File Navigation-RC" height="134" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;The uppercase letters need not be sequential. Notice how &amp;quot;RD&amp;quot; in the screen shot below matches both &amp;quot;&lt;span style="color:#ff0000;"&gt;R&lt;/span&gt;esolve&lt;span style="color:#ff0000;"&gt;D&lt;/span&gt;elegate.cs&amp;quot; and &amp;quot;&lt;span style="color:#ff0000;"&gt;R&lt;/span&gt;esolve&lt;span style="color:#3366ff;"&gt;C&lt;/span&gt;allback&lt;span style="color:#ff0000;"&gt;D&lt;/span&gt;elegate.cs&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="304" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/Quick%20File%20Navigation-RD_b89f6a4b-a0ad-4266-8d66-8dd1bb4cffab.png" alt="Quick File Navigation-RD" height="114" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;Tab to Next Reference&lt;/h3&gt;
&lt;p&gt;This is a really cool navigation feature that takes you to the next (and previous) reference just by pressing the &lt;b&gt;Tab &lt;/b&gt;key (or &lt;b&gt;Shift+Tab&lt;/b&gt; key to go backwards) when the caret is inside an identifier, member, or a type. For example, in the following code, the caret was inside the last &lt;strong&gt;Person &lt;/strong&gt;type reference (in the &amp;quot;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#3366ff;"&gt;new&lt;/span&gt; &lt;span style="color:#008080;"&gt;&lt;strong&gt;Person&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;()&lt;/span&gt;&lt;/span&gt;&amp;quot; instantiation call) when the &lt;strong&gt;Tab&lt;/strong&gt; key was pressed, causing the &lt;strong&gt;Person&lt;/strong&gt; reference at the top of the file to become highlighted.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="605" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/TabToNextReference_9c708a6a-818f-4a68-9ad2-743d8281657d.png" alt="TabToNextReference" height="327" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;h3&gt;Expand/Shrink Selection&lt;/h3&gt;
&lt;p&gt;This feature allows you to increase a selection by logical blocks, or decrease an expanded selection by the same logical blocks. This feature is perfect when refactoring, since many refactorings work on a contiguous selection of code (e.g., extract method, introduce local, etc.).&lt;/p&gt;
&lt;h3&gt;TDD-Style Intelligent Declaration Based on Usage&lt;/h3&gt;
&lt;p&gt;Place the caret on any undeclared element in your code and press the Refactor/Code key (Ctrl+`) to see list of intelligent suggestions for the type of the new variable. For example, in the screen shot below two appropriate types are suggested, even though Console.WriteLine has many overloads that accept a wide variety of types.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="670" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/DeclareLocalTwoOptions_63c5a3af-50c6-4e7b-9bb2-ee265c8c1a94.png" alt="DeclareLocalTwoOptions" height="255" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;You can even turn a function call or property access into a variable declaration.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="635" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/DeclareLocalOnProperty_ede4171c-08d4-43ee-a22a-1ada63238aaf.png" alt="DeclareLocalOnProperty" height="203" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;This makes writing code with Visual Studio&amp;#39;s Intellisense really fast. Just use Intellisense to produce the property reference or function call, and then press the Refactor/Code key to declare a new local variable of the appropriate type. Here&amp;#39;s an example with a function call -- notice the caret can be just about anywhere on the function call, even at the end of the line.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="587" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/DeclareLocalOnFunction_1a74526e-907b-4f65-8e64-f08cc58b5481.png" alt="DeclareLocalOnFunction" height="234" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;You can even declare a local from a simple instantiation, like this:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="432" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/DeclareLocalNewPerson_87cc2f58-4221-40de-85cc-85a294b0a19a.png" alt="DeclareLocalNewPerson" height="198" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;And it&amp;#39;s worth noting you can declare &lt;i&gt;all kinds of elements &lt;/i&gt;based on usage, not just locals. Anything you need types, members, fields -- the full list of elements that can be declared appears below.&lt;/p&gt;
&lt;h3&gt;Professional Grade Refactorings&lt;/h3&gt;
&lt;p&gt;CodeRush Xpress includes many powerful refactorings to help improve the quality of your code. For example, consider the following:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;private static void&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt; ShowInt(&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt; n)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;Console&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;.WriteLine(n);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;private static void &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;ShowEntries(&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;List&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;gt; entries)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entries.ForEach((&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;Action&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;gt;)ShowInt);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;With the caret on the ShowInt method reference, you can press the Refactor! key...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="638" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/InlineDelegate_39706ca4-a73e-4f2a-8a2c-262d26472e6e.png" alt="InlineDelegate" height="285" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and then select &lt;b&gt;Inline Delegate&lt;/b&gt;. This will produce the following code:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;private static void &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;ShowEntries(&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;List&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;gt; entries)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entries.ForEach(&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;delegate&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;(&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt; n)&lt;br /&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;br /&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;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;Console&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;.WriteLine(n);&lt;br /&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;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice the caret is on the delegate keyword. You can immediately press the Refactor! key again...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="618" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/CompressToLambdaExpression_63893c50-271a-4fb6-9bcb-47da48ccd303.png" alt="CompressToLambdaExpression" height="205" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Note that we can go in &lt;i&gt;two directions&lt;/i&gt; now. We can either convert the anonymous method to a named method (in essence reversing the Inline Delegate refactoring we just performed), or we can take it a step further and compress the anonymous method into a lambda expression. Choosing &lt;b&gt;Compress to Lambda Expression&lt;/b&gt;, we get the following:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;private static void &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;ShowEntries(&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;List&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;gt; entries)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; entries.ForEach(n =&amp;gt; &lt;/span&gt;&lt;span style="font-family:courier new,courier;color:#2b91af;"&gt;Console&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;.WriteLine(n));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;CodeRush Xpress is loaded with powerful refactorings taken from &lt;a target="_blank" href="http://www.devexpress.com/Refactor"&gt;Refactor! Pro&lt;/a&gt;. One of our favorites, &lt;b&gt;Extract Method to Type&lt;/b&gt;, allows you to extract a method from one type into another, updating both the calling code and the extracted method appropriately. For an example, consider the following code:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public string &lt;/span&gt;Name { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public bool &lt;/span&gt;IsAnOrphan { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;Mother { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;Father { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;span style="color:#800080;"&gt;// ...&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;class &lt;/span&gt;BabyMaker&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;MakeOne(&lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;mother, &lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;father, &lt;span style="color:#0000ff;"&gt;string &lt;/span&gt;name)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Person &lt;/span&gt;newBaby = &lt;span style="color:#0000ff;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newBaby.Name = name;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newBaby.Mother = mother;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newBaby.Father = father;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newBaby.IsAnOrphan = newBaby.Mother == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; newBaby.Father == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return &lt;/span&gt;newBaby;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Notice that the code in the &lt;b&gt;MakeOne &lt;/b&gt;method contains a local variable that&amp;#39;s an instance of type &lt;b&gt;Person&lt;/b&gt;, and that code sets the &lt;b&gt;IsAnOrphan &lt;/b&gt;property. There is some logic in this method that pertains to Person, but it feels like it&amp;#39;s in the wrong class! &lt;/p&gt;
&lt;p&gt;We already have the class &lt;b&gt;Person &lt;/b&gt;in our solution, so it makes sense to move some of this code to the proper class. With CoderRush Xpress installed, all we need to do is select the code we want to move....&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="641" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/SelectCodeToExtract_a636f93a-2b93-4133-9537-dddb494461a6.png" alt="SelectCodeToExtract" height="157" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Press the &lt;b&gt;Refactor &lt;/b&gt;key...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img border="0" width="624" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/ExtractMethodToPerson3_07e70449-3b0b-4c81-a733-85492d0140de.png" alt="ExtractMethodToPerson3" height="379" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;And choose &amp;quot;&lt;b&gt;Extract Method to Person&lt;/b&gt;&amp;quot;. CodeRush Xpress analyzes the selection and determines there&amp;#39;s at least one local variable of a type you have declared elsewhere in the solution. Now let&amp;#39;s apply this refactoring...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img border="0" width="331" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/TargetPicker2_22e01982-2ac1-4914-8362-2768e76c9b5c.png" alt="TargetPicker2" height="125" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Press the &lt;b&gt;Up &lt;/b&gt;and/or &lt;b&gt;Down &lt;/b&gt;arrow keys to select a location for this new method, and press &lt;b&gt;Enter &lt;/b&gt;to commit. Give the method a meaningful name...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="536" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/AnnouncingCodeRushExpressforC_D46F/SetParents_4a3638e0-3510-4a27-b66e-06dfe67bca08.png" alt="SetParents" height="392" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Cool. Now we have the logic (that should have been inside &lt;b&gt;Person&lt;/b&gt; to start with)&lt;b&gt; &lt;/b&gt;right where it belongs. Notice how the new &lt;b&gt;SetParents &lt;/b&gt;instance method works on the instance itself (compare that code with the original code that operated on the newBaby local). The code is easier to read and cleaner in both locations.&lt;/p&gt;
&lt;p&gt;Notice also that tiny dark blue triangle, in the code above. That&amp;#39;s a &lt;i&gt;stack-based marker&lt;/i&gt;, and CodeRush Xpress drops markers automatically whenever you apply a refactoring or TDD-style declaration that takes you away from the original location. You can jump back at any time to the top marker on the stack by pressing &lt;b&gt;Escape&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;There are many more refactorings and cool features in CodeRush Xpress. This is just a preview. Here&amp;#39;s the full list of what you get:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="color:#5081c0;"&gt;Editor Features&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Duplicate Line&lt;/li&gt;
&lt;li&gt;Highlight Usages&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#5081c0;"&gt;Clipboard Features &lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Smart Cut/Copy&lt;/li&gt;
&lt;li&gt;Paste Replace&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#5081c0;"&gt;Enhanced Selection Abilities&lt;/span&gt; 
&lt;ul&gt;
&lt;li&gt;Extend/reduce selection&lt;/li&gt;
&lt;li&gt;Camel-case selection&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="color:#5081c0;"&gt;Navigation Features&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Camel-case Navigation&lt;/li&gt;
&lt;li&gt;Tab to Next Reference&lt;/li&gt;
&lt;li&gt;Go to File&lt;/li&gt;
&lt;li&gt;Go to Symbol (QuickNav)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="color:#5081c0;"&gt;TDD - Declaration from Usage&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color:#5081c0;"&gt;Types &lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Declare Class&lt;/li&gt;
&lt;li&gt;Declare Delegate&lt;/li&gt;
&lt;li&gt;Declare Enum&lt;/li&gt;
&lt;li&gt;Declare Enum Element&lt;/li&gt;
&lt;li&gt;Declare Interface&lt;/li&gt;
&lt;li&gt;Declare Struct&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#5081c0;"&gt;Members &lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Declare Constructor&lt;/li&gt;
&lt;li&gt;Declare Event Handler&lt;/li&gt;
&lt;li&gt;Declare Getter&lt;/li&gt;
&lt;li&gt;Declare Method&lt;/li&gt;
&lt;li&gt;Declare Property&lt;/li&gt;
&lt;li&gt;Declare Property (auto-implemented)&lt;/li&gt;
&lt;li&gt;Declare Property (with backing field)&lt;/li&gt;
&lt;li&gt;Declare Setter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#5081c0;"&gt;Variables&lt;/span&gt; 
&lt;ul&gt;
&lt;li&gt;Declare Field&lt;/li&gt;
&lt;li&gt;Declare Local&lt;/li&gt;
&lt;li&gt;Declare Local (implicit)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="color:#5081c0;"&gt;Refactorings&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add/Remove Block Delimiters&lt;/li&gt;
&lt;li&gt;Combine Conditionals (merge nested &amp;quot;If&amp;quot; statements)&lt;/li&gt;
&lt;li&gt;Compress to Lambda Expression&lt;/li&gt;
&lt;li&gt;Compress to Ternary Expression&lt;/li&gt;
&lt;li&gt;Convert to Auto-implemented Property&lt;/li&gt;
&lt;li&gt;Convert to Initializer (use object/collection initialize when possible)&lt;/li&gt;
&lt;li&gt;Create Backing Store (converts Auto-implemented Property to standard Property with get and set)&lt;/li&gt;
&lt;li&gt;Decompose Initializer&lt;/li&gt;
&lt;li&gt;Decompose Parameter&lt;/li&gt;
&lt;li&gt;Expand Lambda Expression&lt;/li&gt;
&lt;li&gt;Expand Ternary Expression&lt;/li&gt;
&lt;li&gt;Extract Method to Type&lt;/li&gt;
&lt;li&gt;Flatten Conditional&lt;/li&gt;
&lt;li&gt;Introduce Local (introduce variable)&lt;/li&gt;
&lt;li&gt;Inline Delegate&lt;/li&gt;
&lt;li&gt;Inline Temp (inline variable)&lt;/li&gt;
&lt;li&gt;Make Explicit&lt;/li&gt;
&lt;li&gt;Make Implicit&lt;/li&gt;
&lt;li&gt;Move Type to File&lt;/li&gt;
&lt;li&gt;Name Anonymous Method&lt;/li&gt;
&lt;li&gt;Name Anonymous Type&lt;/li&gt;
&lt;li&gt;Reverse Conditional (invert &amp;quot;if&amp;quot;)&lt;/li&gt;
&lt;li&gt;Split Conditional (split complex &amp;quot;If&amp;quot; statements)&lt;/li&gt;
&lt;li&gt;Use StringBuilder&lt;/li&gt;
&lt;li&gt;Use String.Format&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://community.devexpress.com/aggbug.aspx?PostID=237599" width="1" height="1"&gt;</content><author><name>Mark Miller (Developer Express)</name><uri>http://community.devexpress.com/members/Mark-Miller-_2800_Developer-Express_2900_.aspx</uri></author></entry><entry><title>If there's one thing you see at PDC...</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/10/24/if-there-s-one-thing-you-see-at-pdc.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/10/24/if-there-s-one-thing-you-see-at-pdc.aspx</id><published>2008-10-24T19:05:00Z</published><updated>2008-10-24T19:05:00Z</updated><content type="html">&lt;p&gt;If there&amp;#39;s one thing you see, one place you want to be... this is it.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;Time:&lt;/span&gt; Monday night, 6:55pm&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;Place: &lt;/span&gt;PDC. Exhibition hall. The Oversized 30x30 DevExpress booth.&lt;/p&gt;
&lt;p&gt;At this time and place, DevExpress will be showing quite likely the most amazing thing ever presented at any technical conference ever (if not the most amazing thing anyone has ever seen or will ever see in the entire history and future of humanity). And that&amp;#39;s an understatement. I haven&amp;#39;t even begun to raise expectations yet. &lt;/p&gt;
&lt;p&gt;I&amp;#39;m not kidding.&lt;/p&gt;
&lt;p&gt;This will be the event that everyone will be blogging about and talking about. If you&amp;#39;re there, you&amp;#39;ll be among those who will speak with authority. If you&amp;#39;re not, well, I don&amp;#39;t even want to look at your face anymore.&lt;/p&gt;
&lt;p&gt;Seriously.&lt;/p&gt;
&lt;p&gt;Now, back to work on cloning my new assistant for the demo....&lt;/p&gt;&lt;img src="http://community.devexpress.com/aggbug.aspx?PostID=239321" width="1" height="1"&gt;</content><author><name>Mark Miller (Developer Express)</name><uri>http://community.devexpress.com/members/Mark-Miller-_2800_Developer-Express_2900_.aspx</uri></author><category term="PDC 2008" scheme="http://community.devexpress.com/blogs/markmiller/archive/tags/PDC+2008/default.aspx" /></entry><entry><title>Think I'm Starting a Trend</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/10/24/think-i-m-starting-a-trend.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/10/24/think-i-m-starting-a-trend.aspx</id><published>2008-10-24T19:01:00Z</published><updated>2008-10-24T19:01:00Z</updated><content type="html">&lt;p&gt;Looks like&amp;nbsp;Julian has started to fancy my &lt;a href="http://community.devexpress.com/blogs/thinking/archive/2008/10/24/changing-the-world-video-preview-in-production.aspx"&gt;new Mr. Clean look&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://community.devexpress.com/aggbug.aspx?PostID=239315" width="1" height="1"&gt;</content><author><name>Mark Miller (Developer Express)</name><uri>http://community.devexpress.com/members/Mark-Miller-_2800_Developer-Express_2900_.aspx</uri></author></entry><entry><title>IDE Team Discussion - Using CodeRush Templates to Generate Code</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/18/ide-team-discussion-using-coderush-templates-to-generate-code.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/09/18/ide-team-discussion-using-coderush-templates-to-generate-code.aspx</id><published>2008-09-18T20:47:00Z</published><updated>2008-09-18T20:47:00Z</updated><content type="html">&lt;p&gt;CodeRush users interested in creating templates that generate custom code based on elements inside a container (e.g., fields in a class, methods in a type, types in a namespace, comments in a file, etc.), might want to check out this &lt;a href="http://www.youtube.com/watch?v=apIu9_tQavg"&gt;YouTube video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In it, the IDE Team discusses some work we&amp;#39;re doing, where we need to add custom code to serialize and deserialize the fields of around 30 classes. The solution came in creating a template that iterates through the fields in each class and generates the appropriate serialization or deserialization code for each field. &lt;/p&gt;
&lt;p&gt;The main template looks like this:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="color:#ff6600;font-family:courier new,courier;"&gt;&amp;laquo;:ccsr&amp;raquo;&lt;/span&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;public override void &lt;/span&gt;WriteData(&lt;span style="color:#008000;"&gt;BinaryWriter &lt;/span&gt;writer)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.WriteData(writer);&lt;br /&gt;&amp;nbsp;&lt;span style="color:#ff0000;"&gt;&amp;laquo;ForEach(Field in this, WriteField)&amp;raquo;&lt;/span&gt;}&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public override void&lt;/span&gt; ReadData(&lt;span style="color:#008000;"&gt;BinaryReader &lt;/span&gt;reader)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.ReadData(reader);&lt;br /&gt;&amp;nbsp;&lt;span style="color:#ff0000;"&gt;&amp;laquo;ForEach(Field in this, ReadField)&amp;raquo;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Both the &lt;strong&gt;ReadField&lt;/strong&gt; and &lt;strong&gt;WriteField&lt;/strong&gt; templates will be called once for each field in the active class. Both of these templates have a number of alternate expansions. The expansion ultimately selected for a particular field is determined by &lt;strong&gt;context&lt;/strong&gt;. You can set context with the Context Picker on the lower right of the Template options page.&lt;/p&gt;
&lt;p&gt;To make this work, we created a new context, called &lt;strong&gt;TypeImplements&lt;/strong&gt;, because many of the scenarios we needed to respond to were dependent upon the type of the field. For example, one of the alternate expansions for ReadField has this context:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;TypeImplements(&lt;span style="color:#0000ff;"&gt;&amp;laquo;?Get(itemType)&amp;raquo;&lt;/span&gt;,System.Boolean)&lt;/p&gt;
&lt;p&gt;You can pass parameters to contexts (like we&amp;#39;ve done here), by right-clicking the context in the Context Picker, and selecting &amp;quot;Parameters...&amp;quot;.&lt;/p&gt;
&lt;p&gt;The expansion for the ReadField template associated with the context above looks like this:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="color:#0000ff;font-family:courier new,courier;"&gt;&amp;laquo;?Get(itemName)&amp;raquo;&lt;/span&gt; = reader.ReadBoolean();&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#0000ff;font-family:Courier New;"&gt;&amp;laquo;?Get(itemName)&amp;raquo;&lt;/span&gt;&amp;nbsp;returns the name of the field we&amp;#39;re iterating over, while &lt;span style="color:#0000ff;font-family:Courier New;"&gt;&amp;laquo;?Get(itemType)&amp;raquo; &lt;/span&gt;returns the full type name. &lt;span style="color:#0000ff;font-family:courier new,courier;"&gt;Get&lt;/span&gt; is a custom StringProvider that you can use to retrieve the value of a template variable stored with the &lt;span style="color:#0000ff;font-family:courier new,courier;"&gt;Set&lt;/span&gt; StringProvider (the &lt;strong&gt;ForEach &lt;/strong&gt;TextCommand stores the itemName and itemType variables for you automatically before calling the &lt;strong&gt;ReadField &lt;/strong&gt;and &lt;strong&gt;WriteField &lt;/strong&gt;templates).&lt;/p&gt;
&lt;p&gt;The new &lt;strong&gt;TypeImplements &lt;/strong&gt;context added to solve this code generation challenge will ship with the next version of CodeRush.&lt;/p&gt;&lt;img src="http://community.devexpress.com/aggbug.aspx?PostID=235411" width="1" height="1"&gt;</content><author><name>Mark Miller (Developer Express)</name><uri>http://community.devexpress.com/members/Mark-Miller-_2800_Developer-Express_2900_.aspx</uri></author><category term="CodeRush" scheme="http://community.devexpress.com/blogs/markmiller/archive/tags/CodeRush/default.aspx" /></entry><entry><title>Language Translation on Paste with the Clipboard History Plug-in</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-12.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-12.aspx</id><published>2008-09-10T21:51:00Z</published><updated>2008-09-10T21:51:00Z</updated><content type="html">&lt;p&gt;Welcome to Part 12 of the &lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;series&lt;/a&gt; showing how to build plug-ins for Visual Studio using &lt;a href="http://www.devexpress.com/dxcore"&gt;DXCore&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So far we&amp;#39;ve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;Built the plug-in framework.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-2.aspx"&gt;Created the ClipboardHistory class.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-3.aspx"&gt;Created a simple UI.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-4.aspx"&gt;Added a cursor and support for the keyboard.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-5.aspx"&gt;Added form positioning code and dynamic update ability.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-6.aspx"&gt;Added a custom menu item and mouse support.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-7.aspx"&gt;Added clipboard history persistence across sessions.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-8.aspx" class="null"&gt;Added an options page.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-9.aspx"&gt;Added ability to restore default settings.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-10.aspx"&gt;Added the &amp;quot;Maximize Active CodeView&amp;quot; feature.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-11.aspx"&gt;Improved discoverability and added a context menu.&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Today, in our final post of the 12-part series, we&amp;#39;ll add a neat feature that shows how to paste code copied from one language into another.&lt;/p&gt;
&lt;h3&gt;&lt;span style="color:#5081c0;"&gt;Paste As Language Conversions&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;I know a number of developers who work in more than one language. And sometimes when researching a question online I&amp;#39;ll find example code in the wrong language. While the DXCore was never specifically built to convert from one language to another, it has a pretty decent (but not always 100% perfect) ability to do so. And so I&amp;#39;m thinking it might be nice to offer the ability to convert code copied from one language into another just before pasting.&lt;/p&gt;
&lt;p&gt;I also like this feature because it shows how to convert source code from one language to another using the DXCore.&lt;/p&gt;
&lt;p&gt;So let&amp;#39;s add a &amp;quot;&lt;strong&gt;Paste as...&lt;/strong&gt;&amp;quot; menu item which can convert code in the clipboard history into the active language. This menu item would be available when the active language is different from the language of the entry.&lt;/p&gt;
&lt;p&gt;Right-click the horizontal bar in our ContextMenuStrip and choose &lt;strong&gt;Insert &lt;/strong&gt;| &lt;strong&gt;MenuItem&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="458" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/InsertMenuItem_b765efdc-80eb-4d4f-a34f-e7328799523b.png" alt="InsertMenuItem" height="294" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Set these properties:&lt;/p&gt;
&lt;p&gt;
&lt;table cellpadding="2" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;span style="color:#5081c0;"&gt;Property&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;span style="color:#5081c0;"&gt;Value&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(Name)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;itmPasteAs&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Paste as&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="409" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/PasteAsMenuItem_61b9ce78-25d1-4a14-a3a4-42091781ef9f.png" alt="PasteAsMenuItem" height="222" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Create an &lt;strong&gt;event handler &lt;/strong&gt;for this menu item&amp;#39;s &lt;strong&gt;Click &lt;/strong&gt;event....&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="342" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/itmPasteAsClickEventHandler_f0a692c8-9518-46bb-bc2e-79d575f15fee.png" alt="itmPasteAsClickEventHandler" height="211" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;In the handler, add a call to &lt;strong&gt;PasteAsTargetLanguage &lt;/strong&gt;(we&amp;#39;ll implement this soon):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; itmPasteAs_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; PasteAsTargetLanguage();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Next, let&amp;#39;s ensure this menu item is only available under the right conditions, e.g., when the selected clipboard entry contains source code in a language that is different from the language of the active source file.&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;FrmClipHistory.cs [Design]&lt;/strong&gt; file, click the &lt;strong&gt;contextMenuStrip1 &lt;/strong&gt;control.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="567" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/SelectContextMenu2_698a049a-4831-42f4-9cb1-55484fd6e43e.png" alt="SelectContextMenu2" height="98" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;Properties &lt;/strong&gt;grid, click the &lt;strong&gt;Events &lt;/strong&gt;tab.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="389" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/contextMenuStripClickEvents_15f28587-2958-424a-bbd1-8bbabc7694c5.png" alt="contextMenuStripClickEvents" height="187" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Create a handler for the &lt;strong&gt;Opening &lt;/strong&gt;event. This event fires just before the context menu appears.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="389" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/contextMenuStripOpeningEventHandler_9866bdf8-0a51-4999-8b26-94d79d917b88.png" alt="contextMenuStripOpeningEventHandler" height="187" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Inside the &lt;strong&gt;Opening &lt;/strong&gt;handler, add the following code:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; contextMenuStrip1_Opening(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;CancelEventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; itmPasteAs.Visible = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;LanguageExtensionBase&lt;/span&gt; sourceLanguage;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;LanguageExtensionBase&lt;/span&gt; targetLanguage;&lt;br /&gt;&amp;nbsp; GetLanguagesForConversion(&lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; sourceLanguage, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; targetLanguage);&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (sourceLanguage == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; || targetLanguage == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; itmPasteAs.Visible = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; itmPasteAs.Text = &lt;span style="color:#a31515;"&gt;&amp;quot;Paste as &amp;quot;&lt;/span&gt; + targetLanguage.LanguageID;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This code will make the itmPasteAs menu item visible only if the language from which the source code in the current entry was copied.... LEFT OFF HERE&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GetLanguagesForConversion&lt;/strong&gt; determines the source and target languages necessary for conversion, and looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; GetLanguagesForConversion(&lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;LanguageExtensionBase&lt;/span&gt; sourceLanguage, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;LanguageExtensionBase&lt;/span&gt; targetLanguage)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; sourceLanguage = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; targetLanguage = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;ClipboardHistoryEntry&lt;/span&gt; entry = &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.GetEntry(CursorIndex);&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (entry == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; || &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.IsNullOrEmpty(entry.Language) || entry.Language == &lt;span style="color:#2b91af;"&gt;CodeRush&lt;/span&gt;.Language.Active)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; sourceLanguage = &lt;span style="color:#2b91af;"&gt;CodeRush&lt;/span&gt;.Language.GetLanguageExtension(entry.Language);&lt;br /&gt;&amp;nbsp; targetLanguage = &lt;span style="color:#2b91af;"&gt;CodeRush&lt;/span&gt;.Language.ActiveExtension;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#71289b;"&gt;// Only return languages that supports types....&lt;br /&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (sourceLanguage != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !sourceLanguage.SupportsTypes)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sourceLanguage = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (targetLanguage != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !targetLanguage.SupportsTypes)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; targetLanguage = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice the check in the code above to make sure both languages return true in their &lt;strong&gt;SupportsTypes&lt;/strong&gt; properties. This check is performed because there are languages supported by the DXCore that do not support types, such as HTML, and converting from HTML to Visual Basic, for example, would probably not yield useful results. So this simple check should ensure that both the language of the clipboard entry and the language of the active file we&amp;#39;re about to paste into, both have a good chance of producing a relatively useful conversion.&lt;/p&gt;
&lt;p&gt;Finally, our &lt;strong&gt;PasteAsTargetLanguage &lt;/strong&gt;method looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PasteAsTargetLanguage()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;LanguageExtensionBase&lt;/span&gt; sourceLanguage;&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &lt;/span&gt;LanguageExtensionBase&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt; targetLanguage;&lt;br /&gt;&amp;nbsp; GetLanguagesForConversion(&lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; sourceLanguage, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; targetLanguage);&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (sourceLanguage != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; targetLanguage != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;ParserBase&lt;/span&gt; parser = &lt;span style="color:#2b91af;"&gt;CodeRush&lt;/span&gt;.Language.GetParserFromLanguageID(sourceLanguage.LanguageID);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (parser != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;LanguageElement&lt;/span&gt; rootNode = parser.ParseString(&lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.GetText(CR_ClipboardHistory.&lt;span style="color:#2b91af;"&gt;FrmClipHistory&lt;/span&gt;.CursorIndex));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (rootNode != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CloseAndPaste(&lt;span style="color:#2b91af;"&gt;CodeRush&lt;/span&gt;.Language.GenerateElement(rootNode, targetLanguage));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; CloseAndPaste();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This method gets the source languages necessary for conversion, and then gets a parser for the source language, calling &lt;strong&gt;ParseString &lt;/strong&gt;to turn that code into a parse tree. Then it takes that parse tree and feeds it to &lt;strong&gt;GenerateElement &lt;/strong&gt;to get the source code equivalent in the target language. With the conversion complete all that&amp;#39;s needed is to pass those results on to &lt;strong&gt;CloseAndPaste&lt;/strong&gt;. And speaking of CloseAndPaste, I needed to refactor that method so it could optionally accept the text to paste (instead of taking it directly from the ClipboardHistory). The refactored CloseAndPaste and its corresponding overload (to prevent existing code from breaking) look like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; CloseAndPaste()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; thisText = &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.GetText(CursorIndex);&lt;br /&gt;&amp;nbsp; CloseAndPaste(thisText);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; CloseAndPaste(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; textToPaste)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Application&lt;/span&gt;.RemoveMessageFilter(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;);&lt;br /&gt;&amp;nbsp; PasteOnClose = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (textToPaste != &lt;span style="color:#2b91af;"&gt;Clipboard&lt;/span&gt;.GetText() &amp;amp;&amp;amp; !&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.IsNullOrEmpty(textToPaste)) &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#71289b;"&gt;// Need to put text on clipboard.&lt;br /&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Clipboard&lt;/span&gt;.SetText(textToPaste);&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#71289b;"&gt;// Simply calling close here will fail when a mouse double-clicks on a CodeView.&lt;br /&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NativeMethods&lt;/span&gt;.PostMessage(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Handle, &lt;span style="color:#2b91af;"&gt;WindowMessage&lt;/span&gt;.WM_CLOSE, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;.Zero, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;.Zero);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Adding this optional parameter makes it possible for us to condition the text before pasting (such as what we&amp;#39;re doing here in converting code from one language to another).&lt;/p&gt;
&lt;p&gt;Finally, let&amp;#39;s add keyboard support for this so developers can paste translated source code without being forced to reach for the mouse. We&amp;#39;ve already assigned the &lt;strong&gt;Enter &lt;/strong&gt;key to our &lt;strong&gt;Paste &lt;/strong&gt;functionality, so it seems logical to make &lt;strong&gt;Alt+Enter &lt;/strong&gt;be our alternate &amp;quot;&lt;strong&gt;Paste as...&lt;/strong&gt;&amp;quot; shortcut. This requires a small addition to our &lt;strong&gt;ProcessCmdKey &lt;/strong&gt;method:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;protected&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt; override bool ProcessCmdKey(ref Message msg, Keys keyData)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;const int WM_KEYDOWN = 0x100;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;if (msg.Msg == WM_KEYDOWN)&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;switch (keyData)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;case Keys.Enter:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;CloseAndPaste();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;return true;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;case&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Keys&lt;/span&gt;.Enter | &lt;span style="color:#2b91af;"&gt;Keys&lt;/span&gt;.Alt:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PasteAsTargetLanguage();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;case Keys.Escape:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;Close();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;return true;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;switch (keyData &amp;amp; ~Keys.Control)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;{&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;case Keys.Left:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;MoveCursor(0, -1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;return true;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;case Keys.Right:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;MoveCursor(0, 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;return true;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;case Keys.Up:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;MoveCursor(-1, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;return true;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;case Keys.Down:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;MoveCursor(1, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;"&gt;return true;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#808080;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;&amp;nbsp; }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;font-family:courier new,courier;"&gt;&amp;nbsp; return base.ProcessCmdKey(ref msg, keyData);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that&amp;#39;s it for the code changes. One thing I&amp;#39;ve noticed, however, is when we bring up the context menu on the Clipboard History, there are no shortcuts shown in the menu. For example, &lt;strong&gt;Enter &lt;/strong&gt;is already our Paste command trigger, however you see no mention of that when the menu is up:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="227" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/NoShortcuts_ca54d624-5208-4665-a9ad-28ce19fb3984.png" alt="NoShortcuts" height="91" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;So let&amp;#39;s fix this. I noticed that the &lt;strong&gt;ShortcutKeys &lt;/strong&gt;property of the &lt;strong&gt;ToolStripMenuItem &lt;/strong&gt;control seems to be missing an option to compose a shortcut with the &lt;strong&gt;Enter &lt;/strong&gt;key. Fortunately this control also has a string property &lt;strong&gt;ShortcutKeyDisplayString&lt;/strong&gt;, which will work. &lt;/p&gt;
&lt;p&gt;Set the &lt;strong&gt;ShortcutKeyDisplayString &lt;/strong&gt;properties of the two &lt;strong&gt;Paste &lt;/strong&gt;and &lt;strong&gt;Paste as&lt;/strong&gt; menu items to &amp;quot;&lt;strong&gt;Enter&lt;/strong&gt;&amp;quot; and &amp;quot;&lt;strong&gt;Alt+Enter&lt;/strong&gt;&amp;quot;, respectively.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img border="0" width="330" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/LanguageTranslationonPastewiththeClipboa_9000/ShortcutKeyDisplayStringAltEnter_67311676-6e83-4175-b809-093d59ed01b4.png" alt="ShortcutKeyDisplayStringAltEnter" height="153" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;The form should now look like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img border="0" width="236" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/LanguageTranslationonPastewiththeClipboa_9000/ShortcutKeysOnContextMenuAltEnter_fe6c2eb4-35f5-43e6-940c-4b50e71088f8.png" alt="ShortcutKeysOnContextMenuAltEnter" height="179" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Now it&amp;#39;s time to test. Click &lt;strong&gt;Run&lt;/strong&gt;. Open a file in one language (e.g.,&lt;strong&gt; C#&lt;/strong&gt;), and copy some code to the clipboard. For example, I&amp;#39;ve selected this method with a C# initializer in it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Form&lt;/span&gt; CreateNewWindow()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; window = new &lt;span style="color:#2b91af;"&gt;Form&lt;/span&gt; { Name = &lt;span style="color:#d70000;"&gt;&amp;quot;New window&amp;quot;&lt;/span&gt;, Width = 640, Height = 480 };&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; window;&lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Open a file in a different language (e.g., &lt;strong&gt;VB&lt;/strong&gt;), press &lt;strong&gt;Ctrl+Shift+Insert &lt;/strong&gt;to bring up the &lt;strong&gt;Clipboard History&lt;/strong&gt;, right click the entry to paste, and select &amp;quot;&lt;strong&gt;Paste as Basic&lt;/strong&gt;&amp;quot; (or whatever language you&amp;#39;ve selected.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img border="0" width="939" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/LanguageTranslationonPastewiththeClipboa_9000/PasteAsBasic3_0cf1d946-829d-4a2f-b4c1-b28a0a7f7a89.png" alt="PasteAsBasic3" height="355" style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the code I get when pasting in Visual Basic:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;Private Shared Function&lt;/span&gt; CreateNewWindow() &lt;span style="color:#0000ff;"&gt;As&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Form&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;Dim&lt;/span&gt; window = &lt;span style="color:#0000ff;"&gt;New&lt;/span&gt; Form() &lt;span style="color:#0000ff;"&gt;With&lt;/span&gt; {.Name = &lt;span style="color:#d70000;"&gt;&amp;quot;New window&amp;quot;&lt;/span&gt;, .Width = 640, .Height = 480}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;Return&lt;/span&gt; window&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;End Function&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Excellent! As I alluded to at the beginning of this post, language conversion has never been the number one priority with the DXCore. It&amp;#39;s really more a side-effect of the architecture that you get for free, so you may find examples where the results require some editing (especially in areas where features exist in the source language but not the target language). So it&amp;#39;s not always perfect, but it&amp;#39;s still pretty cool.&lt;/p&gt;
&lt;h2&gt;&lt;span style="color:#5081c0;"&gt;Wrap Up&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;For now I think this Clipboard History feature is done. We&amp;#39;ve come a long way since &lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;part one&lt;/a&gt;&amp;nbsp;of&amp;nbsp;this series, where we had an idea for a simple plug-in to provide quick access to a history of clipboard operations. Now we have syntax highlighting, ease of use, discoverability, persistence, customization (with preview) and language conversion, all in a professional package with concise code that should be easy to maintain. And this series should have given you a sense of what it takes to produce a high quality feature that many developers will enjoy.&lt;/p&gt;
&lt;p&gt;Speaking of which, CodeRush customers will get this feature (and full source code) wrapped up into the next release (3.2). For eveyone else, you&amp;#39;ll need to download the &lt;a href="http://www.devexpress.com/DXCore"&gt;DXCore&lt;/a&gt; and follow the steps of this series (or you could purchase a license &lt;a href="http://www.devexpress.com/CodeRush"&gt;CodeRush&lt;/a&gt; -- it rocks on multiple levels)....&lt;/p&gt;
&lt;p&gt;So what&amp;#39;s next? Well, the next step is up to you. What cool feature will &lt;em&gt;you &lt;/em&gt;build and share with your peers? Let us know what you&amp;#39;re working on and what we can do to make writing plug-ins even easier and more enjoyable. Also, let us know what parts of the DXCore we should cover in more depth with tutorials like this.&lt;/p&gt;&lt;img src="http://community.devexpress.com/aggbug.aspx?PostID=234311" width="1" height="1"&gt;</content><author><name>Mark Miller (Developer Express)</name><uri>http://community.devexpress.com/members/Mark-Miller-_2800_Developer-Express_2900_.aspx</uri></author></entry><entry><title>Improving Discoverability with our Clipboard History DXCore Plug-in for Visual Studio</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-11.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-11.aspx</id><published>2008-09-10T21:10:00Z</published><updated>2008-09-10T21:10:00Z</updated><content type="html">&lt;p&gt;Welcome to Part&amp;nbsp;11 of the &lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;series&lt;/a&gt; showing how to build plug-ins for Visual Studio using &lt;a href="http://www.devexpress.com/dxcore"&gt;DXCore&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So far we&amp;#39;ve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;Built the plug-in framework.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-2.aspx"&gt;Created the ClipboardHistory class.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-3.aspx"&gt;Created a simple UI.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-4.aspx"&gt;Added a cursor and support for the keyboard.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-5.aspx"&gt;Added form positioning code and&amp;nbsp;dynamic update ability.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-6.aspx"&gt;Added a custom menu item and mouse support.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-7.aspx"&gt;Added clipboard history persistence across sessions.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-8.aspx" class="null"&gt;Added an options page.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-9.aspx"&gt;Added ability to restore default settings.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-10.aspx"&gt;Added the &amp;quot;Maximize Active CodeView&amp;quot; feature.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In today&amp;#39;s post, we&amp;#39;ll improve shortcut discoverability and add a context menu to our Clipboard History. We&amp;#39;ll also learn how to programmatically invoke the options page we created earlier, and see yet another way to work with DecoupledStorage.&lt;/p&gt;
&lt;h2&gt;&lt;span style="color:#5081c0;"&gt;Improving Shortcut Key Discoverability&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;So far the shortcut and visual interaction feel good, but discoverability for the shortcut keys could be better. To make shortcuts easier to discover, I&amp;#39;m thinking about placing a status bar below the views, revealing available keys.&lt;/p&gt;
&lt;p&gt;So let&amp;#39;s try that. From the Toolbox, &lt;strong&gt;select&lt;/strong&gt; the &lt;strong&gt;StatusStrip &lt;/strong&gt;control.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="178" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/SelectStatusStrip_7cb6aeaa-5f98-4473-82d6-5f90faad0e40.png" alt="SelectStatusStrip" height="125" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Drop&lt;/strong&gt; the &lt;strong&gt;StatusStrip&lt;/strong&gt; onto our &lt;strong&gt;FrmClipHistory&lt;/strong&gt; form...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img border="0" width="640" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/DropStatusStrip_70b939cb-d79f-44e0-834d-066084448263.png" alt="DropStatusStrip" height="75" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Click the &lt;strong&gt;Add &lt;/strong&gt;drop down button.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="640" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/ClickAddLabel_f0d48038-c983-4e04-84ba-b786542d690a.png" alt="ClickAddLabel" height="75" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Select the &lt;strong&gt;StatusLabel&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="631" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/AddStatusLabel_b91b42b2-6207-4334-b217-b478ac014f31.png" alt="AddStatusLabel" height="138" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Set the following properties for the new StatusLabel:&lt;/p&gt;
&lt;p&gt;
&lt;table cellpadding="2" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;span style="color:#5081c0;"&gt;Property&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;span style="color:#5081c0;"&gt;Value&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(Name)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;lblStatusText&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enabled&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Arrow keys to select, Enter to paste, Escape to cancel. Hold down Ctrl to maximize code view.&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;Next, let&amp;#39;s update that AllViewsRect property to take this new status bar into consideration:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt; AllViewsRect&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;get&lt;br /&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_FrmClipHistory == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt;.Empty;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt; rect = _FrmClipHistory.ClientRectangle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_FrmClipHistory.statusStrip1.Visible)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rect.Height -= _FrmClipHistory.statusStrip1.Height;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; rect;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;That should be all we need. &lt;strong&gt;Run&lt;/strong&gt; and &lt;strong&gt;test&lt;/strong&gt; to make sure that it&amp;#39;s working as expected.&lt;/p&gt;
&lt;p&gt;Now that we have a status bar, it might be nice to allow developers familiar with the shortcuts to &lt;strong&gt;hide the status bar&lt;/strong&gt; to regain some screen real estate for clipboard entries. It would also be nice to provide a fast and easy way to get directly to our new options page from the Clipboard History UI. Both of these problems can be solved with a right-click context menu....&lt;/p&gt;
&lt;h2&gt;&lt;span style="color:#5081c0;"&gt;Adding a Context Menu&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;#39;s add a context menu with items to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paste the selected entry &lt;/li&gt;
&lt;li&gt;Make it easy to discover and access our options page &lt;/li&gt;
&lt;li&gt;Toggle the visibility of the status bar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;#39;re still running a debugger session, close it now.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Activate FrmClipHistory.cs [Design]&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="280" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/ActivateFrmClipHistoryDesign_d775968b-10ac-4fff-8dd4-8a89d210f995.png" alt="ActivateFrmClipHistoryDesign" height="113" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;From the &lt;strong&gt;Toolbox&lt;/strong&gt;, select a &lt;strong&gt;ContextMenuStrip &lt;/strong&gt;control...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="169" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/SelectContextMenu_0427e0ed-0dd9-4176-bc0d-c0d84f9cdb4b.png" alt="SelectContextMenu" height="283" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Drop the ContextMenuStrip onto the form...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="573" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/DropContextMenuStrip_d7db6a98-f500-44b0-93d5-e05573974773.png" alt="DropContextMenuStrip" height="104" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Using the in-place editor...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="295" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/AddNewOptionsMenuItem_313c7f7a-64fd-4b0c-b139-00996216a3b1.png" alt="AddNewOptionsMenuItem" height="157" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Add four new menu items:&amp;nbsp; &amp;quot;&lt;strong&gt;Paste&lt;/strong&gt;&amp;quot;, &amp;quot;&lt;strong&gt;-&lt;/strong&gt;&amp;quot;, &amp;quot;&lt;strong&gt;Toggle status bar visibility&lt;/strong&gt;&amp;quot;, and &amp;quot;&lt;strong&gt;Options...&lt;/strong&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="247" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/AddMenuItems_889d5efb-c45b-44c7-880e-1cbf0f9ba606.png" alt="AddMenuItems" height="168" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Let&amp;#39;s create event handlers for each menu item. First, double-click on the &lt;strong&gt;Paste &lt;/strong&gt;menu item, and inside that event handler add a call to &lt;strong&gt;CloseAndPaste&lt;/strong&gt;, like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; pasteToolStripMenuItem_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; CloseAndPaste();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Activate the &lt;strong&gt;FrmClipHistory.cs [Design] &lt;/strong&gt;form again, and then &lt;strong&gt;double-click &lt;/strong&gt;the &amp;quot;&lt;strong&gt;Toggle status bar visibility&lt;/strong&gt;&amp;quot; menu item. Add the following code to that event handler:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; toggleStatusBarVisibilityToolStripMenuItem_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; statusStrip1.Visible = !statusStrip1.Visible;&lt;br /&gt;&amp;nbsp; PositionViews();&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;DecoupledStorage&lt;/span&gt; storage = &lt;span style="color:#2b91af;"&gt;OptClipboardHistory&lt;/span&gt;.Storage)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; storage.WriteBoolean(&lt;span style="color:#a31515;"&gt;&amp;quot;Settings&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;ShowStatusBar&amp;quot;&lt;/span&gt;, statusStrip1.Visible);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think it&amp;#39;s important to save this preference out whenever it changes. That way developers will only have to hide it once. &lt;/p&gt;
&lt;p&gt;
&lt;table bgcolor="#739acb" cellpadding="2" cellspacing="2"&gt;

&lt;tr&gt;
&lt;td align="center"&gt;&lt;span style="font-size:medium;color:#ffffff;"&gt;Using DecoupledStorage&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td bgcolor="#ffffff"&gt;
&lt;p&gt;One of the cool things about this plug-in is that it uses DecoupledStorage in three different but interesting ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To save and load the clipboard history. &lt;/li&gt;
&lt;li&gt;To save and load options page settings. &lt;/li&gt;
&lt;li&gt;To save configuration settings that are &lt;strong&gt;not &lt;/strong&gt;on any options page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This last bullet point is what we&amp;#39;re doing now. While we could place a new check box on our options page, having an option to show or hide the status bar is pretty trivial, and may introduce some confusion. Instead, we can provide contextual access to the setting through the right-click menu. This also has the benefit of giving developers immediate feedback on the setting (to get the same effect with a check box on an options page we would have to modify the preview to draw a status bar -- again, more work than seems justified).&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;Next, let&amp;#39;s make sure the status bar is hidden if needed on startup. First, add a call to &lt;strong&gt;LoadSettings &lt;/strong&gt;from inside &lt;strong&gt;ShowClipboardHistory&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt; static void ShowClipboardHistory()&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp; if (_FrmClipHistory != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;return;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;_FrmClipHistory = new FrmClipHistory();&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;PasteOnClose = false;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;try&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application.AddMessageFilter(_FrmClipHistory);&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LoadSettings();&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;CreateViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;PositionViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;UpdateViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;ShowCursor();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;PositionForm();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;_FrmClipHistory.ShowDialog(CodeRush.IDE);&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;}&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;finally&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;CleanUpViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Application.RemoveMessageFilter(_FrmClipHistory);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;if (_FrmClipHistory != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;_FrmClipHistory.Dispose();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;_FrmClipHistory = null;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;}&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;if (PasteOnClose)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Paste();&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is important to call LoadSettings &lt;em&gt;before&lt;/em&gt; calling PositionViews, since CodeView position depends upon that AllViewsRect property, which changes based on status bar visibility.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LoadSettings &lt;/strong&gt;looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; LoadSettings()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;DecoupledStorage&lt;/span&gt; storage = &lt;span style="color:#2b91af;"&gt;OptClipboardHistory&lt;/span&gt;.Storage)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _FrmClipHistory.statusStrip1.Visible = storage.ReadBoolean(&lt;span style="color:#a31515;"&gt;&amp;quot;Settings&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;ShowStatusBar&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Activate the &lt;strong&gt;FrmClipHistory.cs [Design] &lt;/strong&gt;form again, and then &lt;strong&gt;double-click &lt;/strong&gt;the &amp;quot;&lt;strong&gt;Options...&lt;/strong&gt;&amp;quot; menu item. Add the following code to that event handler:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; optionsToolStripMenuItem_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;OptClipboardHistory&lt;/span&gt;.Show();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now I think this is really cool. Take a look at that code in the event handler. It&amp;#39;s calling a static method inside our options page. That method was built courtesy of the wizard, and it brings up the DevExpress options dialog and displays this page. &lt;/p&gt;
&lt;p&gt;One last important step: We need to assign our new context menu to the form&amp;#39;s ContextMenuStrip property, like this:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="296" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/AssignContextMenuStripProperty_bfab4143-47a2-493d-8f69-cc7fb543b942.png" alt="AssignContextMenuStripProperty" height="230" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="296" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/ContextMenuStripAssigned_8aad8182-6a8b-4daf-8080-c5a4cf7ff960.png" alt="ContextMenuStripAssigned" height="62" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Nice. Let&amp;#39;s give this a try.&lt;/p&gt;
&lt;h3&gt;&lt;span style="color:#5081c0;"&gt;Testing the Context Menu&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Click &lt;strong&gt;Run&lt;/strong&gt;. In the second instance of Visual Studio, press &lt;strong&gt;Ctrl+Shift+Insert &lt;/strong&gt;to bring up the &lt;strong&gt;Clipboard History &lt;/strong&gt;form. &lt;strong&gt;Right-click &lt;/strong&gt;the form to bring up the context menu. Try the &lt;strong&gt;Paste &lt;/strong&gt;and &lt;strong&gt;Toggle status bar visibility&lt;/strong&gt; menu items to verify expected behavior. Try hiding the status bar, closing the form, and then bringing it up again to verify that the status bar visibility setting is in fact preserved.&lt;/p&gt;
&lt;p&gt;Not bad. Although I am noticing that when I right-click, the CodeView under the mouse is not selected, and I think it should be.&lt;/p&gt;
&lt;p&gt;We can fix that while we&amp;#39;re running if edit and continue is enabled. Just set a breakpoint in the &lt;strong&gt;PreFilterMessage&lt;/strong&gt; method, and when it hits make this change (add the check for the right mouse button):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;bool IMessageFilter.PreFilterMessage(ref Message m)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; bool isDoubleClick;&lt;br /&gt;&amp;nbsp; if (m.Msg == (int)WindowMessage.WM_LBUTTONDOWN&lt;/span&gt; || m.Msg == (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;)&lt;span style="color:#2b91af;"&gt;WindowMessage&lt;/span&gt;.WM_RBUTTONDOWN&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; isDoubleClick = false;&lt;br /&gt;&amp;nbsp; else if (m.Msg == (int)WindowMessage.WM_LBUTTONDBLCLK)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; isDoubleClick = true;&lt;br /&gt;&amp;nbsp; else &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;// Not a message we&amp;#39;re interested in.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Control target = Control.FromHandle(m.HWnd);&lt;br /&gt;&amp;nbsp; if (target is WheelPanel) &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;// WheelPanel is the child of the CodeView that holds the text.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; target = target.Parent;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; if (target != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt;= ClipboardHistory.LastIndex; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_Borders[ i ] == target || _CodeViews[ i ] == target)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MoveCursorTo(i);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (isDoubleClick)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CloseAndPaste();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return false;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And then clear out the breakpoint and run again. Now you should be able to right-click any CodeView, and have it become &lt;strong&gt;selected &lt;/strong&gt;before the context menu pops up.&lt;/p&gt;
&lt;p&gt;Next, let&amp;#39;s test bringing up the options page. &lt;strong&gt;Right-click&lt;/strong&gt; the Clipboard History form, and choose &amp;quot;&lt;strong&gt;Options...&lt;/strong&gt;&amp;quot;. &lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="382" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/InvokeOptions_44393098-47ba-4c6f-bfb6-29d9448b419a.png" alt="InvokeOptions" height="343" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Remember this line of code?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp; &lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#2b91af;"&gt;OptClipboardHistory&lt;/span&gt;.Show();&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That static method is all it takes to bring up the options dialog and have our new options page displayed. &lt;/p&gt;
&lt;p&gt;With the Options dialog up, &lt;strong&gt;change only &lt;/strong&gt;the &lt;strong&gt;Selector Color&lt;/strong&gt; (don&amp;#39;t touch the dimensions just yet)...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="307" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/ChangeOnlyColor_f7d32a4d-2116-4348-88df-9cce3ffaa2af.png" alt="ChangeOnlyColor" height="218" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;and click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="338" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/ClickOKOptionsDialog_47f86032-da53-4e70-ad50-a1eee3009e85.png" alt="ClickOKOptionsDialog" height="44" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;And yet the cursor color &lt;strong&gt;does not appear &lt;/strong&gt;to have changed:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="382" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/CursorColorNotChanged_4901699c-8f5f-449f-a6fe-267fd63aa9c7.png" alt="CursorColorNotChanged" height="343" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt;&lt;/p&gt;
&lt;p&gt;Press one of the &lt;strong&gt;arrow keys &lt;/strong&gt;to move the cursor, and you&amp;#39;ll see the cursor color correctly drawn.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="382" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/CursorColorChanged_af23a7f9-1bb2-4055-95aa-6c6f6337ad32.png" alt="CursorColorChanged" height="343" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;OK, so it seems we need to call &lt;strong&gt;ShowCursor &lt;/strong&gt;on the form after returning from the options page. I&amp;#39;m a big fan of efficient code, so let&amp;#39;s only call ShowCursor &lt;em&gt;if the color changes&lt;/em&gt;, by adding the following code to our &lt;strong&gt;Options... &lt;/strong&gt;menu item event handler:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;private void optionsToolStripMenuItem_Click(object sender, EventArgs e)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;{&lt;br /&gt;&lt;/span&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Color&lt;/span&gt; previousColor = SelectedBorderColor;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;OptClipboardHistory.Show();&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (previousColor != SelectedBorderColor)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowCursor();&lt;br /&gt;&lt;span style="color:#808080;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can add this code by setting a breakpoint at the opening brace of the handler (bringing up the options page again through the context menu) and using Edit and Continue, or you can shut down the debugging session, make the change, and then start a new debugging session (Edit and Continue is much faster).&lt;/p&gt;
&lt;p&gt;With the change made, let&amp;#39;s repeat the test again. &lt;strong&gt;Right-click &lt;/strong&gt;the &lt;strong&gt;Clipboard History&lt;/strong&gt;, select &amp;quot;&lt;strong&gt;Options...&lt;/strong&gt;&amp;quot;, and then change only the &lt;strong&gt;Selector Color &lt;/strong&gt;(we&amp;#39;ll test dimension changes in a bit), and then click &lt;strong&gt;OK&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="382" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/CursorColorChangedImmediately_88ad34ad-a42e-49ec-8fdd-f1d55bb50ff3.png" alt="CursorColorChangedImmediately" height="343" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;This time the cursor color is updated immediately when the options page closes.&lt;/p&gt;
&lt;p&gt;Excellent.&lt;/p&gt;
&lt;p&gt;Now, let&amp;#39;s try changing the dimensions. Specifically, try &lt;em&gt;increasing &lt;/em&gt;one or both of the dimensions. I&amp;#39;ve been holding off testing a dimension change because I&amp;#39;m pretty sure we&amp;#39;re going to see some issues. Much of the code in FrmClipHistory depends upon a certain synchronization between the values in ClipboardHistory (e.g., RowCount, ColumnCount), and the CodeViews and border Panels on the form.&lt;/p&gt;
&lt;p&gt;So, after right-clicking the context menu and bringing up the Options dialog one more time, &lt;strong&gt;increasing the dimensions &lt;/strong&gt;and clicking OK, we might see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="382" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/NotGood_c790cb41-af43-4e77-8d8d-924e7b47a9a7.png" alt="NotGood" height="343" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Not only is there no indication that our change in dimensions has taken place, but there also appears to be &lt;strong&gt;two cursors&lt;/strong&gt;! Interacting further with the Clipboard History and you might find yourself suddenly staring at a dialog back in the &lt;em&gt;first instance &lt;/em&gt;of Visual Studio, looking something like this:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="527" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/OutOfRange_7e6a8c00-3e88-402f-b935-c9cb8e54badd.png" alt="OutOfRange" height="235" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;And if you click &lt;strong&gt;Continue&lt;/strong&gt;, you might eventually see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="366" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/VisualStudioIsClosing_6b9079c6-42d5-411c-93ae-2c24c9a54984.png" alt="VisualStudioIsClosing" height="199" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;So &lt;em&gt;&lt;strong&gt;clearly &lt;/strong&gt;&lt;/em&gt;we have at least one issue that requires attention. &lt;/p&gt;
&lt;p&gt;One solution might be to &lt;strong&gt;close &lt;/strong&gt;the Clipboard History and &lt;strong&gt;reopen &lt;/strong&gt;it again after returning from the call to &lt;strong&gt;OptClipboardHistory.Show&lt;/strong&gt;. However I think we can clean things up and rebuild the dialog while it&amp;#39;s still up, without closing the form.&lt;/p&gt;
&lt;p&gt;We should be able to fix this by adding the following code to our &lt;strong&gt;Options... &lt;/strong&gt;click event handler:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;private void optionsToolStripMenuItem_Click(object sender, EventArgs e)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;Color previousColor = SelectedBorderColor;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; previousRowCount = &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.RowCount;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; previousColumnCount = &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.ColumnCount;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#808080;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;OptClipboardHistory.Show();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (previousRowCount != &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.RowCount || previousColumnCount != &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.ColumnCount)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; previousCount = previousRowCount * previousColumnCount;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color:#008000;"&gt;0&lt;/span&gt;; i &amp;lt; previousCount; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Controls.Remove(_Borders[ i ]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _CodeViews[ i ] = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _Borders[ i ] = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CreateViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PositionViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UpdateViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowCursor();&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;if (previousColor != SelectedBorderColor)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;ShowCursor();&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I put the &lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:courier new,courier;"&gt;else&lt;/span&gt; &lt;/span&gt;in front of the last &lt;span style="color:#0000ff;font-family:courier new,courier;"&gt;if&lt;/span&gt;-statement (that checks for color change) for efficiency, as there is already a &lt;strong&gt;ShowCursor &lt;/strong&gt;call in the previous block (there&amp;#39;s no need to call this twice if the dimensions change).&lt;/p&gt;
&lt;p&gt;Now, let&amp;#39;s try to test this again.&lt;/p&gt;
&lt;p&gt;Click &lt;strong&gt;Run&lt;/strong&gt;. Press &lt;strong&gt;Ctrl+Shift+Insert &lt;/strong&gt;to bring up the &lt;strong&gt;Clipboard History&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Right-click &lt;/strong&gt;the Clipboard History and choose &amp;quot;&lt;strong&gt;Options...&lt;/strong&gt;&amp;quot;. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Change &lt;/strong&gt;the &lt;strong&gt;dimensions &lt;/strong&gt;of the clipboard history and click &lt;strong&gt;OK&lt;/strong&gt;. Try changing dimensions again. Be sure to test changes where you increase the dimensions.&lt;/p&gt;
&lt;p&gt;This time changes to row or column count appear to be reflected immediately in the Clipboard History upon closing the options dialog.&lt;/p&gt;
&lt;p&gt;Not bad, but in testing you&amp;#39;ve probably noticed that this new code appears to have introduced a &lt;em&gt;very strange bug&lt;/em&gt;. After clicking &lt;strong&gt;OK &lt;/strong&gt;on the options dialog and returning to the Clipboard History, the &lt;strong&gt;arrow keys no longer move the cursor&lt;/strong&gt;! If I switch focus to another application and then return to this instance of Visual Studio, the arrow keys work normally again as expected.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#800000;"&gt;&lt;strong&gt;What&amp;#39;s going on?&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If I set a breakpoint inside the &lt;strong&gt;ProcessCmdKey &lt;/strong&gt;method, and then repeat the steps to reproduce the bug (switching to the first instance of Visual Studio to set the breakpoint fixes the problem when I switch back -- so that&amp;#39;s why I need to repeat the steps), I find that the &lt;strong&gt;ProcessCmdKey &lt;/strong&gt;breakpoint is NEVER HIT when the problem is reproduced.&lt;/p&gt;
&lt;p&gt;This is a very strange problem indeed. &lt;/p&gt;
&lt;p&gt;After playing with this more, I theorized that the form is somehow no longer considering itself active. It doesn&amp;#39;t make sense to me why this would happen, however the behavior certainly seems to indicate that. &lt;/p&gt;
&lt;p&gt;My first stab at fixing this was to place a call to &lt;strong&gt;Activate &lt;/strong&gt;at the end of the block that rebuilds and repositions the CodeViews (right after the first ShowCursor call). &lt;/p&gt;
&lt;p&gt;Unfortunately this call to &lt;strong&gt;Activate &lt;/strong&gt;had no effect on the problem. Changing the dimensions through the right-click context menu still resulted in completely disabled keyboard functionality. &lt;/p&gt;
&lt;p&gt;Then I tried adding a call to &lt;strong&gt;Focus &lt;/strong&gt;instead, and remarkably, THAT WORKED.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the final version of the event handler, with that added call to &lt;strong&gt;Focus &lt;/strong&gt;that restores keyboard functionality:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;private void optionsToolStripMenuItem_Click(object sender, EventArgs e)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Color previousColor = SelectedBorderColor;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp; int previousRowCount = ClipboardHistory.RowCount;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;int previousColumnCount = ClipboardHistory.ColumnCount;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;OptClipboardHistory.Show();&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;if (previousRowCount != ClipboardHistory.RowCount || previousColumnCount != ClipboardHistory.ColumnCount)&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;int previousCount = previousRowCount * previousColumnCount;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;for (int i = 0; i &amp;lt; previousCount; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;Controls.Remove(_Borders[ i ]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;_CodeViews[ i ] = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;_Borders[ i ] = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;CreateViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;PositionViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;UpdateViews();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;ShowCursor();&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Focus();&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#808080;"&gt;else if (previousColor != SelectedBorderColor)&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&lt;span style="font-family:courier new,courier;"&gt;ShowCursor();&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I suspect a few minutes spent with Reflector may reveal what&amp;#39;s happening here.&lt;/p&gt;
&lt;p&gt;Test this new code and see what you think.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-12.aspx"&gt;Tomorrow&lt;/a&gt;, we&amp;#39;ll add one of the last features on my list, the ability to paste in a &lt;em&gt;different&lt;/em&gt; language (e.g., copy from a VB file and paste into a C# file). See you then!&lt;/p&gt;&lt;img src="http://community.devexpress.com/aggbug.aspx?PostID=234304" width="1" height="1"&gt;</content><author><name>Mark Miller (Developer Express)</name><uri>http://community.devexpress.com/members/Mark-Miller-_2800_Developer-Express_2900_.aspx</uri></author></entry><entry><title>Maximizing the Active CodeView in our Clipboard History Plug-in for Visual Studio</title><link rel="alternate" type="text/html" href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-10.aspx" /><id>http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-10.aspx</id><published>2008-09-10T20:56:00Z</published><updated>2008-09-10T20:56:00Z</updated><content type="html">&lt;p&gt;Welcome to Part&amp;nbsp;10 of the &lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;series&lt;/a&gt; showing how to build plug-ins for Visual Studio using &lt;a href="http://www.devexpress.com/dxcore"&gt;DXCore&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So far we&amp;#39;ve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-1.aspx"&gt;Built the plug-in framework.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-2.aspx"&gt;Created the ClipboardHistory class.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/08/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-3.aspx"&gt;Created a simple UI.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-4.aspx"&gt;Added a cursor and support for the keyboard.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-5.aspx"&gt;Added form positioning code and&amp;nbsp;dynamic update ability.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-6.aspx"&gt;Added a custom menu item and mouse support.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-7.aspx"&gt;Added clipboard history persistence across sessions.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-8.aspx" class="null"&gt;Added an options page.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/markmiller/archive/2008/09/10/clipboard-history-plug-in-for-visual-studio-with-dxcore-part-9.aspx"&gt;Added ability to restore default settings.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In today&amp;#39;s post, we&amp;#39;ll add the ability to quickly &lt;em&gt;maximize&lt;/em&gt; and later&amp;nbsp;restore the active CodeView in the Clipboard History.&lt;/p&gt;
&lt;h2&gt;&lt;span style="color:#5081c0;"&gt;Maximizing the Active CodeView&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;I want to improve the Clipboard History UI a bit. While we have increased flexibility by allowing developers the ability to change the dimensions of the Clipboard History, having many rows and/or columns may lead to views that clip a portion of their content, forcing developers to scroll to see everything they contain.&lt;/p&gt;
&lt;p&gt;So what I would like to do is make it possible to &lt;strong&gt;maximize &lt;/strong&gt;the active CodeView temporarily, by holding down the &lt;strong&gt;Ctrl &lt;/strong&gt;key. This allows developers working in space-constrained environments the ability to quickly see the contents of a selected clipboard history entry, without having to reach for the mouse to scroll.&lt;/p&gt;
&lt;p&gt;Unfortunately I&amp;#39;m not aware of any elegant code which can notify me the moment the Ctrl key is pressed or released, so I&amp;#39;m going to hack this the old-fashioned way: by polling with a Timer (&lt;em&gt;shudder&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Activate FrmClipHistory.cs [Design]&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="280" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/ActivateFrmClipHistoryDesign_d775968b-10ac-4fff-8dd4-8a89d210f995.png" alt="ActivateFrmClipHistoryDesign" height="113" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;From the &lt;strong&gt;Toolbox&lt;/strong&gt;, select a &lt;strong&gt;System.Windows.Forms.Timer &lt;/strong&gt;control...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="173" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/SelectTimer_84bbcda8-a651-4edb-8c48-07a21e4651dd.png" alt="SelectTimer" height="154" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Drop &lt;/strong&gt;the &lt;strong&gt;Timer &lt;/strong&gt;onto the &lt;strong&gt;FrmClipHistory &lt;/strong&gt;design surface...&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="242" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/DropTimer_11a4ad69-b15c-42fc-abdb-612fbbc1ee81.png" alt="DropTimer" height="85" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Set the following properties:&lt;/p&gt;
&lt;p&gt;
&lt;table cellpadding="2" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;span style="color:#5081c0;"&gt;Property&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;span style="color:#5081c0;"&gt;Value&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(Name)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;tmrCheckControl&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enabled&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;True&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;Properties &lt;/strong&gt;grid, click the &lt;strong&gt;Events &lt;/strong&gt;button.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="295" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/tmrCheckControlClickEventsButton_601d6707-141e-4918-950d-fc1a5a5e98d7.png" alt="tmrCheckControlClickEventsButton" height="211" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Double-click &lt;/strong&gt;the &lt;strong&gt;Tick &lt;/strong&gt;event to add a new handler.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="295" src="http://community.devexpress.com/blogs/markmiller/WindowsLiveWriter/ClipboardHistoryPluginforVisualStudiousi_A822/HandleTickEvent_82e0dd19-2e33-4c41-af8e-7808ccde6a19.png" alt="HandleTickEvent" height="127" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" /&gt; &lt;/p&gt;
&lt;p&gt;Add the following code...&lt;/p&gt;
&lt;blockquote&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#000000;"&gt; _ActiveViewMaximized;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new,courier;"&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; tmrCheckControl_Tick(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Keys&lt;/span&gt; controlState = &lt;span style="color:#2b91af;"&gt;Control&lt;/span&gt;.ModifierKeys &amp;amp; &lt;span style="color:#2b91af;"&gt;Keys&lt;/span&gt;.Control;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!_ActiveViewMaximized &amp;amp;&amp;amp; controlState == &lt;span style="color:#2b91af;"&gt;Keys&lt;/span&gt;.Control ||&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ActiveViewMaximized &amp;amp;&amp;amp; controlState != &lt;span style="color:#2b91af;"&gt;Keys&lt;/span&gt;.Control)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ActiveViewMaximized = !_ActiveViewMaximized;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PositionViews();&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;And let&amp;#39;s now modify &lt;strong&gt;PositionViews&lt;/strong&gt; so it can distribute the CodeViews evenly or maximize the view under the cursor. Speaking of PositionViews, this method is getting a little meaty, and with this new code it&amp;#39;s going to get even meatier, so I think we should refactor it a bit. Here&amp;#39;s the &lt;em&gt;new&lt;/em&gt; &lt;strong&gt;PositionViews&lt;/strong&gt; method:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PositionViews()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_FrmClipHistory == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_ActiveViewMaximized)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MaximizeActiveView();&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DistributeViewsEvenly();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;DistributeViewsEvenly &lt;/strong&gt;contains essentially the code from the &lt;em&gt;old&lt;/em&gt; &lt;strong&gt;PositionViews&lt;/strong&gt; method:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DistributeViewsEvenly()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; width = AllViewsRect.Width / &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.ColumnCount;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; height = AllViewsRect.Height / &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.RowCount;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Size&lt;/span&gt; viewSize = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Size&lt;/span&gt;(width - CursorBorder * &lt;span style="color:#008000;"&gt;2&lt;/span&gt;, height - CursorBorder * &lt;span style="color:#008000;"&gt;2&lt;/span&gt;);&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Size&lt;/span&gt; borderSize = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Size&lt;/span&gt;(width, height);&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; row = &lt;span style="color:#008000;"&gt;0&lt;/span&gt;; row &amp;lt; &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.RowCount; row++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; column = &lt;span style="color:#008000;"&gt;0&lt;/span&gt;; column &amp;lt; &lt;span style="color:#2b91af;"&gt;ClipboardHistory&lt;/span&gt;.ColumnCount; column++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; index = GetIndex(row, column);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;CodeView&lt;/span&gt; thisView = _CodeViews[index];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Panel&lt;/span&gt; thisBorder = _Borders[index];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (thisView == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; || thisBorder == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;continue&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thisBorder.Size = borderSize;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thisBorder.Location = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(width * column, height * row);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; thisView.Size = viewSize;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I replaced access to &lt;strong&gt;_FrmClipHistory.ClientRectangle&lt;/strong&gt; from inside that old PositionViews code with an &lt;strong&gt;AllViewsRect &lt;/strong&gt;property access. The AllViewsRect property simply returns the client rectangle of the form, like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt; AllViewsRect&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _FrmClipHistory.ClientRectangle; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;MaximizeActiveView &lt;/strong&gt;needs this rectangle as well, and now seems like a good time to consolidate this access anyway, because I&amp;#39;m thinking about adding a status bar soon to assist with discoverability. If we do this, that status bar will reduce available space to be something &lt;em&gt;less&lt;/em&gt; than ClientRectangle. Later, if/when we need to calculate the new available space (e.g., due to this new status bar I&amp;#39;m thinking about adding to the form), we can make that calculation from a single location.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MaximizeActiveView&lt;/strong&gt; looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:courier new,courier;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; MaximizeActiveView()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; cursorIndex = GetIndex(_CursorRow, _CursorColumn);&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;CodeView&lt;/span&gt; cursorView = _CodeViews[cursorIndex];&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Panel&lt;/span&gt; cursorBorder = _Borders[cursorIndex];&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cursorView == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; || cursorBorder == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Rectangle&lt;/span&gt; viewRect = AllViewsRect;&lt;br /&gt;&amp;nbsp; viewRect.Inflate(-CursorBorder, -CursorBorder);&lt;br /&gt;&amp;nbsp; cursorView.Size = viewRect.Size;&lt;br /&gt;&amp;nbsp; cursorBorder.Size = AllViewsRect.Size;&lt;br /&gt;&amp;nbsp; cursorBorder.Location = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(&lt;span style="color:#008000;"&gt;0&lt;/span&gt;, &lt;span style="color:#008000;"&gt;0&lt;/span&gt;