Clipboard.GetText会覆盖剪贴板吗?

这就是我想要做的事情:当我按下Ctrl-C时,有一些游戏会将鼠标光标下的项目信息写入剪贴板。 我试图抓住这些信息并从中选择一些我需要的东西。 我这样做:

//at form load RegisterHotKey(this.Handle, 0, 0x002, (int)Keys.C); protected override void WndProc(ref Message m) { if (m.Msg == 0x0312) { int id = m.WParam.ToInt32(); if (id == 0) { System.Threading.Thread.Sleep(155); //ive thought if i add some delay it would help but it doesnt... string textFromClipboard = Clipboard.GetText(); if (textFromClipboard.Contains("Itemlevel: ")) { // do some stuff with data IF it exists in clipboard, doesnt important what i do - i never get here } } } base.WndProc(ref m); } 

所以基本上,当我在没有这个程序的情况下在游戏中按Ctrl-C – 一切正常,信息在剪贴板中复制。 当我打开程序时 – 剪贴板保持与我在游戏中按Ctrl-C之前相同。 我该如何防止这种情况? 如何正确地从剪贴板中获取文本? 也许我得到这个文字的方式是错的? 或者这个注册的热键可能会干扰游戏热键,所以它不再起作用了?

更新:我已经找到了一些简单的解决方案,但非常粗糙和野蛮。 但它运作正常。

  public static void KeyDown(System.Windows.Forms.Keys key) { keybd_event((byte)key, 0x45, 0x0001 | 0, 0); } public static void KeyUp(System.Windows.Forms.Keys key) { keybd_event((byte)key, 0x45, 0x0001 | 0x0002, 0); } protected override void WndProc(ref Message m) { if (m.Msg == 0x0312) { int id = m.WParam.ToInt32(); if (id == 0) { ToggleHotkeys(false); KeyDown(Keys.Control); KeyDown(Keys.C); KeyUp(Keys.C); KeyUp(Keys.Control); System.Threading.Thread.Sleep(155); //if i comment this sleep - code executes too fast, making first Ctrl-C press //capture nothing, second press outputs results for first item //third press - for second item, ... string textFromClipboard = Clipboard.GetText(); if (textFromClipboard.Contains("Itemlevel: ")) { //do stuff with data } ToggleHotkeys(true); } } base.WndProc(ref m); } 

也许有更聪明的方法来解决这个问题?

我会使用ClipBoard监视器,以便在ClipBoard更改时收到通知:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private ClipBoardMonitor cbm = null; public Form1() { InitializeComponent(); cbm = new ClipBoardMonitor(); cbm.NewText += cbm_NewText; } private void cbm_NewText(string txt) { Console.WriteLine(txt); } } public class ClipBoardMonitor : NativeWindow { private const int WM_DESTROY = 0x2; private const int WM_DRAWCLIPBOARD = 0x308; private const int WM_CHANGECBCHAIN = 0x30d; [DllImport("user32.dll")] static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); [DllImport("user32.dll")] static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); public event NewTextEventHandler NewText; public delegate void NewTextEventHandler(string txt); private IntPtr NextClipBoardViewerHandle; public ClipBoardMonitor() { this.CreateHandle(new CreateParams()); NextClipBoardViewerHandle = SetClipboardViewer(this.Handle); } protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_DRAWCLIPBOARD: if (Clipboard.ContainsText()) { if (NewText != null) { NewText(Clipboard.GetText()); } } SendMessage(NextClipBoardViewerHandle, m.Msg, m.WParam, m.LParam); break; case WM_CHANGECBCHAIN: if (m.WParam.Equals(NextClipBoardViewerHandle)) { NextClipBoardViewerHandle = m.LParam; } else if (!NextClipBoardViewerHandle.Equals(IntPtr.Zero)) { SendMessage(NextClipBoardViewerHandle, m.Msg, m.WParam, m.LParam); } break; case WM_DESTROY: ChangeClipboardChain(this.Handle, NextClipBoardViewerHandle); break; } base.WndProc(ref m); } } }