我是靠谱客的博主 热情斑马,最近开发中收集的这篇文章主要介绍C# 操作Clipboard,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

C#定义了一个类System.Windows.Forms.Clipboard来简化剪切板操作,这个类有一个静态方法,主要有:

Clear 清除剪切板中的所有数据;

ContainsData,ContainsAudio,ContainsFlieDropList,ContainsText,ContainsImage,用于检查剪切板中是否存在相应的数据;

GetAudioStream,GetDataObject,GetText,GetImage,GetFileDropList,用于取得数据;

SetAudio,SetDataObject,SetText,SetImage,SetFileDropList,用于添加数据;

以下是检测剪切板的方法:

一、引入

要使用剪切板首先要引入三个函数,

        [System.Runtime.InteropServices.DllImport("user32")]

        private static extern IntPtr SetClipboardViewer(IntPtr hwnd);

        [System.Runtime.InteropServices.DllImport("user32")]

        private static extern IntPtr ChangeClipboardChain(IntPtr hwnd,IntPtr hWndNext);

        [System.Runtime.InteropServices.DllImport("user32")]

        private static extern int SendMessage(IntPtr hwnd,int wMsg,IntPtr wParam,IntPtr lParam);

        const int WM_DRAWCLIPBOARD = 0x308;

        const int WM_CHANGECBCHAIN = 0x30D;

IntPtr SetClipboardViewer(IntPtr hwnd) 用于往观察链中添加一个窗口句柄,这个窗口就可成为观察链中的一员了,返回值指向下一个观察者。

IntPtr ChangeClipboardChain(IntPtr hwnd,IntPtr hWndNext); 删除由hwnd指定的观察链成员,这是一个窗口句柄,第二个参数hWndNext是观察链中下一个窗口的句柄

int SendMessage(IntPtr hwnd,int wMsg,IntPtr wParam,IntPtr lParam); 发送消息

二、使用

定义完成之后,可以分三部来使用,第一步把自己的窗口添加到观察链中成为观察者,并保存下一个观察者的句柄;第二步监视剪切板,并把剪切板变化的消息发送给下一个观察者;第三步撤消自己定义的观察者,并通知下一个观察者。

第一步:把自己的窗口添加到观察链中成为观察者,并保存下一个观察者的句柄;

//存放观察链中下一个窗口句柄   

IntPtr NextClipHwnd;

private void Form1_Load(object sender, System.EventArgs e)

{  

     //获得观察链中下一个窗口句柄

    NextClipHwnd=SetClipboardViewer(this.Handle);           

}

第二步:监视剪切板,并把剪切板变化的消息发送给下一个观察者,这里需要重载WndProc方法;

这里用到两个消息常量:

   const int WM_DRAWCLIPBOARD = 0x308;

   const int WM_CHANGECBCHAIN = 0x30D;

protected override void WndProc(ref System.Windows.Forms.Message m)

{

    switch(m.Msg)

    {

        case WM_DRAWCLIPBOARD:

            //将WM_DRAWCLIPBOARD消息传递到下一个观察链中的窗口

            SendMessage(NextClipHwnd,m.Msg,m.WParam,m.LParam);

            IDataObject iData = Clipboard.GetDataObject();

              //检测文本

            if(iData.GetDataPresent(DataFormats.Text)|iData.GetDataPresent(DataFormats.OemText))

            {

                     this.richTextBox1.Text=(String)iData.GetData(DataFormats.Text);

            }

             //检测图像

             if (iData.GetDataPresent(DataFormats.Bitmap))

              {

                        pictureBox1.Image=Clipboard.GetImage();

                        NewClipData();

              }

              //检测自定义类型

               if (iData.GetDataPresent("myFormat"))

                {

                        MyObj myobj=(MyObj)iData.GetData("myFormat");

                        this.richTextBox1.Text=myobj.ObjName;

                }

              break;

        default:

            base.WndProc(ref m);

            break;

    }       

}

第三步:撤消自己定义的观察者,并通知下一个观察者。

private void Form1_Closed(object sender, System.EventArgs e)

{

            //从观察链中删除本观察窗口(第一个参数:将要删除的窗口的句柄;第二个参数://观察链中下一个窗口的句柄 )

           ChangeClipboardChain(this.Handle,NextClipHwnd);

            //将变动消息WM_CHANGECBCHAIN消息传递到下一个观察链中的窗口

            SendMessage(NextClipHwnd,WM_CHANGECBCHAIN,this.Handle,NextClipHwnd);  

}

三、扩展

DataFormats类定义了剪切板内容的几种格式,包括Text,UnicodeText,OemText,Rtf,Html,Dib,Bitmap等,但自己可以定义新的数据格式,代码如下 :

    //新类

    public class MyObj

    {

        private string objName;

        public MyObj()

        {

            objName = "自定义剪切板内容";

        }

        public string ObjName

        {

            get { return objName; }

        }

    }

        //往剪切板中添加一个自定义内容

        private void NewClipData()

        {

            DataFormats.Format myFormat = DataFormats.GetFormat("myFormat");

            MyObj myobj = new MyObj();

            DataObject myDataObject = new DataObject("myFormat", myobj);

            Clipboard.SetDataObject(myDataObject);

        }

其中myFormat就是自定义数据格式的名称,

在上面的WinProc中可以看到

             //检测图像

             if (iData.GetDataPresent(DataFormats.Bitmap))

              {

                        pictureBox1.Image=Clipboard.GetImage();

                        NewClipData();

              }

检测到剪切板中有图像内容时,就显示这个图像,然后,调用NewClipData(),产生一个新剪切板数据,其格式是自定义的myFormat,这时,程序会通过下面这段代码来检测到这个变化,并处理

              //检测自定义类型

               if (iData.GetDataPresent("myFormat"))

                {

                        MyObj myobj=(MyObj)iData.GetData("myFormat");

                        this.richTextBox1.Text=myobj.ObjName;

                }

 

Clipboard就是所谓的剪切板,当我们同时按动Ctrl+C键或者点击菜单“拷贝”的时候,选定的对象就被存放在了剪切板中了。如果刚才选定的对象是文件,那么在定盘符后,按动Ctrl+V键或者点击菜单“粘贴”,这时选定的文件就保存到指定的磁盘上面了;如果选定的对象是图象,那么在打开“画图”之后,按动Ctrl+V键或者点击菜单“粘贴”,图象就会显示在画图中了;如果是文本,那么在打开文本编辑器后,按动Ctrl+V键或者点击菜单“粘贴”,这时文本就会显示在文本编辑器中。当然选定的对象还有许多种,这就不一一举例了。上面这些操作其实就是剪切板几种典型的操作。那么这些操作如果用Visual C#来实现到底是个什么样子?本文就将通过一个程序来具体探讨这个问题。

一.本文程序设计和运行的软件环境
(1).微软公司视窗2000服务器版
(2)..Net FrameWork SDK Beta 2
二.程序的主要功能以及运行界面
其实看了上面的介绍以后,我们不难得出剪切板的几种基本的操作,即:拷贝数据到剪
切板中、把当前剪切板中的数据取出来。下面就按照这些操作来编写一个程序。这个程序主窗体是由二个TextBox组件即TextBox1和TextBox2,和二个Button组件构成。实现的功能是当选定TextBox1的文本后,按动“拷贝指定的数据到剪切板”按钮,拷贝数据到剪切板中,然后按动“从当前剪切板获得数据”按钮得到剪切板中的数据,并由TextBox2显示出来.

 

 

 

 

 

 

 

 

三.程序的设计思路以及重要步骤地解决办法
(1).如何把指定对象拷贝到剪切板中:
在这个环节中要处理好二件问题:其一是如何判断是否选定了TextBox1中的对象,其二是如何把选定的对象存放到剪切板中。下面就带着这二个问题来进行分析。
I > .如何判断TextBox1中是否选定了对象:
对于TextBox组件中有一个属性SelectedText,这个属性就是选定的文本,在程序中是通过判断这个属性值是否为“”,来判断TextBox1中是否选定了对象的。
II > .如何把选定的对象存放到剪切板中:
要完成此功能,要使用到中的Clipboard类,Clipboard类是一个封闭的类,这决定了他无法被继承,此类的主要功能就是存取剪切板中的数据。他有一个方法SetDataObject(),这个方法的作用就是把数据存放到剪切板中。
解决上面二个问题的代码如下:
if ( textBox1.SelectedText != "" )
Clipboard.SetDataObject ( textBox1.SelectedText ) ;
else
textBox2.Text = "在textBox1中没有选定的内容" ;
(2).把读取剪切板中的数据,并显示出来。
要实现本步骤,也需要解决好二个问题:其一,在剪切板中不仅可以存放文本,还可以存放其他类型的数据,而TextBox2能够显示出来的数据类型只有文本,所以为了程序有更好的稳定性,在显示之前,要判断当前剪切板中的数据类型是文本,其二,读取剪切板中的数据,并显示出来。
I > .判断当前剪切板中的数据类型:
判断剪切板中的数据类型,要使用到IdataObject接口,此接口的可以存放从剪切板中读取得数据。通过IdataObject接口的方法GetDataPresent()来判断是否为符合自己需要的数据类型。
II >.读取剪切板中的数据,并显示出来:
通过Clipboard类的GetDataObject()可以把当前剪切板中的数据存放到IdataObject接口中,但IdataObject接口这地数据不能直接被程序使用,必须通过IdataObject接口的GetData()获得数据。但由于GetData()地返回值是一个Object类型变量,即参考类型变量,而TextBox1显示的文本是实值类型变量,所以还要进行一次出箱的操作,这种操作在前面的文章已经比较详细的介绍过了,这里就不加叙述了。经过出箱操作后的数据就可以被TextBox1使用了。下面是解决上面二个问题的代码:
IDataObject iData = Clipboard.GetDataObject ( ) ;
//检测数据是否是可以使用的格式,即文本格式
if ( iData.GetDataPresent ( DataFormats.Text ) )
{
//是可以使用的格式,就在textbox2中显示剪切板中的内容
textBox2.Text = ( String ) iData.GetData ( DataFormats.Text ) ;
}
else
{
//如果不是
textBox2.Text = "没有从剪切板中接收到数据!" ;
}
四.本文的源程序代码
掌握了程序的主要步骤后,不难得到以下程序代码:
using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
 
public class Form1 : Form
{
private Button button1 ;
private Button button2 ;
private TextBox textBox1 ;
private TextBox textBox2 ;
private System.ComponentModel.Container components = null ;
public Form1 ( )
{
InitializeComponent ( ) ;
}
 
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
 
private void InitializeComponent ( )
{
this.button1 = new Button ( ) ;
this.button2 = new Button ( ) ;
this.textBox1 = new TextBox () ;
this.textBox2 = new TextBox ( ) ;
this.SuspendLayout ( ) ;
 
this.button1.Location = new System.Drawing.Point ( 264 , 56 ) ;
this.button1.Size = new System.Drawing.Size ( 96 , 40 ) ;
this.button1.Name = "button1" ;
this.button1.TabIndex = 0 ;
this.button1.Text = "拷贝指定的数据到剪切板" ;
this.button1.Click += new System.EventHandler ( this.button1_Click ) ;
 
this.button2.Location = new System.Drawing.Point ( 264 , 104 ) ;
this.button2.Size = new System.Drawing.Size ( 96 , 40 ) ;
this.button2.Name = "button2" ;
this.button2.TabIndex = 1 ;
this.button2.Text = "从当前剪切板获得数据" ;
this.button2.Click += new System.EventHandler ( this.button2_Click ) ;
 
this.textBox1.Location = new System.Drawing.Point ( 64 , 64 ) ;
this.textBox1.Name = "textBox1" ;
this.textBox1.TabIndex = 2 ;
this.textBox1.Text = "" ;
 
this.textBox2.Location = new System.Drawing.Point ( 64 , 104 ) ;
this.textBox2.Name = "textBox2" ;
this.textBox2.TabIndex = 3 ;
this.textBox2.Text = "" ;
 
this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;
this.ClientSize = new System.Drawing.Size ( 384 , 273 ) ;
this.Controls.Add ( textBox2 ) ;
this.Controls.Add ( textBox1 ) ;
this.Controls.Add ( button2 ) ;
this.Controls.Add ( button1 ) ;
this.Name = "Form1" ;
this.Text = "Visual C#来操作Clipboard!" ;
this.ResumeLayout ( false ) ;
 
}
 
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}
 
private void button1_Click ( object sender , System.EventArgs e )
{
if ( textBox1.SelectedText != "" )
Clipboard.SetDataObject ( textBox1.SelectedText ) ;
else
textBox2.Text = "在textBox1中没有选定的内容";
}
 
private void button2_Click ( object sender , System.EventArgs e )
{
IDataObject iData = Clipboard.GetDataObject ( ) ;
//检测数据是否是可以使用的格式,即文本格式
if ( iData.GetDataPresent ( DataFormats.Text ) )
{
//是可以使用的格式,就在textbox2中显示剪切板中的内容
textBox2.Text = ( String ) iData.GetData ( DataFormats.Text ) ;
}
else
{
//如果不是
textBox2.Text = "没有从剪切板中接收到数据!" ;
}
 
}
}
五.总结
至此我们已经完成了用Visual C#实现剪切板基本操作的全部工作,这就是拷贝数据到剪切板、读取剪切板中需要的数据、显示剪切板中的数据等三个方面。其中又以前二个方面的内容最为重要。虽然以上这些操作和处理针对的对象都是文本,但实际对于其他类型的对象也是一样,只需要做少许修改就可以了,不信你试一下。

最后

以上就是热情斑马为你收集整理的C# 操作Clipboard的全部内容,希望文章能够帮你解决C# 操作Clipboard所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部