john1990_1 Ответов: 4

Как сохранить данные буфера обмена windows, изменить их, использовать и затем восстановить?


В приложениях Windows forms:

У меня есть программа перевода, которая должна получить выделенный текст при нажатии F1 глобально, она отправляет Ctrl+C в активное окно в Windows, а затем использует текст и переводит его, теперь я хочу, чтобы она восстановила то, что было в буфере обмена до того, как моя программа отправила Ctrl+C.

Что я уже пробовал:

//Backup
var lBackup = new Dictionary<string, object>();
var lDataObject = Clipboard.GetDataObject();
var lFormats = lDataObject.GetFormats(false);
foreach(var lFormat in lFormats)
{
  lBackup.Add(lFormat, lDataObject.GetData(lFormat, false));
}

//Set test data
Clipboard.SetText("asd");

//Would be interesting to check the contents of lDataObject here

//Restore data
foreach(var lFormat in lFormats)
{
  lDataObject.SetData(lBackup[lFormat]);
}
//This might be unnecessary
Clipboard.SetDataObject(lDataObject);

4 Ответов

Рейтинг:
2

john1990_1

Там есть это, но они говорят в комментариях, что в нем есть ошибки.

Резервное копирование буфера обмена в C#[^]

У вас есть код получше?


Richard MacCutchan

Это совсем не трудно. Захват содержимого буфера обмена. Займитесь своим переводом. Восстановить первоначальное содержание.

Я дал вам ссылку на класс буфера обмена, который содержит всю необходимую информацию для достижения этой цели.

john1990_1

Затем, поскольку я изучил C# методом проб и ошибок, я не думаю, что у меня есть возможность сделать это самостоятельно, не могли бы вы помочь?

Richard MacCutchan

Нет, потому что мы понятия не имеем, в чем ваша проблема.

john1990_1

У меня есть программа перевода, которая переводит выделенный текст в Windows при нажатии F1 глобально, при нажатии F1 она отправляет Ctrl+C в активное окно и переводит текст в буфер обмена (данные, которые были в буфере обмена, исчезают), я хочу сохранить то, что было в буфере обмена, а затем при нажатии F1 отправить Ctrl+C в активное окно Windows, скопировать выделенный текст в буфер обмена, перевести текст в буфер обмена глобально в моей программе и восстановить то, что было в буфере обмена до нажатия F1 и отправки Ctrl+C.

http://sites.google.com/site/windowsprogramfortranslation/

Ясно?

Richard MacCutchan

Да, вы продолжаете повторять это, и я дал вам ссылку на класс ClipBoard, который содержит все методы сохранения и восстановления данных. Используйте методы ContainsXXX, чтобы узнать, в каком формате находятся данные. Используйте соответствующий метод Get для захвата данных и соответствующие методы Set для отправки их обратно в буфер обмена.

john1990_1

Я любитель и не изучал C# в школе, извините, у меня нет такой возможности, не могли бы вы помочь мне и многим другим?

Рейтинг:
2

Richard MacCutchan

Вот основные наброски того, что вам нужно сделать.

IDataObject iData = Clipboard.GetDataObject(); // get a link to the ClipBoard data
string strSave = (string)iData.GetData(DataFormats.Text); // get the object's data

// do your copying & translating

Clipboard.SetText(strSave, TextDataFormat.UnicodeText); // restore original cotents

Это всего лишь простой шаблон для сохранения и восстановления некоторого текста в Юникоде. Вам нужно добавить код для обслуживания всех различных форматов данных, как показано в документации для класса Clipboard - см. ссылку, которую я дал вам выше.


john1990_1

Я почти понял это, но из-за недостатка знаний, а не из-за лени я не могу этого сделать.

Richard MacCutchan

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

john1990_1

Ну, я хотел сделать эту программу, я отключил в ней эту функциональность, во всяком случае, thx.

Рейтинг:
1

john1990_1

Но, к сожалению, я не думаю, что ответ есть.

Richard MacCutchan

Тогда вам нужно объяснить вопрос.

john1990_1

У меня есть программа перевода, которая переводит выделенный текст в Windows при нажатии F1 глобально, при нажатии F1 она отправляет Ctrl+C в активное окно и переводит текст в буфер обмена, а также уничтожает то, что было в буфере обмена, я хочу сохранить то, что было в буфере обмена, затем отправить Ctrl+C в активное окно, скопировать выделенный текст в буфер обмена, перевести текст в буфер обмена и восстановить то, что было в буфере обмена до нажатия F1 и отправки Ctrl+C.

http://sites.google.com/site/windowsprogramfortranslation/

phil.o

Тем не менее, это не вопрос, это требование.
Вы хотите сохранить содержимое буфера обмена до его изменения. Тогда почему бы вам просто не создать строковую переменную и не сохранить текущее текстовое содержимое буфера обмена перед его переназначением?
Что-то вроде string originalText = Clipboard.GetText();

john1990_1

буфер обмена может содержать сложные данные, а не только строку (файлы, рис...)

Richard MacCutchan

Да, мы это знаем.

Richard MacCutchan

Поэтому все, что вам нужно сделать, это добавить код, представляющий этот набор псевдо-инструкций. Если у вас есть проблема с кодированием, пожалуйста, объясните, что это такое, а не просто скажите нам, что вы хотите сделать.

john1990_1

Я любитель, который изучал C# методом проб и ошибок, я программировал в течение длительного времени, и я хорош, мне просто нужен способ сохранить данные в буфере обмена и восстановить их позже, как было объяснено ранее...

Рейтинг:
1

Jochen Arndt

Это не так просто, как может показаться вначале.

Данные буфера обмена хранятся системой внутри системы в различных форматах (глобальная память, IStream, IStorage, file, GDI object).

Это также является причиной того, что код из Резервное копирование буфера обмена в C#[^] статья может потерпеть крах:
Он использует вызовы Win32 API, но не проверяет тип хранилища. Он предполагает глобальные данные памяти, что приводит к NULL указатели при попытке доступа к глобальной памяти с помощью дескриптора, например an IStream или объект GDI.

Таким образом, вы должны определить тип хранения для каждого объекта буфера обмена и хранить его вместе с форматом и необработанными данными. При восстановлении должны использоваться те же типы хранения (и должны быть для объектов GDI).

Должен признаться, я не знаю, что именно. Интерфейс idataobject.Метод GetData (String, Boolean) (System.Окна.Формы)[^] делает внутренне. Но он возвращает System.Object тип, который, вероятно, не способен представлять все виды данных, которые могут находиться в буфере обмена, и может не использовать один и тот же метод хранения при размещении таких данных в буфере обмена. Но он будет обрабатывать различные методы хранения и использовать их для чтения данных и создания System.Object.

Даже при обработке всего вышеперечисленного могут быть различия во внутренних данных буфера обмена, поскольку приложение не должно изначально помещать данные в буфер обмена, но может создавать содержимое по запросу при извлечении данных (задержка рендеринга). Источник буфера обмена также может указывать функцию обратного вызова release, которая не может быть сохранена и повторно использована вашим приложением при возврате данных.


john1990_1

Значит, будучи любителем, я не могу этого сделать? Я отключил эту функцию в своей программе, но если вы предоставите класс для этого, я могу пересмотреть его добавление...

Jochen Arndt

Извините, но я не могу предоставить класс (я разработчик C++ и имею только базовые знания C#). Вы можете проверить, работает ли ваше решение для всех видов данных буфера обмена (я не уверен в этом). Вероятно,с утилизацией lDataObject (повторное его использование может не сработать). Если это работает, вам просто нужно принять, что буфер обмена не восстанавливается idfentically (но содержимое объектов остается тем же самым).