Изменение содержимого буфера обмена при изменении буфера обмена - PullRequest
2 голосов
/ 12 октября 2009

Я делаю это в C #, но, думаю, это не проблема для конкретного языка ...

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

Но если I SetDataObject () при обнаружении содержимого буфера обмена изменилось, то будет сгенерировано сообщение о том, что содержимое буфера обмена снова изменилось. Теоретически, я думаю, это звучит как бесконечный цикл (на практике по некоторым причинам это не так).

Какова стратегия, чтобы сделать эту модификацию один раз и отправить сообщение по цепочке мониторинга буфера обмена?


P.S. В качестве теста я делаю следующее, но происходит то, что строка Clipboard.SetDataObject .. вызывается дважды. Я не понимаю почему, я ожидал бы, что это сделает это бесконечно.

case Win32.Msgs.WM_DRAWCLIPBOARD:

    String clipboardText = GetClipboardText();
    if (!String.IsNullOrEmpty(clipboardText))
    {
        Clipboard.SetDataObject("test( " + clipboardText + " )!");
    }

    Win32.User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);

Ответы [ 3 ]

1 голос
/ 12 октября 2009

К сожалению, каждый раз, когда вы устанавливаете данные буфера обмена с помощью Clipboard.SetDataObject, вы будете «перерисовывать» буфер обмена, так как вы меняете его содержимое.

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

В вашем случае вы говорите, что удаляете некоторые теги. Просто проверьте строку clipboardText до и после вашей процедуры, и если строка не изменилась, не устанавливайте ее снова.

Таким образом, в первый раз он удалит теги, а затем сбросит их. Затем снова запустите, посмотрите, нет никаких изменений и не сбросьте данные буфера обмена.

1 голос
/ 17 октября 2010

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

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

1 голос
/ 12 октября 2009

Чтобы предотвратить рекурсию, вы должны устанавливать текст буфера обмена только в том случае, если имеются теги для удаления.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...