Here is what im trying to do: There is some game which writes some info about item under mouse cursor into clipboard when i press Ctrl-C. Im trying to grab that info and select some stuff i need from it. Im doing it like this:
//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);
}
So basically, when i press Ctrl-C in-game without this program on - all works fine, info copied in clipboard. When i turn program on - clipboard stays same as it was before i press Ctrl-C in-game. How do i prevent this? How do i get text from clipboard correctly? Maybe the way i get this text is wrong? Or maybe that registered hotkey interferes with game hotkey so it doesn't work anymore?
update: Ive figured out some simple solution, but very rough and barbaric. But it works fine.
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);
}
Maybe there is more clever way to solve this problem?
I would use a ClipBoard monitor so you can get notified whenever the ClipBoard changes:
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);
}
}
}