大家好,
我正在开发一个应用程序,它通过发送键盘事件来按下键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)。
当用户按下复制事件时,将调用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:
是否有可能与WPF混淆?
或者在另一个线程中使用PrintState
方法的问题?
我迷失了即将调试此事。
任何帮助或想法都将不胜感激
感谢。
答案 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;
}
}