2009-10-12 3 views
2

я делаю это в C#, но, я думаю, это не язык конкретных проблем ...Изменение содержимого буфера обмена на изменение буфера обмена

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

Но если я установил 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); 

ответ

1

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

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

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

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

+0

Он ожидает замкнутую петлю, но только видеть это случается дважды в этом примере ... – cjk

+1

Но это был не вопрос. Фактический вопрос заключался в том, как правильно справляться с этим. Уклонение от цикла infitite, вероятно, связано с тем, что он не пропускает сообщение Windows (захват его), когда он обрабатывает сообщение proc. –

+0

есть лучший способ (общий), чтобы предотвратить рекурсию. См. Мой ответ ниже. – Giorgi

1

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

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

1

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

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