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...

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...

Click OK.

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

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...

then drop it onto the design surface...

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:

Now switch to the Events view:

Double-click the Execute event handler....

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

Quick Test

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

Click 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...

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

Creating a Custom Shortcuts Folder

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

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

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....

The Key 1 TextBox gains focus....

Press Ctrl+Shift+Insert.

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.

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).

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:

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:

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...

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!

Mark Miller (DevExpress)

22 comment(s)

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.

9 September, 2008

Mark Miller (DevExpress)

Hi Christer,

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

9 September, 2008

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

9 September, 2008

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).

9 September, 2008

Mark Miller

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

11 September, 2008

Mark Miller

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

11 September, 2008

Mark Miller

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

12 September, 2008

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

12 September, 2008

Mark Miller

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

13 September, 2008

Mark Miller

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

14 September, 2008

Mark Miller

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

15 September, 2008

Mark Miller

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

16 September, 2008

Mark Miller

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

17 September, 2008

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

18 September, 2008

Mark Miller

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

18 September, 2008

Mark Miller

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

19 September, 2008

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.

19 September, 2008

.NET Geek

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

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

Thx!

9 December, 2008

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.