Introduction

The Visual Studio 2008 C++ text editor only highlights matching braces if written the first time. Almost all text editors have the feature of highlighting matching braces if you put the cursor near to an open or close brace (even the Visual Studio C# editor). This add-in will provide this feature for C++ too. (Tested with Visual Studio 2008; for 2005, you need to change the version information in the "MatchingBraces.AddIn" file from 9.0 to 8.0).

Using the Add-in

Just copy the contents of the "readyplugin" folder to "C:\Users\Username\Documents\Visual Studio 2008\Addins". Restart Visual Studio.

Put the cursor on the right side of a brace (one of: '{[()]}'). If the brace has a matching one, both braces will be highlighted with a bold font.

Source Code Overview

Get mouse and keyboard events:

To get the add-in working, we first need to get notified if the user has moved the cursor somewhere inside the text editor using the mouse or the keyboard. The Visual Studio Add-in API does not provide a functionality for mouse events. It is necessary to use a Window Hook using the SetWindowsHookEx() function. The built-in TextDocumentKeyPressEvents does not work with the arrow keys. For these keys, a keyboard hook is needed:

To make use of SetWindowsHookEx(), it is necessary to use the Platform Invoke stuff. If the user released a key or released a mouse button, the MouseProc (orKeyboardProc)
'function' will be called before the event reaches the Visual Studio window.

Do something with the event (here keyboard):

If KeyboardProc is called, we only know that a key is released somewhere. First, we need to make sure that a document is open and that the document is a C++ source code:

This is the case if the keyboard focus belongs to a window with the class "VsTextEditPane".

Next, we are (almost) ready to highlight the matching braces:

privatevoid Highlight()
{
try
{
TextSelection ts =
(TextSelection)_applicationObject.ActiveDocument.Selection;
if (!ts.IsEmpty)
{
return;
}
//create an edit point on the current cursor position
EditPoint ep = ts.ActivePoint.CreateEditPoint();
//get the letter on the left side of the cursor
String s = ep.GetText(-1);
//check if it is one of the braces: '{[( }])'
String pattern = "({|}|\\[|\\]|\\(|\\))";
if (System.Text.RegularExpressions.Regex.IsMatch(s, pattern))
{
//select the brace and rewrite it,
//this will trigger the matching braces
//functionality from Visual Studio
ts.CharLeft(true, 1);
ts.Text = s;
}
}
catch
{
}
}

Of course, it is first necessary to check if the cursor (returned by ts.ActivePoint.CreateEditPoint()) is on the right side of a brace, using GetText(-1) and a Regex which will match for all braces. If 'Yes', the brace will be selected using ts.CharLeft(true, 1) and replaced with a new one. This will trigger the built-in brace matching functionality of Visual Studio.

Avoid adding the input of the braces into the undo-list:

Everything between the call of _applicationObject.UndoContext.Open() and _applicationObject.UndoContext.SetAborted() will not be visible in the undo-list.

Avoid visible page scrolling:

After calling UndoContext.SetAborted(), the cursor will jump to the last position before UndoContext.Open() was called. It is necessary to move the page back to the current position. To hide this movement from the user, it is necessary to forbid the updating of the editor window by using: SendMessage(EditorWindowHwnd, WM_SETREDRAW, (IntPtr)0, (IntPtr)0). If everything is finished, window updating could be re-enabled using SendMessage(EditorWindowHwnd, WM_SETREDRAW, (IntPtr)1, (IntPtr)0).

Humm .. Nice add-on, but I noticed a couple of problems with it. I don't know if they are even possible to remove: 1). For files in a good source control (Perforce, VSS, etc) the files are locked by default (read only) and when you try to edit them, they either prompt or check out the files automatically (depending on your setting). This will either prompt us on every keyboard movement (in my case) or automatically check out files without knowledge, because we are actually editing the files under the covers. 2). For editable (non-read only) files, My Visual Studio File Tab shows a * sign on the file name when I am on a brace, because it has edited it just now. When I move my cursor away, it removes that because we probably undo the change without maintaining it in the undo/redo list. But that is just disturbing to eyes to see that asterisk on the file name.

I've got visual studio 2008 under MSDNAA license and unfortunately I'm only able to get the german version. As for installing this plugin I have the problem that I have no "Addins"-folder and nothing similar in the german equivalent to "C:\Users\Username\Documents\Visual Studio 2008". I tried around a bit, but I don't get working brace matching. Do you have any advice for me how to install this plugin?

if Vista the folder is: User\Dokumente\Visual Studio 2008\AddinsYou can only see the "Dokumente" folder with explorer.The germany folders do not exist in real, on your harddisk the folder is:C:\Users\Username\Documents\Visual Studio 2008\Addins.

1. make sure the files: matchingbraces.Addin and MatchingBraces.dll are in the folder "C:\Users\username\Documents\Visual Studio 2008\Addins" (click on the adress in the explorer window to see the whole path).

2. start VS and take a look in Tools->Addin-Manager if the addin is available and Startup is enabled.

3. open a C++ document and put the cursor behind a brace

tested on Win7 64 bit, englisch VS, but in the time of writing the addin I used a german version of VS and it works.

thanks for the interesting article. could you please advise as to how i could create a similar add-in that would not only find the matching end brace, but add to it a comment that relates it back to the signiture of the block it closes? i usually work in C#, so if you could use sample code in C# it would be greatly appreciated.

It would be a little more work to support multiple languages because the macro gets the properties of the text editor (C/C++, C#, VB) on startup and makes some decisions based on that. That said, it should only be a LITTLE more work. I think that given the example of what I did with the original macro, it should be straightforward to implement this yourself.

what i'm really looking to do is simply add a comment to the end brace of a block to match it's signiture. i thought i could modify/extend your example to do this. is there a better approach to do what i want?

Sorry kjward, but my knowledge of Windows add-ins is limited. I found the article by Jochen Baier and after downloading the source code I found it pretty simple to modify for my use with the VB editor. What you want to do sounds more complicated. My suggestion to you would be to download the source code, look at it and experiment with it to see if you can achieve the results you want. If not, perhaps try to contact Jochen Baier. Bottom line is that as long as you experiment on test C# source files, I don't think you can hurt anything by testing, because if your changes cause the C# files to be junked up, you can just deleted the DLL from the add-in directory and the editor will return to its normal behavior.

Visual Basic also lacks the feature to highlight round brackets. just when you close a round bracket the first time, the corresponding bracket gets highlighted, but unlike c# not when you place the cursor next to a bracket. ctrl + ] also isn't working for visual basic.net.would be great if you could adapt this addin to work for visual basic as well.