简体   繁体   中英

Clipboard.GetText overrides clipboard?

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);
        }

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM