Michael Haephrati Ответов: 2

Как отличить вырезку от копирования


Когда GetClipboardData() используется для доступа к данным, захваченным буфером обмена, существует ли вызов API или флаг для различения действия копирования (CTRL+C) и действия вырезания (CTRL+X)?

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

Поиск в интернете. Вообще говоря, я не смог найти никакой документации о разнице между вырезанием и копированием, когда речь заходит о данных, захваченных буфером обмена

0x01AA

Очень хороший вопрос. Я просто попробовал следующее, чтобы проверить, работает ли операция разреза между приложениями:
а) вырезать текстовый файл в Проводнике Windows
б) вставьте его в документ Word

Результат:
Файл копируется в документ word, но не удаляется в файловой системе проводником.

[Редактировать]
В то время как наоборот, вырезать файл из WinWord doc и вставить его с помощью проводника, файл исчезает из word doc....

Richard MacCutchan

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

Michael Haephrati

Это может быть другое ограничение, но предположим, что вы разрабатываете приложение 1, а пользователь, запускающий Приложение 2, вырезает текст и вставляет его в одно и то же приложение (App2). Есть способы запечатлеть этот текст, но мне интересно, как можно определить, была ли это копия или вырезка...

0x01AA

Я больше думал о том, что приложение cuting (владелец буфера обмена (?)) получает, наконец, что-то вроде события "paste_executed". Но, похоже, все не так. И я также узнал, что слово imediatelly показывает "cuted", в то время как Explorer показывает ему что-то вроде "помечено как вырезано". Извините за мой английский :-)

Во всяком случае ваш вопрос был интересным и заставил меня задуматься о некоторых деталях

Jochen Arndt

У тебя была правильная идея.

Смотрите мой ответ ниже. Это объясняет, почему проводник показывает такие файлы помеченными.

Существует нечто похожее на событие "paste_executed". Целевой объект создает два объекта буфера обмена CFSTR_PASTESUCCEEDED и CFSTR_PERFORMEDDROPEFFECT, которые считываются источником (проводником). Таким образом, он знает, когда вставка прошла успешно, и может удалить файл или обновить дисплей в зависимости от действия, выполненного целью.

0x01AA

Большое вам спасибо за подсказку.

Richard MacCutchan

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

0x01AA

См. комментарий Йохена выше

Richard MacCutchan

Да, но это все еще не говорит вам, была ли первоначальная операция сокращением или копией.

2 Ответов

Рейтинг:
2

Jochen Arndt

Как сказано в решении 1 и комментариях:
Нет никакого общего способа узнать, что произошло на стороне источника.

Но есть одно исключение: Операции удаления при вставке
Они используются при вырезании файлов (например, из Проводника Windows).

При этом источник запрашивает у цели информацию о выполнении операции вставки путем добавления дополнительного объекта в данные буфера обмена. Когда цель обнаруживает такие запросы, она знает, что на стороне источника была выполнена операция разреза (и что она должна действовать соответственно).

В разделе Обработка операций удаления при вставке около Обработка Сценариев Передачи Данных Оболочки (Windows)[^] для того, как это работает.


0x01AA

Мои 5 и спасибо что поделились этим

Jochen Arndt

Спасибо, что поддержал меня.

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

Рейтинг:
0

OriginalGriff

Нет. Вы не можете сказать, потому что приложение, которое помещает его в буфер обмена:
1) не сообщает буферу обмена ничего, кроме "вот некоторые данные, это такой тип"
2) совсем не обязательно подчиняться "нормальным" правилам вырезания или копирования: он может, например, переместить текст в архив и скопировать его в буфер обмена.
3) Не обязательно иметь какой - либо пользовательский ввод для загрузки данных в буфер обмена-он может быть автоматизирован с помощью таймера для загрузки данных из RSS-канала в буфер обмена, чтобы выдать сообщение инструкции "вставить" в другое приложение.

Так что нет. Вообще ничего нельзя было сказать.


Michael Haephrati

Ты получил мои 5 звезд! Интересно, есть ли творческое решение для захвата действий вырезания или копирования

Dave Kreskowiak

Нет, это не так. Приложение, которое помещает данные в буфер обмена, знает об этом, но никогда не знает принимающее приложение. Приложение "отправка" обрабатывает операцию вырезания или копирования, но это только для того, чтобы сообщить приложению, что делать с его собственными данными документа. Данные, которые помещаются в буфер обмена, полностью независимы от операции вырезания или копирования. "Принимающее" приложение никак не может знать, что произошло в "отправляющем" приложении.

0x01AA

Пожалуйста, смотрите мой комментарий к этому вопросу. Как вы объясните этот эксперимент?

Michael Haephrati

Я имел в виду своего рода "глобальное зацепление" для захвата копирования или вырезания событий

Dave Kreskowiak

Нет таких вещей, как "вырезать событие" или "копировать событие". Кроме того, материал может попасть в буфер обмена, даже не будучи вырезанным или скопированным. Например, запустить приложение на виртуальной машине и вырезать что-то в буфер обмена с хост-компьютера.

Глобальный Хук клавиатуры? Нет. Во-первых, нет никакого способа сказать, куда шли эти нажатия клавиш. Вы понятия не имеете, какое приложение делало вырезание/копирование. Кроме того, есть несколько способов вырезать/скопировать что-то в приложении, кроме Ctrl-X и Ctrl-C.

Вам также придется обрабатывать альтернативные комбинации клавиш и последовательности, такие как всегда популярные, не обязательно!, Alt-E, Alt-C или Alt-T, чтобы делать то же самое.

Вы также пропустите контекстные меню. Выберите диапазон текста в приложении "отправитель", щелкните правой кнопкой мыши выделенный фрагмент и выберите команду копировать/вырезать.

На самом деле нет никакого способа сделать то, о чем вы думаете, каким-либо последовательным образом. Для этих операций не существует таких понятий, как "глобальные события".

Michael Haephrati

Есть такое http://winapi.freetechsecrets.com/win32/WIN32WMCUT.htm

OriginalGriff

Да, есть сообщение для WM_CUT, но его не нужно использовать:

        private void button1_Click(object sender, EventArgs e)
            {
            Clipboard.SetText(myTextBox.Text);
            myTextBox.Text = "";
            }

Это операция вырезания, но она не вызывает создание сообщения WM_CUT в любом месте системы. А буфер обмена (да и вся система в целом) не может отличить то от этого:
        private void button1_Click(object sender, EventArgs e)
            {
            Clipboard.SetText(myTextBox.Text);
            }

Dave Kreskowiak

Существует также сообщение WM_COPY. Оба они отправляются в целевое окно (элемент управления), чтобы сообщить ему о выполнении этой операции. Он не отправляется в ответ на то, что операция действительно происходит.

Существуют также другие способы выполнения операций вырезания и копирования в буфер обмена без использования этих сообщений вообще.