启动复制/粘贴事件不起作用

时间:2013-05-25 15:45:05

标签: c# multithreading clipboard

[CODE CONTEXT]

大家好,

我正在开发一个应用程序,它通过发送键盘事件来按下键C和Ctrl来启动复制或粘贴事件。

我实际上有这种方法来发送Kb事件:

[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);

public static void PressKey(Keys key, bool up)
{
    const int KEYEVENTF_EXTENDEDKEY = 0x1;
    const int KEYEVENTF_KEYUP = 0x2;
    if (up)
    {
        keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
    }
    else
    {
        keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
    }
}

呼叫:

private void launchCopy()
{
    PressKey(Keys.ControlKey, false);
    PressKey(Keys.C, false);
    PressKey(Keys.C, true);
    PressKey(Keys.ControlKey, true);
}

并使用静态方法获取结果:

System.Windows.Forms.Clipboard.GetText()

用户必须使用鼠标按其他键以启动此事件,因此我使用SFML使用SFML 2.0中的函数Keyboard.IsKeyPressed(Keyboard.Key key);取回用户操作。

我创建了一个等待用户事件的无限循环,然后在复制数据上启动复制和处理。 此代码正常 然后我用一些窗口创建了另一个WPF解决方案,我正在使用NotifyIcon。 加载后,主窗口创建一个带有循环方法的线程(在用户事件上 - > launchCopy)。

[DEBUG]

当用户按下复制事件时,将调用PressKey方法,但ClipBoard.GetText ()方法返回空字符串。 使用SFML我检查了是否真的按下了键

  private void PrintState ()
  {
    Console.WriteLine(Keyboard.IsKeyPressed(Keyboard.Key.C)  &&
                      (Keyboard.IsKeyPressed(Keyboard.Key.LControl) ||
                       Keyboard.IsKeyPressed(Keyboard.Key.RControl)));
  }

private void launchCopy()
{
    PrintState ();
    PressKey(Keys.ControlKey, false);
    PressKey(Keys.C, false);
    PrintState ();
    PressKey(Keys.C, true);
    PressKey(Keys.ControlKey, true);
    PrintState ();
}

输出是:

  

False True False

就像它应该......

[问题]

为什么快捷方式复制模拟不适用于此应用程序? 从工作代码I:

  • 将代码放在另一个线程
  • 1其他线程但相同的应用程序:WPF windows + NotifyIcon 文库

是否有可能与WPF混淆? 或者在另一个线程中使用PrintState方法的问题?

我迷失了即将调试此事。

任何帮助或想法都将不胜感激

感谢。

1 个答案:

答案 0 :(得分:0)

永远不会太晚。

此问题已由thread解决,发送事件不是,问题是检索剪贴板数据。

这是我用来从另一个线程使用剪贴板的代码:

public static class fastClipboard
{
        [DllImport("user32.dll")]
        static extern IntPtr GetClipboardData(uint uFormat);
        [DllImport("user32.dll")]
        static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
        [DllImport("user32.dll")]
        static extern bool IsClipboardFormatAvailable(uint format);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool CloseClipboard();
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        static extern bool GlobalUnlock(IntPtr hMem);

        const uint CF_UNICODETEXT = 13;

        public static bool SetText(string data)
        {
            if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
                return false;
            if (!OpenClipboard(IntPtr.Zero))
                return false;

            var ptr = Marshal.StringToHGlobalUni(data);
            var res = SetClipboardData(CF_UNICODETEXT, ptr);
            CloseClipboard();
            if (res != IntPtr.Zero)
                return true;
            else
                return false;
        }

        public static string GetText()
        {
            if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
                return null;
            if (!OpenClipboard(IntPtr.Zero))
                return null;

            string data = null;
            var hGlobal = GetClipboardData(CF_UNICODETEXT);
            if (hGlobal != IntPtr.Zero)
            {
                var lpwcstr = GlobalLock(hGlobal);
                if (lpwcstr != IntPtr.Zero)
                {
                    data = Marshal.PtrToStringUni(lpwcstr);
                    GlobalUnlock(lpwcstr);
                }
            }
            CloseClipboard();
            return data;
        }
    }