Сегодня 27 ноября, среда ГлавнаяНовостиО проектеЛичный кабинетПомощьКонтакты Сделать стартовойКарта сайтаНаписать администрации
Поиск по сайту
 
Ваше мнение
Какой рейтинг вас больше интересует?
 
 
 
 
 
Проголосовало: 7276
Кнопка
BlogRider.ru - Каталог блогов Рунета
получить код
Справочник по C#
Справочник по C#
Голосов: 1
Адрес блога: http://www.csharpcoderr.com/
Добавлен: 2012-11-28 00:46:26
 

Мониторинг буфера обмена

2012-10-15 09:02:37 (читать в оригинале)


Обзор
      ОС Windows поддерживает список, или цепь, приложений, которые обратились с просьбой получить уведомление, когда данные поступят в буфер обмена. Каждый раз, когда в буфере обмена изменяется данные, первое приложение в этой цепочке получает сообщение - WM_DRAWCLIPBOARD. Приложения могут запросить тип данных в буфере обмена, например RTF, ASCII текст, и так далее. Так как нет управляемых (. NET) API для добавления приложения в цепочку, чтобы получать уведомление об изменении буфера, вы должны использовать Win32 SetClipboardViewer. Вы должны знать некоторые общие правила при использовании этой функции.
      • При вызове SetClipboardViewer, вам необходимо пройти дескриптор окна, которое будет получать сообщение WM_DRAWCLIPBOARD. SetClipboardViewer функция возвращает текущее первое приложение в цепочке. Ваше приложение должно хранить в классе членов, потому что каждое приложение которое получает сообщение WM_DRAWCLIPBOARD может отправить то же сообщение к следующему приложению в цепочке (через функцию SendMessage).
      • WM_CHANGECBCHAIN. Поскольку каждое приложение, которое обрабатывает WM_DRAWCLIPBOARD, отвечает за отправку этого сообщения к следующему приложению в цепочке, оно также должно знать, когда изменилась цепь. Буфер обмена посылает сообщения WM_CHANGECBCHAIN , когда приложение удалило себя из цепочки.
      • При завершении работы необходимо удалить приложение из цепочки. Эта задача решается с помощью Win32ChangeClipboardChain функции, и это может быть сделано в любое время, буфер обмена мониторинга больше не нужен.

Для работы вам понадобится разместить компонент richTextBox. Так же в его свойствах ForeColor указать цвет Black!

Вот код приложения:

IntPtr nextClipboardViewer;

public Form1()
{
    InitializeComponent();
    nextClipboardViewer = (IntPtr)SetClipboardViewer((int)
                this.Handle);
}
[DllImport("User32.dll")]
  protected static extern int
            SetClipboardViewer(int hWndNewViewer);
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool
         ChangeClipboardChain(IntPtr hWndRemove,
                              IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, 
                                     int wMsg,
                                     IntPtr wParam,
                                     IntPtr lParam);

protected override void WndProc(ref System.Windows.Forms.Message m)
{              
    const int WM_DRAWCLIPBOARD = 0x308;
    const int WM_CHANGECBCHAIN = 0x030D;

    switch (m.Msg)
    {
        case WM_DRAWCLIPBOARD:
            DisplayClipboardData();
            SendMessage(nextClipboardViewer, m.Msg, m.WParam,
                        m.LParam);
            break;

        case WM_CHANGECBCHAIN:
            if (m.WParam == nextClipboardViewer)
                nextClipboardViewer = m.LParam;
            else
                SendMessage(nextClipboardViewer, m.Msg, m.WParam,
                            m.LParam);
            break;

        default:
            base.WndProc(ref m);
            break;
    }
}

void DisplayClipboardData()
{
    try
    {
        IDataObject iData = new DataObject();
        iData = Clipboard.GetDataObject();

        if (iData.GetDataPresent(DataFormats.Rtf))
            richTextBox1.Rtf = (string)iData.GetData(DataFormats.Rtf);
        else if (iData.GetDataPresent(DataFormats.Text))
            richTextBox1.Text = (string)iData.GetData(DataFormats.Text);
        else
            richTextBox1.Text = "[Clipboard data is not RTF or ASCII Text]";
    }
    catch (Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}
Так же вам необходимо в Form1.Designer.cs заменить функцию Dispose:
С:
protected override void Dispose(bool disposing)
{    
    if (disposing)
    {
        if (components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose(disposing);
}
НА:
protected override void Dispose(bool disposing)
{
    ChangeClipboardChain(this.Handle, nextClipboardViewer);
    if (disposing)
    {
        if (components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose(disposing);
}

Скриншот получившегося приложения:

Тэги: application, form, system, window

 


Самый-самый блог
Блогер ЖЖ все стерпит
ЖЖ все стерпит
по сумме баллов (758) в категории «Истории»
Изменения рейтинга
Категория «Кино»
Взлеты Топ 5
+363
414
Информационный колодец
+341
345
Yurenzo
+339
343
CAPTAIN
+331
341
Alta1r
+322
361
Vindigo
Падения Топ 5


Загрузка...Загрузка...
BlogRider.ru не имеет отношения к публикуемым в записях блогов материалам. Все записи
взяты из открытых общедоступных источников и являются собственностью их авторов.