5,557,174 members and growing! (16,738 online)
Email Password   helpLost your password?
General Programming » Macros and Add-ins » Visual Studio .NET Addins     Intermediate License: The MIT License

VSHelper - Visual Studio IDE enhancements

By Ivo Beltchev

VSHelper adds some usability enhancements to Visual Studio .NET.
VC6, VC7.1, VC8.0, C++, Windows, .NET, .NET 1.1, .NET 2.0VS.NET2003, VS2005, Visual Studio, Dev

Posted: 3 Jan 2006
Updated: 20 Jul 2007
Views: 63,491
Bookmarked: 55 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
16 votes for this Article.
Popularity: 5.44 Rating: 4.52 out of 5
0 votes, 0.0%
1
1 vote, 6.3%
2
0 votes, 0.0%
3
2 votes, 12.5%
4
13 votes, 81.3%
5

Introduction

When I had to switch from Visual C++ 6 to .NET, I discovered that things were not working the same way as they used to. I had to adapt to the new IDE. I thought, "Why can't the IDE adapt to me?" That's how the VSHelper add-in was born. It fixed some of the pet peeves I had with .NET IDE. Over time, I continued to add more functionality. Hopefully, other people will find some of these features useful. The add-in registers 11 new commands, which you can map to key combinations or access from the toolbar.

Add-in commands

Cut and copy: use plain text, do nothing if no text is selected

These are replacements for the standard Edit.Cut and Edit.Copy commands. The difference is that all special formatting is stripped out from the clipboard. What does that mean? Imagine that you copy this text from your C++ source to your email:

The text is copied in Rich Text Format, which preserves the fonts and colors of the source window. Not all applications interpret the RTF content correctly. Even if they do, you may still prefer plain text. The text pasted into Outlook Express would look as follows. Note that the font and the background colors are not preserved:

The text pasted into Word would look as below. Note that the font is not preserved properly:

The text pasted into WordPad, shown below, is technically correct, but still not the same as the original:

Another feature of the new Cut and Copy is that they do nothing if no text is selected. The original Edit.Cut and Edit.Copy put the current line in the clipboard even if nothing is selected. If you press Ctrl+C when you actually wanted to press Ctrl+V, the editor will copy the current line and mess up the clipboard contents. If for some reason you want to preserve the full RTF content, in that case you can access the Edit.Copy command from the main menu or from the right-click menu.

Esc: close all secondary windows

Do you remember how you could press Esc in VC6 and hide all of the unnecessary windows? It is an incredibly useful way to quickly maximize your work area. Sadly, .NET doesn't support that, even though there is an even greater need for it because there are more modeless windows that pop up that don't close on their own. These include the Properties, Find, Toolbox, etc. windows. The new Esc command can help in this situation. Pressing Esc several times will progressively:

  • Focus the main document
  • Clear the text selection
  • Close the unnecessary windows

The list of affected windows can be customized from the settings. The initial selection includes: Output window, Find Results windows, Properties, Task List, Toolbox, Find Symbol, Find and Replace, Visual Assist's Find References and the Incredibuild window. The list of all available windows is retrieved from the HKLM\SOFTWARE\Microsoft\VisualStudio\7.1\ToolWindows registry key. For VS 2005, replace 7.1 with 8.0.

FindNext and FindPrev: find the text and close the Find window

In VS 2003, the Find window is no longer modal. This is not a big deal in itself; the problem is that it loses focus very easily. For example, press Ctrl+F, type some text and then press F3. The Find window stays open, but loses focus. Now, you have this modeless, focus-less window obscuring your editor until you press Cltr+F and Esc or reach for the mouse to close it. The new FindNext and FindPrev commands first invoke the original Edit.FindNext and Edit.FindPrevious commands and then close the Find window. It works like this:

m_pDTE->ExecuteCommand(
    CComBSTR(next?L"Edit.FindNext":L"Edit.FindPrevious"),
    CComBSTR(L""));
CloseWindow(wins,vsWindowKindFindReplace);

Output: show the Output and Find Results windows

In VC6, Output and Find Results are part of the same window. You can have a single key combination to go to them. In .NET, they are separate windows and you'll need different shortcuts for each of them. The new Output command will show all three with a single key combination. If the windows are docked together, the Output window will be on top, followed by Find Results 1 and then Find Results 2. Here's how it's done:

CComPtr<Window> output=FindWindow(wins,vsWindowKindOutput);
CComPtr<Window> find1=FindWindow(wins,vsWindowKindFindResults1);
CComPtr<Window> find2=FindWindow(wins,vsWindowKindFindResults2);
find2->Activate();
find1->Activate();
output->Activate();

Opposite: switch between C/CPP and H files

This command simply switches between the source and header files:

// Retrieve the current document's name

CComPtr<Document> doc;
m_pDTE->get_ActiveDocument(&doc);
CComBSTR name;

doc->get_FullName(&name);
wchar_t name2[_MAX_PATH+_MAX_EXT];
memcpy(name2,name,wcslen(name)*2+2);

// modify name2 according to the settings

// .....

           
// Open the new file name

CComPtr<ItemOperations> operations;
m_pDTE->get_ItemOperations(&operations);
ComPtr<Window> win;
operations->OpenFile(CComBSTR(name2),CComBSTR(vsViewKindTextView),&win);

The Opposite command can cycle between a list of extensions. By default, it is .h -> .inl -> .cpp -> .c -> .h. This can be changed from the settings. Also, if the current file starts with // ## <filename>, the command will switch to the specified file name. For example, to toggle between File.inc and File.hpp you must:

Put this in the beginning of File.inc:

// ## File.hpp

..........

Put this in the beginning of File.hpp:

// File.inc

..........

The // ## prefix is configurable from the settings.

Locate: find a document in the Solution Explorer

Visual Studio has an option "Track Active Item," which will always expand the tree in Solution Explorer to show the current document. This can be very annoying when working with large projects. After some time, all of the projects and their folders become expanded and it takes lot of scrolling to find the files you are looking for. In VS 2002, this was the only behavior. In VS 2003, it is optional and turned off by default (thanks, MS :)).

Occasionally you do need to find the current file in the Solution Explorer. That's when the Locate command comes in. It will locate the current document in the Solution Explorer. It will switch focus to Solution Explorer and will scroll the selected item into the view. The code uses a combination of the VS automation API and the Win32 API:

// Find the ProjectItem for the current document

CComPtr<Document> doc;
m_pDTE->get_ActiveDocument(&doc);

CComPtr<ProjectItem> pitem;
doc->get_ProjectItem(&pitem);

// Find the Solution Explorer object

CComPtr<Windows> wins;
m_pDTE->get_Windows(&wins);
CComPtr<Window> se=FindWindow(wins,vsWindowKindSolutionExplorer);

// Get the UIHierarchyItems

CComPtr<UIHierarchy> uih;
se->get_Object((IDispatch**)&uih);
CComPtr<UIHierarchyItems> items;
uih->get_UIHierarchyItems(&items);

// Convert the ProjectItem into UIHierarchyItem

CComPtr<UIHierarchyItem> hitem=FindProjectItem(items,pitem);
if (hitem) 
{
    // Select the item in the Explorer

    hitem->Select(vsUISelectionTypeSelect);
    if (g_SolutionTree) 
    {
        // Scroll the item into view

        HTREEITEM h=TreeView_GetSelection(g_SolutionTree);
        TreeView_EnsureVisible(g_SolutionTree,h);
    }
    // Activate the Solution Explorer window

    se->Activate();
}

Home: go to the first column (in VS 2003 version only)

Another thing missing from VS 2003 is the "Go to the first column of the line" command. The new Home command does exactly that: It jumps to the first column of the current line. That command exists only in the VS 2003 version of the add-in because in VS 2005 that feature is back; the command is called Edit.LineFirstColumn.

CComPtr<Window> w;
m_pDTE->get_ActiveWindow(&w);

// Get the selection

CComPtr<TextSelection> sel;
w->get_Selection((IDispatch **)&sel);

// Jump to the beginning of the line

long top;
sel->get_TopLine(&top);
sel->GotoLine(top,FALSE);

ClearBookmarks (in VS 2005 version only)

Starting with VS 2005, if you try to clear all bookmarks in the document you will be asked "Are you sure you want to delete all of the bookmark(s)?" It would be great if there was a way to turn this question off after the first time, but there isn't. You can use the ClearBookmarks command instead:

CComPtr<Document> doc;
m_pDTE->get_ActiveDocument(&doc);

// get the text document

CComPtr<IDispatch> spTextDocumentDisp;
doc->Object(CComBSTR(L"TextDocument"),&spTextDocumentDisp);
CComQIPtr<TextDocument> textDoc=spTextDocumentDisp;

textDoc->ClearBookmarks();

Settings

The Settings command opens a dialog box to edit the settings:

Screenshot - settings.gif

  • Evaluate g_DebugData - Evaluates g_DebugData when the debugger stops. See below. The change will take effect the next time Visual Studio is started.
  • Add new files to Perforce - When new files are added to the project, they will be added to Perforce automatically. See below. The change will take effect the next time Visual Studio is started.
  • Always show selection in Solution Explorer - Shows the selection in the Solution Explorer even when it is inactive. See below. This option is only available in Visual Studio 2005. The change will take effect the next time Visual Studio is started.
  • Support for Numpad Clear key - Translates VK_CLEAR to VK_NUMPAD5. See below. This option is only available in Visual Studio 2005. Turning this option ON requires restarting Visual Studio.
  • Opposite order - Lists the order of extensions for the Opposite command. You can add or remove extensions and change their order.
  • Opposite prefix - The prefix for the Opposite command.
  • Windows to close - Shows a list of all tool windows in Visual Studio. The selected windows will be closed with the Esc command.

Additional features

Subclassing Solution Explorer (in VS 2005 version only)

The developers of VS 2005 decided that the selection in the Solution Explorer should be hidden if the window doesn't have focus and if "Track Active Item" is off. I have that option off; see the Locate command. Now imagine the following situation: You select multiple projects and open their settings. The Solution Explorer loses focus because the settings dialog gets the focus and now you can't see which projects you are editing! I'm sure there must be a good reason behind that behavior. I just can't find it. Fortunately, Solution Explorer is using a standard TreeView control. The add-in subclasses Solution Explorer to force the TVS_SHOWSELALWAYS style:

LRESULT CALLBACK CConnect::SolutionProc( HWND hWnd, 
    UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    // Force the TVS_SHOWSELALWAYS style

    if (uMsg==WM_STYLECHANGING && wParam==GWL_STYLE)
        ((STYLESTRUCT*)lParam)->styleNew|=TVS_SHOWSELALWAYS;
    return CallWindowProc(g_OldSolutionProc,hWnd,uMsg,wParam,lParam);
}

Support for the numpad Clear key (in VS 2005 version only)

In the VC6 IDE, you can create shortcuts using the key in the middle of the Numpad, i.e. where the digit 5 is. The shortcut can be used with NumLock turned off. VC6 calls this key "Numpad Clear," i.e. "Ctrl+Numpad Clear." VS 2003 still supports such shortcuts, but doesn't have a name for the key. The shortcuts show up as "Ctrl+."

VS 2005 completely ignores the Clear key and it can't be used in shortcuts. On the other hand, it accepts the "Num 5" key, which is the same but with NumLock turned on. Since I keep my NumLock turned off, I have a whole key on my keyboard that I can't use. The VSHelper add-in solves that problem by installing a keyboard hook and translating VK_CLEAR to VK_NUMPAD5. When the hook is in effect, you can press the Clear key with or without NumLock and Visual Studio will accept it as the "Num 5" key:

LRESULT CALLBACK CConnect::NumKeyboardProc( int code,
    WPARAM wParam, LPARAM lParam )
{
    if (code<0) return CallNextHookEx(g_KbdHook,code,wParam,lParam);
    if (CallNextHookEx(g_KbdHook,code,wParam,lParam)) return TRUE;
    if (!g_bTranslateNum5 || wParam!=VK_CLEAR) return FALSE;
    if (GetKeyState(VK_CONTROL)>=0 && GetKeyState(VK_SHIFT)>=0
         && GetKeyState(VK_MENU)>=0) return FALSE;
    keybd_event(VK_NUMPAD5,0,(lParam&0x80000000)?KEYEVENTF_KEYUP:0,0);
    return TRUE;
}

The hook is controlled by the "Support for Numpad Clear key" option. If the option is on when Visual Studio starts, the hook will be installed. If you really need to enter the Clear key, you can temporarily disable the VK_CLEAR -> VK_NUMPAD5 translation by turning off the option. There is only one place in VS where this might be necessary: When creating an accelerator in your resources that uses the Clear key. Even then, you can simply type VK_CLEAR in the accelerator table.

Evaluate debug data

The add-in registers an OnEnterBreakMode event handler. Every time the debugger breaks, the handler will calculate the expression ((int)&g_DebugData),d and will store it in a variable. You can retrieve the value by calling the GetDebugData function. The purpose of that value will be revealed in another article [1]. :)

static char g_DebugData[128];

// OnEnterBreakMode handler

STDMETHODIMP CConnect::OnEnterBreakMode(EnvDTE::dbgEventReason Reason,
    EnvDTE::dbgExecutionAction* ExecutionAction)
{
    *ExecutionAction=dbgExecutionActionDefault;
    Expression *exp=NULL;
    memcpy(g_DebugData,"err",4);
    if (g_pDebugger) 
    {
        // Evaluate the expression and store the 

        // result in g_DebugData

        g_pDebugger->GetExpression(CComBSTR("((int)&g_DebugData),d"),
           VARIANT_FALSE,-1,&exp);
        if (!exp) return S_OK;
        BSTR val=NULL;
        exp->get_Value(&val);
        exp->Release();
        if (!val) return S_OK;
        WideCharToMultiByte(CP_ACP,0,val,-1,
            g_DebugData,sizeof(g_DebugData),NULL,NULL);
        SysFreeString(val);
    }
    return S_OK;
}

Perforce helper

When working with Perforce, I prefer to use the P4Win client to submit my changes instead of the Visual Studio integration. Sometimes I add files to the project and forget to add them to Perforce, so the next day when somebody tries to build my code they complain about missing files.

For VS 2005, the add-in registers the OnItemAdded event handler that fires when a new file is added to the project. For VS 2003, there is no such universal event. Instead, the add-in first registers an OnOpened event handler that fires when a new solution is opened. Then it goes through all projects of the solution and, if it finds a C++ project, it registers the OnItemAdded handler for that project only. For more details on how to hook project events, see here: [2].

Once the OnItemAdded event is detected, the add-in checks if the new file is under Perforce control by issuing the fstat command. If it is not, the file is added to default change list -- but not submitted -- with the add command. To compile the Perforce code, you will need the multithreaded DLL version of the P4API. The latest version can be found here: [3]. To disable the Perforce functionality, comment out #define ADD_TO_PERFORCE at the top of the Connect.inc file. This will allow you to compile VSHelper without the P4API. Documentation for the Perforce API can be found here: [4].

Configuration combo box (in VS2005 version only)

Visual Studio 2005 has combo boxes to select the configuration and platform:

Screenshot - ConfigurationEnabled.gif

This is all great until you start building or debugging. Since you can't change the configurations during building/debugging, the combo boxes get disabled. Unfortunately in VS 2005, the disabled combo boxes also hide their text:

Screenshot - ConfigurationDisabled.gif

Now I can't see what configuration I'm currently using! If you work on a project with many configurations or platforms, you know how annoying this can be. To solve that problem, the add-in creates a new combo box that you can use to select the current configuration:

Screenshot - Configuration.gif

Instead of getting greyed out, the combo box just ignores the mouse clicks if a build or a debugging session is currently running. You can read all of the details on implementing a custom combo box here: [5]. In short, you create your command like this:

pCommands2->AddNamedCommand2(m_pAddInInstance, CComBSTR(L"Configuration"),
    CComBSTR(L"Configuration"),
    CComBSTR(L"Current solution configuration"),
    VARIANT_TRUE, CComVariant(0), NULL,
    vsCommandStatusSupported+vsCommandStatusEnabled,
    EnvDTE80::vsCommandStyleComboNoAutoComplete,
    EnvDTE80::vsCommandControlTypeDropDownCombo, &pConfiguration);

This will create two commands. The first is called Configuration and the second is called Configuration_1. If the Configuration command is called with no parameter, it must return the text to display in the combo box. If it is called with a parameter, then the user has selected a new item from the list:

if (pvarVariantIn->vt==VT_BSTR && pvarVariantIn->bstrVal) 
{
    // A new text was selected by the user

    return S_OK;
}
else 
{
    // Set the text of the combo box

    CComVariant(L"Combo box text").Detach(pvarVariantOut);
    return S_OK;
}

The Configuration_1 command is called to fill the list of the combo box. The list is returned as a safe array:

CComSafeArray<BSTR> arr(count);
for (int i=0;i<count;i++) 
{
    swprintf(buf,L"Item %d",i+1);
    arr.SetAt(i,CComBSTR(buf));
}
ComVariant(arr).Detach(pvarVariantOut);
return S_OK;

Custom toolbar

The add-in creates a new custom toolbar that contains buttons for most of the commands:

Screenshot - Toolbar.gif

A tip for using custom images in add-ins: To use custom images for the new commands, the add-in must provide a DLL with bitmap resources and provide two values in the registry under the HKLM\Software\Microsoft\VisualStudio\7.1\AddIns\<addin name>.Connect key. For VS 2005, use 8.0 instead of 7.1. The values are SatelliteDLLPath and SatelliteDLLName. The full path to the DLL is constructed like this: <SatelliteDLLPath>\<language code>\<SatelliteDLLName>. The language code is the numeric value of the current language, i.e. 1033 is English. Then when you register the commands call:

pCommands->AddNamedCommand(m_pAddInInstance, CComBSTR(L"FindNext"),
    CComBSTR(L"FindNext"), CComBSTR("Find next text"),
    VARIANT_FALSE, // FALSE means to get the bitmap from the DLL

    IDB_FINDNEXT, // IDB_FINDNEXT is the bitmap's resource ID

    NULL, vsCommandStatusSupported+vsCommandStatusEnabled,&pFindNext);

In this case, we only need bitmaps and they are supposed to be the same in all languages. So instead of providing an additional DLL for the resources, we can use the original add-in DLL: VS2003Helper. To do that, use these keys in your setup project:

SatelliteDLLPath=[TARGETDIR]    <- this gets expanded to the installation path
SatelliteDLLName='..\VS2003Helper.DLL'

When combined, the full path will be <install path>\1033\..\VS2003Helper.DLL, which when optimized points exactly to the add-in's own DLL. Another trick to use during development: Since you will be running the DLL from the Debug or Release folder of your project, it will be hard to update the registry with the correct path. Instead, in the RGS file use:

val SatelliteDLLPath = s '%MODULE%\..'    <- this gets expanded
    to <project path>\Debug\VS2003Helper.DLL
val SatelliteDLLName = s '..\VS2003Helper.DLL'

When combined, the full path will be <project path>\Debug\VS2003Helper.DLL\..\1033\..\VS2003Helper.DLL, which when optimized points to the DLL in the Debug folder.

Installation

  • VS 2003: Download VS2003Helper.zip and run Setup.exe.
  • VS 2005: Download VS2005Helper.zip and run Setup.exe.
  • The add-in will not automatically bind any of the commands to key combinations. You must do so manually in Visual Studio from Tools\Options\Keyboard. All commands are prefixed with VS2003Helper.Connect or VS2005Helper.Connect.

Building the code

The source code contains projects for VS 2003 and 2005. All of the magic happens in the Connect.inc file, which is shared between the two projects. The bitmaps for the toolbar buttons are also shared. If you want to use the Perforce functionality, you need to download P4API from here: [3]. In the project settings, replace D:\Work\Libs\p4api with the actual path to the API.

Licensing

The source code, binaries and this article are owned by Pandemic Studios. They can be freely used for commercial and non-commercial purposes under the terms of the MIT license. A copy of the license is included in the readme.rtf file in VSHelperSrc.zip.

Known problems and future development

The Output command always shows the Output window on top. There may be a way to preserve the Z-order between the Output window and the Find Results windows. Possibly the add-in can subclass these windows and keep track of which is activated last. Perforce functionality uses only the default settings: depot, workspace, user, password. Instead, they can be added to the Settings dialog. Even better, the settings can probably be retrieved from solution properties. Also, in VS 2003 only C++ projects are supported. A future version may support different project types such as C#, VB, etc.

Links

[1] Debugger support for CRC hash values

[2] HOWTO: Getting Project and ProjectItem events from a Visual Studio .NET add-in

[3] Download latest multithreaded DLL version of the P4API

[4] Perforce API documentation

[5] Craig Skibo's WebLog: Command Bar Types, Part 2

[6] HOWTO: Removing commands and UI elements during Visual Studio .NET add-in uninstallation

History

  • Jan, 2006 - First version:
    • The add-in compiles and runs for VS 2003 and VS 2005 Beta 2. Binaries provided for VS 2003 only
  • Mar, 2006 - Few fixes:
    • Fixed a compatibility issue with Visual Assist. The text from the Copy and Cut commands wasn't added to the Visual Assist's Paste Menu
    • Optimized the Locate command for large solutions
  • Oct, 2006 - Version 2.0: new features and bug fixes:
    • Additions to the Opposite command
    • Settings dialog to enable some of the features and to configure the Opposite command
    • Perforce helper automatically adds new files to Perforce
    • Toolbar with icons for most commands
    • Fixed a bug in the Copy and Cut commands that corrupts the clipboard when they are used in the image editor
    • Added uninstall script to remove the commands and the toolbar from Visual Studio. For more details on uninstall scripts see here: [6]
    • Provided binaries for VS 2005
  • Feb, 2007 - Version 2.2: new features and bug fixes:
    • Added ClearBookmarks command for VS 2005
    • Added support for the Numpad Clear key for VS 2005
    • Added a list to pick which windows to close with the Esc command
    • Fixed a crash when opening some corrupted *.vcproj files
    • Published under the MIT license
  • Jul, 2007 - Version 2.5: new features and bug fixes:
    • Added Configurations combo box for VS 2005
    • Some more fixes to the Copy and Cut commands to work reliably with HTML and binary documents
    • Fixed some COM reference leaks
    • Some code cleanup

License

This article, along with any associated source code and files, is licensed under The MIT License

About the Author

Ivo Beltchev


Ivo started programming in 1985 on an Apple ][ clone. He graduated from Sofia University, Bulgaria with a MSCS degree. Ivo has been working as a professional programmer for over 12 years, and as a professional game programmer for over 10. He is currently employed in Pandemic Studios, a video game company in Los Angeles, California.
Occupation: Software Developer (Senior)
Location: United States United States

Other popular Macros and Add-ins articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 26 (Total in Forum: 26) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralOnEnterBreakMode event handler fails on Vistamemberromko22:11 31 Jul '07  
GeneralAlways show selection in Solution Explorermemberkak_karsten1:05 27 Jul '07  
GeneralRe: Always show selection in Solution ExplorermemberIvo Beltchev7:27 27 Jul '07  
GeneralRe: Always show selection in Solution Explorermemberkak_karsten22:12 29 Jul '07  
GeneralIs there no need for .addin file for C++ addinsmemberjass_sim15832:46 26 Dec '06  
GeneralRe: Is there no need for .addin file for C++ addinsmemberIvo Beltchev7:52 26 Dec '06  
GeneralRe: Is there no need for .addin file for C++ addinsmemberjass_sim158317:52 26 Dec '06  
QuestionAnother new optionmemberRonald E. Chambers13:02 17 Oct '06  
AnswerRe: Another new optionmemberIvo Beltchev13:15 17 Oct '06  
GeneralRe: Another new optionmemberRonald E. Chambers7:23 19 Oct '06  
Questionnew feature requestmemberromko3:09 13 Oct '06  
AnswerRe: new feature requestmemberIvo Beltchev7:21 13 Oct '06  
GeneralRe: new feature requestmemberromko0:42 20 Oct '06  
GeneralRe: new feature requestmemberIvo Beltchev6:30 20 Oct '06  
GeneralCtrl-C without selection still copies linememberowillebo21:58 10 Oct '06  
GeneralRe: Ctrl-C without selection still copies linememberIvo Beltchev6:27 11 Oct '06  
GeneralRe: Ctrl-C without selection still copies linememberowillebo10:37 11 Oct '06  
GeneralRe: Ctrl-C without selection still copies linememberIvo Beltchev10:52 11 Oct '06  
GeneralLocate is easymemberAlex Cohn2:59 15 Feb '06  
GeneralRe: Locate is easymemberfeline_dracoform4:41 26 Feb '06  
GeneralRe: Locate is easymember