none
Работа с буфером обмена. RRS feed

Ответы

  • Используя класс Clipboard:

    IDataObject myDataObject=Clipboard.GetDataObject();
    String[] allFormats = myDataObject.GetFormats();
    
    foreach(string s in allFormats)
    {	
    	if(s==DataFormats.UnicodeText)
    	{		
    		string text=myDataObject.GetData(DataFormats.UnicodeText);		
    		MessageBox.Show("UnicodeText size: "+ ((text.Length+1) * 2).ToString());
    	}
    	else
    	{
    		object val=myDataObject.GetData(s);
    		int size=System.Runtime.InteropServices.Marshal.SizeOf(val);
    		MessageBox.Show(s+" size: " + (size).ToString());
    	}
    }

    С размером не все так просто, он зависит от типа данных... Зная тип и формулу, можно размер посчитать (в примере размер Юникод-строки). Для произвольного объекта можно взять размер неуправляемой памяти (Marshal.SizeOf), но не факт что это сработает.

    Добавлено: да, Marshal.SizeOf бесполезен в этом случае. См. ниже рабочий метод.



    29 января 2017 г. 7:03

Все ответы

  • Используя класс Clipboard:

    IDataObject myDataObject=Clipboard.GetDataObject();
    String[] allFormats = myDataObject.GetFormats();
    
    foreach(string s in allFormats)
    {	
    	if(s==DataFormats.UnicodeText)
    	{		
    		string text=myDataObject.GetData(DataFormats.UnicodeText);		
    		MessageBox.Show("UnicodeText size: "+ ((text.Length+1) * 2).ToString());
    	}
    	else
    	{
    		object val=myDataObject.GetData(s);
    		int size=System.Runtime.InteropServices.Marshal.SizeOf(val);
    		MessageBox.Show(s+" size: " + (size).ToString());
    	}
    }

    С размером не все так просто, он зависит от типа данных... Зная тип и формулу, можно размер посчитать (в примере размер Юникод-строки). Для произвольного объекта можно взять размер неуправляемой памяти (Marshal.SizeOf), но не факт что это сработает.

    Добавлено: да, Marshal.SizeOf бесполезен в этом случае. См. ниже рабочий метод.



    29 января 2017 г. 7:03
  • Спасибо. Помогло.

    JohnKorsh

    29 января 2017 г. 10:32
  • Вот нашел еще один способ получения размера произвольного формата в буфере обмена (работает в 80% случаев). Возвращает размер выделенной памяти, который больше или равен размеру самих данных, но для некоторых форматов возвращается слишком маленькое значение или 0:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace Test
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll", SetLastError = true)]
            static extern bool OpenClipboard(IntPtr hWndNewOwner);
    
            [DllImport("user32.dll")]
            static extern IntPtr GetClipboardData(uint uFormat);
    
            [DllImport("kernel32.dll")]
            static extern UIntPtr GlobalSize(IntPtr hMem);
    
            [DllImport("user32.dll", SetLastError = true)]
            static extern bool CloseClipboard();
    
            public uint GetClipboardDataSize(string fmt)//получение размера блока памяти в буфере обмена
            {
                DataFormats.Format myFormat;
                int id;
                IntPtr hMem;
                uint size;
    
                OpenClipboard(IntPtr.Zero);
    
                myFormat = DataFormats.GetFormat(fmt);
                id = myFormat.Id;
                hMem = GetClipboardData((uint)id);
                size = (uint)GlobalSize(hMem);
    
                CloseClipboard();
    
                return size;
            }
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            { 
                IDataObject myDataObject = Clipboard.GetDataObject();
                String[] allFormats = myDataObject.GetFormats();//получение списка форматов
                
                StringBuilder sb=new StringBuilder(300);  
                
                foreach (string s in allFormats)
                {
                    sb.AppendLine(s + ": " + GetClipboardDataSize(s) + " bytes");              
                }            
    
                MessageBox.Show(sb.ToString());
            }
        }
    }
    Тестирование показало, что Marshal.SizeOf не работает (в смысле, для объектов буфера обмена), а также что формула размера для Юникод-текста все-таки ((text.Length+1) * 2) а не ((text.Length+2) * 2)

    29 января 2017 г. 11:18