WPF:Clipboard剪切板(1)

ClipboardSpy剪切板內容查驗

clipboard.png

實現步驟:
一、檢查剪切板上是否有對應的格式,是的話CheckBox打勾app

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

二、獲取剪切板上內容:ide

  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內容 與剪切板數據不兼容spa


ClipbordViewer剪切板展現

clipboard.png

關注點:
一、從RichTextBox中獲取指定數據格式(text,dataFomat)的數據內容:code

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

二、在DataObject中保持自定義格式的數據內容:orm

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

三、從文件中複製數據到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);
        }
    }
}

四、從文件中讀取數據到string中ip

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

五、 從剪切板黏貼數據對象到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;
}

六、黏貼剪切板數據對象到文件中:資源

// 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();
}
}
相關文章
相關標籤/搜索