2014-02-17 99 views
0

我需要这个问题有所帮助:注册全局热键的副本

我想注册一个热键(按Ctrl + Shift + C),其工作全局(也在其他应用程序)。当它被按下时,它应该让我选择的对象(字符串,文件,...这里没有定义)。应用程序应该是WPF项目。

我发现了一些代码部分,但最终没有奏效。

我想要做什么?我尽量让剪贴板帮助工具,在那里我可以存储多个项目

很多谢

的达蒙


守则热键

public sealed class HotKey : IDisposable 
{ 
    public event Action<HotKey> HotKeyPressed; 

    private readonly int _id; 
    private bool _isKeyRegistered; 
    readonly IntPtr _handle; 

    public HotKey(ModifierKeys modifierKeys, System.Windows.Forms.Keys key, System.Windows.Window window) 
     : this(modifierKeys, key, new WindowInteropHelper(window)) 
    { 
     Contract.Requires(window != null); 
    } 

    public HotKey(ModifierKeys modifierKeys, System.Windows.Forms.Keys key, WindowInteropHelper window) 
     : this(modifierKeys, key, window.Handle) 
    { 
     Contract.Requires(window != null); 
    } 

    public HotKey(ModifierKeys modifierKeys, System.Windows.Forms.Keys key, IntPtr windowHandle) 
    { 
     Contract.Requires(modifierKeys != ModifierKeys.None || key != System.Windows.Forms.Keys.None); 
     Contract.Requires(windowHandle != IntPtr.Zero); 

     Key = key; 
     KeyModifier = modifierKeys; 
     _id = GetHashCode(); 
     _handle = windowHandle; 
     RegisterHotKey(); 
     ComponentDispatcher.ThreadPreprocessMessage += ThreadPreprocessMessageMethod; 
    } 

    ~HotKey() 
    { 
     Dispose(); 
    } 

    public System.Windows.Forms.Keys Key { get; private set; } 

    public ModifierKeys KeyModifier { get; private set; } 

    public void RegisterHotKey() 
    { 
     if (Key == System.Windows.Forms.Keys.None) 
      return; 
     if (_isKeyRegistered) 
      UnregisterHotKey(); 
     _isKeyRegistered = HotKeyWinApi.RegisterHotKey(_handle, _id, KeyModifier, Key); 
     if (!_isKeyRegistered) 
      throw new ApplicationException("Hotkey already in use"); 
    } 

    public void UnregisterHotKey() 
    { 
     _isKeyRegistered = !HotKeyWinApi.UnregisterHotKey(_handle, _id); 
    } 

    public void Dispose() 
    { 
     ComponentDispatcher.ThreadPreprocessMessage -= ThreadPreprocessMessageMethod; 
     UnregisterHotKey(); 
    } 

    private void ThreadPreprocessMessageMethod(ref MSG msg, ref bool handled) 
    { 
     if (!handled) 
     { 
      if (msg.message == HotKeyWinApi.WmHotKey 
       && (int)(msg.wParam) == _id) 
      { 
       OnHotKeyPressed(); 
       handled = true; 
      } 
     } 
    } 

    private void OnHotKeyPressed() 
    { 
     if (HotKeyPressed != null) 
      HotKeyPressed(this); 
    } 
} 

internal class HotKeyWinApi 
{ 
    public const int WmHotKey = 0x0312; 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKeys fsModifiers, System.Windows.Forms.Keys vk); 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id); 
} 

的主要应用

private HotKey _hotkey; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     Loaded += (s, e) => 
     { 
      _hotkey = new HotKey(ModifierKeys.Control | ModifierKeys.Shift, System.Windows.Forms.Keys.C, this); 
      _hotkey.HotKeyPressed += (k) => DoIt(); 
     }; 


    } 

    public static void DoIt() 
    { 
     MessageBox.Show("HotKey pressed!"); 
    } 
+0

您是否尝试过使用'KeyBinding'? –

+0

感谢您的快速回答。我试过了,但它没有工作:/ –

+0

你可以发布你尝试过的代码吗? –

回答

0

你应该试试这个博客帖子:Installing a global hot key with C#

至于让选定的文本,你的代码中发现here缺少EM_GETSEL消息获得选择的边界。您可以添加以下代码,它应该工作:

 //Get the text of a control with its handle 
     private string GetText(IntPtr handle) 
     { 
      int maxLength = 100; 
      IntPtr buffer = Marshal.AllocHGlobal((maxLength + 1) * 2); 
      SendMessageW(handle, WM_GETTEXT, maxLength, buffer); 
      int selectionStart = -1; 
      int selectionEnd = -1; 
      SendMessage(handle, EM_GETSEL, out selectionStart, out selectionEnd); 
      string w = Marshal.PtrToStringUni(buffer); 
      Marshal.FreeHGlobal(buffer); 
      if (selectionStart > 0 && selectionEnd >0) 
      { 
       w = w.Substring(selectionStart, selectionEnd - selectionStart); //We need to send the length 
      } 
      return w; 
     } 

    [DllImport("user32.dll")] 
    public static extern int SendMessage(IntPtr hWnd, uint Msg, out int wParam, out int lParam); 

    public const uint EM_GETSEL = 0xB0; 
+0

感谢您的帮助!热键不是“真正的”问题。我已经做了一个功能热键,但在连接与标记的对象是问题...如果热键被激活我如何得到选定的对象? (这2件事情在一起是我的问题^^) 我希望你明白我的意思(我的英语不好XD) –

+0

它现在的作品oO ..但不是100%正确... http://social.msdn。 microsoft.com/Forums/windows/en-US/1dc356e6-9441-44de-9eda-247003fa6ef5/copy-selected-text-from-any-window?forum=winformsapplications我试过这个,但我怎么只得到选定的文字,而不是全文? –

+0

链接上的代码缺少EM_GETSEL消息以获取选择边界。 –