将鼠标侧按钮绑定到VisualStudio操作

我尝试将XButton 1和2(鼠标的侧面按钮)重定向到特定的Visual Studio操作。

当我按下XButton1时,我想编译项目/构建它。 默认情况下,此操作绑定到F6

当我按下XButton2时,我想在代码和设计视图(WinForms)之间切换。 这与F7绑定。

在使用Visual Studio内置工具多次尝试后,我使用AutoHotKey创建了以下脚本:

XButton2:: IfWinActive Microsoft Visual Studio { Send {F7} return } XButton1:: IfWinActive Microsoft Visual Studio { Send {F6} return } 

但是,我想知道是否有人知道使用Visual Studio 2015实现相同的本地方式?

主要思想是注册全局鼠标钩子并处理所需的鼠标事件并运行visual studio命令。 为此:

  1. 首先创建一个Visual Studio包项目。
  1. 使用SetWindowsHookEx注册一个全局鼠标钩子,方法是传递WM_XBUTTONDOWN并处理所需的鼠标事件,例如WM_XBUTTONDOWN 。 解决方案加载时执行注册。
  1. 使用DTE.ExecuteCommand运行所需的Visual Studio命令,传递合适的命令,例如Build.BuildSolution

     var dte = (EnvDTE.DTE)this.GetService(typeof(EnvDTE.DTE)); dte.ExecuteCommand("Build.BuildSolution"); 
  1. 解决方案关闭时,不要忘记使用UnhookWindowsHookEx取消挂钩。

注意:

  • 要查找所需的命令,请转到Tools → Options → Environment → KeyBoard然后找到所需的命令。

  • 你会发现很多关于如何注册像这样的全局鼠标钩子的资源,我改变了一些并用于测试。 在post的最后,您可以找到完整的源代码。

  • 在Visual Studio 2013中,不推荐使用添加项,因此虽然您可以使用Visual Studio外接程序项目执行相同操作,但最好使用VSPackage执行此操作。

Implementaion

首先创建一个Visual Studio包项目,然后将包的代码更改为我在此处发布的代码。 还要将我用于全局鼠标挂钩和Windows API的类添加到解决方案中。

这是我的包的完整代码:

 using Microsoft.VisualStudio.Shell; using System; using System.Runtime.InteropServices; [PackageRegistration(UseManagedResourcesOnly = true)] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] [Guid(GuidList.guidVSPackage1PkgString)] [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.SolutionExists)] public sealed class VSPackage1Package : Package { public VSPackage1Package() { } EnvDTE.DTE dte; protected override void Initialize() { base.Initialize(); dte = (EnvDTE.DTE)this.GetService(typeof(EnvDTE.DTE)); dte.Events.SolutionEvents.Opened += SolutionEvents_Opened; dte.Events.SolutionEvents.AfterClosing += SolutionEvents_AfterClosing; } void SolutionEvents_AfterClosing() { MouseHook.Stop(); } void SolutionEvents_Opened() { MouseHook.Start(); MouseHook.MouseAction += MouseHook_MouseAction; } void MouseHook_MouseAction(object sender, EventArgs e) { dte.ExecuteCommand("Build.BuildSolution"); } } 

Windows API消息,结构和方法

 using System; using System.Runtime.InteropServices; public class Win32 { public delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam); public const int WH_MOUSE_LL = 14; public enum MouseMessages { WM_LBUTTONDOWN = 0x0201, WM_LBUTTONUP = 0x0202, WM_MOUSEMOVE = 0x0200, WM_MOUSEWHEEL = 0x020A, WM_RBUTTONDOWN = 0x0204, WM_RBUTTONUP = 0x0205 } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; } [StructLayout(LayoutKind.Sequential)] public struct MSLLHOOKSTRUCT { public POINT pt; public uint mouseData; public uint flags; public uint time; public IntPtr dwExtraInfo; } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr GetModuleHandle(string lpModuleName); } 

全球鼠标钩

由于我的鼠标中没有XButton,因此我处理了WM_RBUTTONDOWN事件。

 using System; using System.Diagnostics; using System.Runtime.InteropServices; public static class MouseHook { public static event EventHandler MouseAction = delegate { }; private static Win32.LowLevelMouseProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; public static void Start() { _hookID = SetHook(_proc); } public static void Stop() { Win32.UnhookWindowsHookEx(_hookID); } private static IntPtr SetHook(Win32.LowLevelMouseProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { var handle = Win32.GetModuleHandle(curModule.ModuleName); return Win32.SetWindowsHookEx(Win32.WH_MOUSE_LL, proc, handle, 0); } } private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && Win32.MouseMessages.WM_RBUTTONDOWN == (Win32.MouseMessages)wParam) { Win32.MSLLHOOKSTRUCT hookStruct = (Win32.MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(Win32.MSLLHOOKSTRUCT)); MouseAction(null, new EventArgs()); } return Win32.CallNextHookEx(_hookID, nCode, wParam, lParam); } }