Introduction
For most programs, users can use the "thumb-buttons" of the mouse to navigate forwards or backwards. This add-in will implement this feature in Visual Studio 2008 C++. (C# has this feature built-in).
Example usage
- Jump to a function definition (right click on the function name, "Go to definition").
- Jump back using the "backward button" of your mouse.
A look inside the code
The API for Visual Studio add-ins do not provide the possibility to get informed if a mouse button is pressed inside the Visual Studio window. It is necessary to use a Hook to achieve this:
private void InitHook()
{
this.MouseProcDelegate = new HookProc(this.MouseProc);
uint id = GetCurrentThreadId();
hhook=SetWindowsHookEx(WH_MOUSE,
this.MouseProcDelegate, IntPtr.Zero, id);
}
The InitHook()
function is called if Visual Studio is loading an add-in (on VS start). The hook is only attached to the thread whose the thread-ID is returned by GetCurrentThreadId()
. The hook will receive the mouse events before Visual Studio does. Another possibility could be a ShellHook (WH_SHELL
) (HSHELL_APPCOMMAND
with the APPCOMMAND_BROWSER_BACKWARD
and APPCOMMAND_BROWSER_FORWARD
events). But, this does not work well (the event is not triggered under all circumstances).
The Hook will call the MouseProc
function:
private int MouseProc(int code, IntPtr wParam, ref MOUSEHOOKSTRUCTEX lParam)
{
try
{
if (code != HC_ACTION)
{
return CallNextHookEx(hhook, code, wParam, ref lParam);
}
if (wParam.ToInt32() == WM_XBUTTONUP)
{
switch (HiWord(lParam.mouseData))
{
case XBUTTON1:
Debug.Write("mouse back button\n");
_applicationObject.ExecuteCommand("View.NavigateBackward", "");
return 1;
case XBUTTON2:
Debug.Write("mouse forward button\n");
_applicationObject.ExecuteCommand("View.NavigateForward", "");
return 1;
}
}
}
catch
{
}
return CallNextHookEx(hhook, code, wParam, ref lParam);
}
MOUSEHOOKSTRUCTEX
is an updated version of MOUSEHOOKSTRUCT
which supports the extra mouse buttons. If the wParam
is WM_XBUTTONUP
, one of the mouse thumb-buttons was released. You can find out which one was released using the hi-word of lParam.mouseData
:
XBUTTON1
: backward button
XBUTTON2
: forward button
Finally, ExecuteCommand()
is used to call the navigation functionality of Visual Studio:
_applicationObject.ExecuteCommand("View.NavigateBackward", "");
_applicationObject.ExecuteCommand("View.NavigateForward", "");
History
- 0.2: Checks if the mouse button is pressed inside a C++ editor window.
- 0.1: Initial version.