Как сохранить содержимое буфера обмена

Есть ли способ сохранить содержимое буфера обмена? Я попробовал следующий код, но он не работает.

Dim iData As IDataObject = Clipboard.GetDataObject()
...(use clipboard)
Clipboard.SetDataObject(iData)

Спасибо.


person a programmer    schedule 28.05.2009    source источник


Ответы (4)


Самый простой способ сохранить содержимое буфера обмена — оставить его в покое. Буфер обмена предназначен для временного хранения для пользователя, а не для приложений, поэтому, вероятно, то, что вы пытаетесь сделать, имеет лучшие решения, чем затирание буфера обмена.

person Joey    schedule 28.05.2009
comment
Спасибо за ваше предложение, но это не ответ на мой вопрос. - person a programmer; 05.07.2009
comment
Что ж, было бы неплохо, если бы вы указали причину, по которой вы хотите это сделать, в свой вопрос. Тогда проще разработать решение, которое делает то, что вы хотите. Я до сих пор считаю временную затирание буфера обмена очень глупой идеей. - person Joey; 28.09.2009
comment
Уважительных причин для этого нет. «Программы не должны передавать данные из буфера обмена без явного указания пользователя». - Чарльз Петцольд, Программирование Windows 3.1, Microsoft Press, 1992 г. - person Chris Thornton; 17.03.2010
comment
Я наткнулся на этот вопрос, потому что хотел сделать то же самое. Независимо от ПОЧЕМУ проблема с классом .Net заключается в том, что вы не можете сказать, что лежит в основе формата данных, поэтому вы не можете вернуть его в правильном формате. Короче говоря, в нем отсутствует метод GetForamt(). Опрос ContainsData() для каждого стандартного формата на самом деле недостаточно хорош. - person Swanny; 10.09.2010
comment
Что касается ПОЧЕМУ. В моем случае я хотел попытаться выжать немного функциональности из элемента управления WebBrowser, не прибегая к низкоуровневым вещам. Я могу использовать буфер обмена, чтобы вставить фрагмент, который хочу вставить, но не без перезаписи того, что уже находится в буфере обмена. - person Swanny; 10.09.2010
comment
Общепринятым способом копирования форматированного форматированного текста в текстовый редактор является использование буфера обмена. Мне еще предстоит найти решение, обеспечивающее альтернативу, и я пытался. - person Magnum; 31.01.2013
comment
Magnum, для пользователя точно. Для приложений или автоматизации есть другие и лучшие способы. - person Joey; 31.01.2013
comment
ROFL — скажите это разработчикам Microsoft MapPoint, выбравшим буфер обмена в качестве основного интерфейса. - person SChalice; 06.01.2016

Вы можете использовать OpenClipboard и CloseClipboard. Согласно MSDN открытие буфера обмена сохранит другие приложений от изменения данных.

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern bool CloseClipboard();
person Crispy    schedule 28.05.2009
comment
Спасибо за ваш ответ, но я хочу иметь возможность хранить содержимое буфера обмена, использовать буфер обмена для копирования/вставки, а затем восстанавливать исходное содержимое. - person a programmer; 05.07.2009
comment
Удерживание буфера обмена открытым также приведет к краху других приложений, когда они попытаются открыть буфер обмена, не смогут и не обработают его должным образом. - person Chris Thornton; 17.03.2010

Каким образом ваш код выше не работал? Когда я пробую эквивалентный код на С#, я получаю исключение «CloseClipboard Failed (Exception from HRESULT: 0x800401D4 (CLIPBRD_E_CANT_CLOSE))» при вызове Clipboard.SetDataObject(iData).

Тем не менее, следующий обходной путь делает работу для меня:

// save
Dictionary<String, Object> d = new Dictionary<String, Object>();
IDataObject ido = Clipboard.GetDataObject();
foreach (String s in ido.GetFormats(false))
    d.Add(s, ido.GetData(s));

// ...

// restore
var da = new DataObject();
foreach (String s in d.Keys)
    da.SetData(s, d[s]);
Clipboard.SetDataObject(da);
person Edward D'Souza    schedule 16.12.2009
comment
Спасибо за ответ, я попробовал, и он работает для обычного текста. К сожалению, выдает ошибку, когда текст в буфере обмена из MS Word. - person a programmer; 05.02.2010

Я согласен, что контекст важен. В моем случае я хотел вставить отформатированный, динамически заполненный документ титульной страницы на переднюю часть динамически сгенерированного текста (все в MS Word). Вот решение, которое я нашел (используя VSTO и С#):

                object start = 0;
                Word.Range startRng = a_TreatedDocument.Range(ref start, ref start);
                startRng.FormattedText = a_CoverPageDocument.Content.FormattedText;

Обратите внимание, что это работает с таблицами и форматированным текстом.

person Daniel    schedule 12.07.2010