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!");
    }
4

1 に答える 1

0

次のブログ投稿を試してみてください: C# を使用したグローバル ホット キーのインストール

選択したテキストの取得に関しては、ここで見つけたコードには、選択境界を取得するための 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;
于 2014-02-17T16:27:54.383 に答える