Blogs

Mark Miller

Clipboard History Plug-in for Visual Studio with the DXCore, Part 1

Hey, let's create a new plug-in that shows the recent history of clipboard operations using the DXCore, a free and powerful extensibility engine for Visual Studio. If you don't already have the DXCore installed (it's already installed if you have CodeRush or Refactor! Pro), you can get it here.

In this series of daily blog posts we'll go from rough idea to a finished, polished feature, which will eventually ship with CodeRush (including full source). So not only will this series show you how to build plug-ins for Visual Studio, but it will also give you some insight into the creative process we go through here at Developer Express as we build killer developer tools for you.

In this, the first post of the series, you'll learn how to:

  • Create plug-in projects using the DXCore's helpful wizards.
  • Add Actions (commands) to your plug-in.
  • Bind keyboard shortcuts to your commands.
  • Constrain feature availability with context.
  • Handle Visual Studio events.
  • Send text out to the Visual Studio status bar.

I think you'll find all of this easy to follow and even easier to implement. So sit back and enjoy as we start the journey to an exciting and powerful new feature....

Getting Started

From the DevExpress menu, select New Plug-in...

NewPlugin

Select a language and specify the name of the plug-in. I like to prefix features that go into CodeRush with "CR_", so I'm doing that here...

New DXCore Plugin Project

Click OK.

The next dialog lets you specify settings for the project. We can accept all the defaults here.

ProjectSettings

Click OK.

Adding an Action

Next, let's add an action so we can invoke our clipboard history with a keyboard shortcut or menu item. From the DXCore section of the Toolbox, select the "Action" item...

SelectAction

then drop it onto the design surface...

DropAction

and set the following properties:

Property Value Comments
(Name) actClipboardHistory We'll give our "action1" a meaningful name.
ActionName ClipboardHistory We can bind this action to a shortcut later.
Description Shows a history of recent clipboard operations. This description will show up in the User Guide later when the plug-in is loaded.

The Properties grid should now look like this:

actClipboardHistoryProperties

Now switch to the Events view:

SwitchToTheEventsTab

Double-click the Execute event handler....

DoubleClickExecute

Let's add some quick test code so we can quickly verify everything is working.

private void actClipboardHistory_Execute(ExecuteEventArgs ea)
{
  MessageBox.Show("Show clipboard history.");
}

Listening to ClipboardChanged

Let's also listen to the event that fires whenever the clipboard's content changes....

ActivateDesignSurface

Activate the design surface.

ActivateDesignSurface2

Click the design surface itself (so no controls are selected).

ClickOnDesignSurface

Switch to the Events view of the Properties grid.

ActivateEventsTabForSurface

Double-click the ClipboardChanged event.

CreateClipboardChangedHandler

Let's send some text out to the status bar, just so we can have some visual confirmation that the event is firing when we expect it to.

private void PlugIn1_ClipboardChanged(ClipboardChangedEventArgs ea)
{
  string clipboardText = ea.Details.Text;
  if (String.IsNullOrEmpty(clipboardText))
    return;
  int lineBreakPos = clipboardText.IndexOf(Environment.NewLine);
  if (lineBreakPos > 0)
    clipboardText = clipboardText.Substring(0, lineBreakPos) + " ...";
  CodeRush.ApplicationObject.StatusBar.Text = "Clipboard: " + clipboardText;
}
 

Quick Test

Now let's test what we have so far....

Click Run.

Run

This will start up a second instance of Visual Studio.

Important: If you're stepping through code in an instance of Visual Studio that has the DXCore loaded, it is possible to lockup both instances of Visual Studio if you change the contents of the clipboard. This can happen because each instance of the DXCore participates in the clipboard chain, and the instance you're stepping through is unable to respond to clipboard chain messages.

Binding a Shortcut to our ClipboardHistory Action

First, let's assign a shortcut binding to our new ClipboardHistory Action in the newly started instance of Visual Studio....

From the DevExpress menu, select Options...

DevExpressOptions

Open the IDE folder and select the Shortcuts options page....

ClickShortcutsPage

Creating a Custom Shortcuts Folder

If you don't already have a folder for custom shortcuts, click the New Folder button...

 NewShortcutFolder

Give the folder a good name, and make it a top-level folder...

NewFolderDetails

Creating a New Shortcut

Now with your new shortcuts folder selected and ready to hold all your custom shortcuts, click the New Keyboard Shortcut button....

NewKeyboardShortcut

The Key 1 TextBox gains focus....

Key1FieldHasFocus

Press Ctrl+Shift+Insert.

CtrlShiftInsert

This will be the shortcut we press to invoke the clipboard history.

Tab down to the "Command:" combo box.... Type in the first few letters of our ClipboardHistory action.

SpecifyingTheClipboardHistoryAction

Our action name should auto-fill, our first indication that our new clipboard history plug-in has loaded successfully.

If we don't specify a context for this Ctrl+Shift+Insert command binding, then this shortcut binding will be valid and work anywhere inside Visual Studio (even when modal dialogs are up). I'm comfortable with that for now.

Applying Constraints with the Context Picker

If we wanted to limit this shortcut to a more constrained context, we could specify those constraints in the context picker. For example, if we wanted this binding to only work when the code editor had focus, we would give the Focus\Documents\Source\Code Editor context a green check, which means this condition must be satisfied (the editor must have focus).

UseWhenCodeEditorHasFocus

Note that if you click the condition a second time, the green check will turn into a red X, indicating that the condition must be false in order for the binding to be valid.

Clicking the condition a third time will cycle it back to an empty box, which means the context is ignored. It is possible to combine contexts in very sophisticated ways, so you can precisely define the state in which the shortcut binding is allowed to function.

Click OK to close the DevExpress Options dialog (and we'll leave that context empty so the shortcut binding works anywhere).

Testing the Shortcut Binding

Press Ctrl+Shift+Insert, and if everything is working as expected, we'll see our dialog:

ShowClipboardHistory

Great! We've successfully bound a shortcut to our new Action. We'll fill that method with real code in a bit.

Testing the ClipboardChanged Handler

Next, let's test the code we added in the ClipboardChanged event handler. Because this event fires whenever the contents of the clipboard changes, regardless of from where the clipboard change takes place, you should be able to select the title of this section ("Testing the ClipboardChanged Handler") in your browser and then copy that to the clipboard, and see the status bar in Visual Studio change. Try that now. You should see something like this in the instance of Visual Studio that we're testing:

StatusBarUpdate

Excellent! The ClipboardChanged event is firing as expected.

Shutting Down the Test Instance of Visual Studio

Important: When debugging two instances of Visual Studio like this, if the first instance (the debugger) has the DXCore loaded, then we strongly recommend you close down the second instance by clicking the red X close button in the upper right...

ClosingVisualStudio

or by selecting File | Exit from Visual Studio. This will allow the second instance of the DXCore to shut down properly, which includes the necessary de-registration of the DXCore's clipboard hook.  

Wrapping Up the First Part

Congratulations! We've just completed the first, most important step of the process, setting up the plug-in framework.

In tomorrow's post, we'll dive more into the functional implementation details of the clipboard history. See you then!

Published Sep 08 2008, 03:02 PM by
Bookmark and Share

Comments

Christer Johannesson

I've tried to follow the tutorial but I can't find the CodeRush.ApplicationObject. I am running 3.0.8 of CodeRush.

September 9, 2008 5:15 AM

Mark Miller (DevExpress)

Hi Christer,

CodeRush.ApplicationObject is hidden from Intellisense, but it is there and the line should compile.

September 9, 2008 7:36 AM

Tarik Souirji

Hi,

when I tried this in VS 2008 none of the references could be loaded (little warning signs), I tried to remove them and add them manually but without success ...

So I tried it in VS 2005 and it worked.

Now I wanted to push this tutorial a bit further by adding a form that lists the clipboard history (gridcontrol so it looks nice and has searching capabilities). Everything runs smoothly, but I was wondering how to return the selected "clipboard" element back to the IDE (code editor for example) ?? That is to say, insert the selected text where the plugin was called. I tried to use the Core.ExecuteEventArgs.varOut but it didn't work.

Thank you in advance for providing a little help on this,

Tarik

September 9, 2008 8:12 AM

Mark Miller (DevExpress)

Hi Tarik,

I'm not sure what problem you had in VS 2008, but I'm wondering if VS 2008 was installed after DXCore. I suggest running this by support@devexpress.com. To insert clipboard text into the code editor (I'll cover this in detail in an upcoming post), you can call CodeRush.Command.Execute("Edit.Paste"). To place text on the clipboard you can use Clipboard.SetText(textToPaste).

September 9, 2008 8:24 AM

Mark Miller

Welcome to Part 4 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 11, 2008 7:22 AM

Mark Miller

Welcome to Part 3 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 11, 2008 9:01 AM

Mark Miller

Welcome to Part 5 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 12, 2008 11:22 AM

Clipboard History Plug-in for Visual Studio with DXCore, Part 2 - Mark Miller

Pingback from  Clipboard History Plug-in for Visual Studio with DXCore, Part 2 - Mark Miller

September 12, 2008 2:44 PM

Mark Miller

Welcome to Part 6 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 13, 2008 5:40 PM

Mark Miller

Welcome to Part 7 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 14, 2008 1:35 PM

Mark Miller

Welcome to Part 8 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 15, 2008 10:26 AM

Mark Miller

Welcome to Part 9 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 16, 2008 12:27 PM

Mark Miller

Welcome to Part 10 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 17, 2008 12:34 PM

Martin Hart

Mark:

When the series is completed can I access the whole series in one document?

I would like to follow the tutorial from start to finish.

Thanks,

Martin

September 18, 2008 2:52 AM

Mark Miller

Welcome to Part 11 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 18, 2008 12:29 PM

Mark Miller

Welcome to Part 12 of the series showing how to build plug-ins for Visual Studio using DXCore . So far

September 19, 2008 3:25 PM

Mark Miller (DevExpress)

Hi Martin,

We may provide access to the entire series through a knowledge base article and perhaps also through a tutorial integrated into the DXCore. We're still looking into those possibilities.

September 19, 2008 4:55 PM

.NET Geek

In the previous post we just defined what we want the plugin to do. Let's start to walk through the

October 19, 2008 7:14 AM

The One With

Congratulations Mark! We have submitted two entries for the Show Off Contest winner. [ http://www.microsoftpdc

October 28, 2008 3:54 PM

Guillaume Hanique

Hi!

Question: Why should you hide the ApplicationObject-property from Intellisense?

Thx!

December 9, 2008 5:41 AM

J Pottle

I'm working through your series and as a new .Net developer, I'm learning quite a bit. One problem I'm having is that the "language ID" of the clipboard entries is not populated. I'm wondering where that property comes from and if I'm doing something wrong. Thanks a million.

Jacqueline

jpf at nf dot sympatico dot ca

March 17, 2009 3:58 PM

Mehul Harry (DevExpress)

Good post from CodeRush Dev Alex S. on this feature and series:

www.skorkin.com/.../coderush-clipboard-history

December 22, 2010 5:58 PM

About Mark Miller (DevExpress)

Mark Miller is a C# MVP with strong expertise in decoupled design, plug-in architectures, and great UI. Mark is Chief Architect of the IDE Tools division at Developer Express, and is the visionary force behind productivity tools like CodeRush and Refactor!, as well as the DXCore extensibility layer for Visual Studio. Mark is a popular speaker at conferences around the world and has been writing software for over two decades.
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, Silverlight, ASP.NET, WinForms, HTML5 or Windows 8, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2014 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners