ClipboardSpy剪切板内容查验

clipboard.png

实现步骤:
1、检查剪切板上是否有对应的格式,是的话CheckBox打勾

private void CheckStatus(object sender, RoutedEventArgs args)
{
    cbContainsAudio.IsChecked = Clipboard.ContainsAudio();
    cbContainsFileDropList.IsChecked = Clipboard.ContainsFileDropList();
    cbContainsImage.IsChecked = Clipboard.ContainsImage();
    cbContainsText.IsChecked = Clipboard.ContainsText();
}

2、获取剪切板上内容:

  1. 获取剪切板的数据对象
  2. 处理剪切板的数据:

    1. 判断是否数据对象为空,不为空则》
    2. 获取数据对象的格式集合DataObject.GetFormats,返回string[]
    3. 循环格式集合,获取对应格式的数据内容DataObject.GetData()
private void GetClipboard(object sender, RoutedEventArgs args)
{
    _dataObject = Clipboard.GetDataObject();
    CheckCurrentDataObject();
}
private void CheckCurrentDataObject()
{
    CheckStatus(null, null);

    tbInfo.Clear();

    if (_dataObject == null)
    {
        tbInfo.Text = "DataObject is null.";
    }
    else
    {
        tbInfo.AppendText("Clipboard DataObject Type: ");
        tbInfo.AppendText(_dataObject.GetType().ToString());

        tbInfo.AppendText("\n\n****************************************************\n\n");

        var formats = _dataObject.GetFormats();

        tbInfo.AppendText(
            "The following data formats are present in the data object obtained from the clipboard:\n");

        if (formats.Length > 0)
        {
            foreach (var format in formats)
            {
                if (_dataObject.GetDataPresent(format, false))
                    tbInfo.AppendText("\t- " + format + " (native)\n");
                else tbInfo.AppendText("\t- " + format + " (autoconvertable)\n");
            }
        }
        else tbInfo.AppendText("\t- no data formats are present\n");

        foreach (var format in formats)
        {
            tbInfo.AppendText("\n\n****************************************************\n");
            tbInfo.AppendText(format + " data:\n");
            tbInfo.AppendText("****************************************************\n\n");
            tbInfo.AppendText(_dataObject.GetData(format, true).ToString());
        }
    }

ps:有个bug:如对文件资源管理器中 展开 zip文件时,选择复制右侧压缩文件下的(文件夹或文件)时,本程序点击获取剪切板内容时,报错为内存溢出。推测是资源管理器展示(非双击打开)的zip内容 与剪切板数据不兼容


ClipbordViewer剪切板展示

clipboard.png

关注点:
1、从RichTextBox中获取指定数据格式(text,dataFomat)的数据内容:

  1. 使用TextRange获取到RichTextBox.Document头尾的文本,如只要Text格式,直接返回TextRange.Text。
  2. 使用内存流MemoryStream,保存TextRange.Save以指定格式dataFomat,初始字节组byte[],读取内存流的内容到字节组里,以UTF8的格式化字节组返回string[]数据。
// Get text data string from RichTextBox content which encoded as UTF8
        private string GetTextStringFromRichTextBox(string dataFormat)
{
    var document = richTextBox.Document;
    var textRange = new TextRange(document.ContentStart, document.ContentEnd);

    if (dataFormat == DataFormats.Text)
    {
        return textRange.Text;
    }
    Stream contentStream = new MemoryStream();
    textRange.Save(contentStream, dataFormat);

    if (contentStream.Length > 0)
    {
        var bytes = new byte[contentStream.Length];

        contentStream.Position = 0;
        contentStream.Read(bytes, 0, bytes.Length);

        var utf8Encoding = Encoding.UTF8;

        return utf8Encoding.GetString(bytes);
    }

    return null;
}

2、在DataObject中保持自定义格式的数据内容:

  1. 初始化内存流
  2. 获取字符串,其中包含从RichTextBox返回的文本数据。
  3. Encoding.GetBytes()指定一组字符编码为一个字节序列
  4. 把以上字节组编码为UTF8保存到内存流,
  5. 把内存流与自定义格式名,一起放入数据对象中
// Finally, consider a custom, application defined format.
// We use an arbitrary encoding here, for demonstration purposes.
if ((bool) cbCustomSampleDataFormat.IsChecked)
{
    Stream customStream = new MemoryStream();

    var textData = "This is Custom Sample Data Start\n\n" +
                   GetTextStringFromRichTextBox(DataFormats.Text) +
                   "\nCustom Sample Data End.";

    var bytesUnicode = Encoding.Unicode.GetBytes(textData);
    var bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytesUnicode);

    if (bytes.Length > 0)
    {
        customStream.Write(bytes, 0, bytes.Length);
        dataObject.SetData("CustomSample", customStream);
    }
}

3、从文件中复制数据到DataObject中:

// Set the selected data format's data from the file content 
// into DataObject for copying data on the system clipboard
private void CopyDataFromFile(IDataObject dataObject)
{
    string fileName = null;

    var dialog = new OpenFileDialog {CheckFileExists = true};

    if ((bool) cbCopyTextDataFormat.IsChecked)
    {
        dialog.Filter = "Plain Text (*.txt)|*.txt";
        dialog.ShowDialog();
        fileName = dialog.FileName;

        if (string.IsNullOrEmpty(fileName))
        {
            return;
        }

        var fileEncoding = Encoding.Default;
        var textData = GetTextStringFromFile(fileName, fileEncoding);
        if (!string.IsNullOrEmpty(textData))
        {
            dataObject.SetData(DataFormats.Text, textData);
        }
    }

    if ((bool) cbCopyRtfDataFormat.IsChecked)
    {
        fileName = null;
        dialog.Filter = "RTF Documents (*.rtf)|*.rtf";
        dialog.ShowDialog();
        fileName = dialog.FileName;

        if (string.IsNullOrEmpty(fileName))
        {
            return;
        }

        var fileEncoding = Encoding.ASCII;
        var textData = GetTextStringFromFile(fileName, fileEncoding);
        if (!string.IsNullOrEmpty(textData))
        {
            dataObject.SetData(DataFormats.Rtf, textData);
        }
    }

    if ((bool) cbCopyXamlDataFormat.IsChecked)
    {
        fileName = null;
        dialog.Filter = "XAML Flow Documents (*.xaml)|*.xaml";
        dialog.ShowDialog();
        fileName = dialog.FileName;

        if (string.IsNullOrEmpty(fileName))
        {
            return;
        }

        var fileEncoding = Encoding.UTF8;
        var textData = GetTextStringFromFile(fileName, fileEncoding);
        if (!string.IsNullOrEmpty(textData))
        {
            dataObject.SetData(DataFormats.Xaml, textData);
        }
    }

    // Finally, consider a custom, application defined format.
    // We use an arbitrary encoding here, for demonstartion purposes.
    if ((bool) cbCustomSampleDataFormat.IsChecked)
    {
        fileName = null;
        dialog.Filter = "All Files (*.*)|*.*";
        dialog.ShowDialog();
        fileName = dialog.FileName;

        if (string.IsNullOrEmpty(fileName))
        {
            return;
        }

        var fileEncoding = Encoding.UTF8;
        var textData = GetTextStringFromFile(fileName, fileEncoding);
        if (string.IsNullOrEmpty(textData)) return;
        var bytesUnicode = Encoding.Unicode.GetBytes(textData);
        var bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytesUnicode);

        if (bytes.Length > 0)
        {
            var customStream = new MemoryStream();
            customStream.Write(bytes, 0, bytes.Length);
            dataObject.SetData("CustomSample", customStream);
        }
    }
}

4、从文件中读取数据到string中

  1. 使用文件流FileStream打开文件全名
  2. 设置此流的当前位置Position=0
  3. FileStream.Read到字节组。
  4. 根据字符编码格式转换.Encoding。GetString()字节组为string
  5. 关闭流,返回字符串
// Get text data string from file content with the proper encoding
private string GetTextStringFromFile(string fileName, Encoding fileEncoding)
{
    string textString = null;

    FileStream fileStream;

    try
    {
        fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    }
    catch (IOException)
    {
        MessageBox.Show("File is not acessible.\n", "File Open Error");
        return null;
    }

    fileStream.Position = 0;

    var bytes = new byte[fileStream.Length];

    fileStream.Read(bytes, 0, bytes.Length);

    if (bytes.Length > 0)
    {
        textString = fileEncoding.GetString(bytes);
    }

    fileStream.Close();

    return textString;
}

5、 从剪切板黏贴数据对象到RichTextBox中:

// Paste a selected paste data format's data to RichTextBox
private void PasteClipboardDataToRichTextBox(string dataFormat, IDataObject dataObject, bool autoConvert)
{
    if (dataObject != null && dataObject.GetFormats().Length > 0)
    {
        var pasted = false;

        if (dataFormat == DataFormats.Xaml)
        {
            var xamlData = dataObject.GetData(DataFormats.Xaml) as string;
            if (!string.IsNullOrEmpty(xamlData))
            {
                pasted = PasteTextDataToRichTextBox(DataFormats.Xaml, xamlData);
            }
        }
        else if (dataFormat == DataFormats.Rtf)
        {
            var rtfData = dataObject.GetData(DataFormats.Rtf) as string;
            if (!string.IsNullOrEmpty(rtfData))
            {
                pasted = PasteTextDataToRichTextBox(DataFormats.Rtf, rtfData);
            }
        }
        else if (dataFormat == DataFormats.UnicodeText
                 || dataFormat == DataFormats.Text
                 || dataFormat == DataFormats.StringFormat)
        {
            var textData = dataObject.GetData(dataFormat) as string;
            if (textData != string.Empty)
            {
                SetTextOnRichTextBox(textData);
                pasted = true;
            }
        }
        else if (dataFormat == "CustomSample")
        {
            // Paste the application defined custom data format's data to RichTextBox content
            var customStream = dataObject.GetData(dataFormat, autoConvert) as Stream;
            if (customStream.Length > 0)
            {
                var textRange = new TextRange(richTextBox.Document.ContentStart,
                    richTextBox.Document.ContentEnd);
                textRange.Load(customStream, DataFormats.Text);
                pasted = true;
            }
        }

        if (!pasted)
        {
            MessageBox.Show(
                "Can't paste the selected data format into RichTextBox!\n\nPlease click Refresh button to update the current clipboard format Or select File RadioButton to paste data.",
                "Paste Data Format Error",
                MessageBoxButton.OK,
                MessageBoxImage.Exclamation);
        }
    }
}
// Paste text data on RichTextBox as UTF8 encoding
private bool PasteTextDataToRichTextBox(string dataFormat, string textData)
{
    var pasted = false;

    var document = richTextBox.Document;
    var textRange = new TextRange(document.ContentStart, document.ContentEnd);

    Stream stream = new MemoryStream();

    var bytesUnicode = Encoding.Unicode.GetBytes(textData);
    var bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytesUnicode);

    if (bytes.Length > 0 && textRange.CanLoad(dataFormat))
    {
        stream.Write(bytes, 0, bytes.Length);
        textRange.Load(stream, dataFormat);
        pasted = true;
    }

    return pasted;
}

6、黏贴剪切板数据对象到文件中:

// Paste a selected paste data format's data to the fileSSS
private void PasteClipboardDataToFile(string dataFormat, IDataObject dataObject, bool autoConvert)
{
    var dialog = new SaveFileDialog {CheckFileExists = false};

    if (dataFormat == DataFormats.Text
        || dataFormat == DataFormats.UnicodeText
        || dataFormat == DataFormats.StringFormat)
    {
        dialog.Filter = "Plain Text (*.txt)|*.txt | All Files (*.*)|*.*";
    }
    else if (dataFormat == DataFormats.Xaml)
    {
        dialog.Filter = "XAML Flow Documents (*.xaml)|*.xaml | All Files (*.*)|*.*";
    }
    else if (dataFormat == DataFormats.Rtf)
    {
        dialog.Filter = "RTF Documents (*.rtf)|*.rtf | All Files (*.*)|*.*";
    }
    else
    {
        dialog.Filter = "All Files (*.*)|*.*";
    }

    if (!(bool) dialog.ShowDialog())
    {
        return;
    }

    var fileName = dialog.FileName;

    if (dataFormat == DataFormats.Xaml)
    {
        var xamlData = dataObject.GetData(DataFormats.Xaml) as string;
        if (!string.IsNullOrEmpty(xamlData))
        {
            PasteTextDataToFile(dataFormat, xamlData, fileName, Encoding.UTF8);
        }
    }
    else if (dataFormat == DataFormats.Rtf)
    {
        var rtfData = dataObject.GetData(DataFormats.Rtf) as string;
        if (!string.IsNullOrEmpty(rtfData))
        {
            PasteTextDataToFile(dataFormat, rtfData, fileName, Encoding.ASCII);
        }
    }
    else if (dataFormat == DataFormats.UnicodeText
             || dataFormat == DataFormats.Text
             || dataFormat == DataFormats.StringFormat)
    {
        var textData = dataObject.GetData(dataFormat, autoConvert) as string;
        if (!string.IsNullOrEmpty(textData))
        {
            PasteTextDataToFile(dataFormat, textData, fileName,
                dataFormat == DataFormats.Text ? Encoding.Default : Encoding.Unicode);
        }
    }
    else
    {
        // Paste the CustomSample data or others to the file
        //Stream customStream = dataObject.GetData(dataFormat, autoConvert) as Stream;
        var customStream = GetDataFromDataObject(dataObject, dataFormat, autoConvert) as Stream;
        if (customStream != null && customStream.Length > 0)
        {
            PasteStreamDataToFile(customStream, fileName);
        }
    }
}
// Paste text data to the file with the file encoding
private void PasteTextDataToFile(string dataFormat, string textData, string fileName, Encoding fileEncoding)
{
    FileStream fileWriteStream;

    try
    {
        fileWriteStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
    }
    catch (IOException)
    {
        MessageBox.Show("File is not acessible.\n", "File Write Error");
        return;
    }

    fileWriteStream.SetLength(0);

    var bytesUnicode = Encoding.Unicode.GetBytes(textData);
    var bytes = Encoding.Convert(Encoding.Unicode, fileEncoding, bytesUnicode);

    if (bytes.Length > 0)
    {
        fileWriteStream.Write(bytes, 0, bytes.Length);
    }

    fileWriteStream.Close();
}

// Paste stream data to the file
private void PasteStreamDataToFile(Stream stream, string fileName)
{
    FileStream fileWriteStream = null;

    try
    {
        fileWriteStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
    }
    catch (IOException)
    {
        MessageBox.Show("File is not acessible.\n", "File Write Error");
    }

    fileWriteStream.SetLength(0);

    var bytes = new byte[stream.Length];

    stream.Position = 0;
    stream.Read(bytes, 0, bytes.Length);

    if (bytes.Length > 0)
    {
        fileWriteStream.Write(bytes, 0, bytes.Length);
    }

    fileWriteStream.Close();
}
}

李志玮
22 声望34 粉丝

求索~~


引用和评论

0 条评论