Clipboard.GetText覆盖剪贴板? [英] Clipboard.GetText overrides clipboard?

查看:241
本文介绍了Clipboard.GetText覆盖剪贴板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我尝试做的事:
有一些游戏,当我按下Ctrl-C光标下写一些信息有关的项目到剪贴板。我试着去抓住这些信息,并选择一些东西,我从它的需要。
Im做这样的:

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



所以基本上,当我按下Ctrl-C在游戏中没有这个项目上 - 一切工作正常,信息剪贴板复制。当我打开程序 - 剪贴板保持相同的,因为这是我以前在游戏中按下Ctrl-C。我如何防止?我如何正确地得到剪贴板中的文本?也许我得到这个文本的方式是错误的? ?或者,也许已注册热键与游戏热键干扰所以它不工作了。

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

    }

}

这篇关于Clipboard.GetText覆盖剪贴板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆