Проблема
Для второй версии монитора буфера обмена (с которой мы будем разбираться в следующем посте) мы создадимprotected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
// содержимое буфера обмена изменилось
{
// реагируем на изменение буфера
ClipboardChanged();
// пересылаем сообщение следующему окну в цепочке
SendMessage(nextClipboardViewer, WM_DRAWCLIPBOARD, IntPtr.Zero, IntPtr.Zero);
break;
}
case WM_CHANGECBCHAIN:
// цепочка приложений, подписанных на WM_DRAWCLIPBOARD изменилась
{
if (m.WParam == nextClipboardViewer)
{
// окно, которому мы передавали WM_DRAWCLIPBOARD, удалено из
// цепочки, и нам нужно обновить переменную
nextClipboardViewer = m.LParam;
}
else
{
// просто передаем новости дальше
SendMessage(nextClipboardViewer, WM_CHANGECBCHAIN, m.WParam, m.LParam);
}
m.Result = IntPtr.Zero; // уведомляем систему об обработке сообщения
break;
}
default:
// поведение для остальных сообщений - по умолчанию
{
base.WndProc(ref m);
break;
}
}
}
Аналогом класса Form в Windows Forms является класс Window, в котором нет метода WndProc, который мы могли бы переопределить. Возвращаемся в Windows Forms? Нет, решение Решение
Для решения нашей задачи предназначен замечательный класс HwndSource, который находится в пространстве имен System.Windows.Interop. HwndSource — класс, который представляетpublic void AddHook(HwndSourceHook hook); public void RemoveHook(HwndSourceHook hook);Эти методы позволяют соответственно установить и удалить
public delegate IntPtr HwndSourceHook( IntPtr hwnd, // дескриптор окна int msg, // сообщение Windows IntPtr wParam, // параметры IntPtr lParam, // сообщения ref bool handled // обработано ли сообщение )Чтобы создать экземпляр класса HwndSource, мы можем воспользоваться его конструктором и создать новое окно, сообщения которому мы и будем перехватывать. Однако, можно сделать и
В этом моменте я допустил ошибку, вызвав FromVisual в конструкторе формы. В момент вызова окно ещё не было полностью инициализировано, и результатом стало исключение. После этой попытки я переопределил вызов OnSourceInitialized и завершил инициализвцию HwndSource в нём.
Код
Полный код перехвата сообщений Windows выглядит так:public partial class MainWindow : Window
{
private const int WM_DRAWCLIPBOARD = 0x0308;
private HwndSource hwndSource;
// функция-перехватчик
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_DRAWCLIPBOARD)
{
// обрабатываем сообщение
}
return IntPtr.Zero;
}
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
// создаем экземпляр HwndSource
hwndSource = PresentationSource.FromVisual(this) as HwndSource;
// и устанавливаем перехватчик
hwndSource.AddHook(WndProc);
}
}
HwndSource Class (System.Windows.Interop)HwndSourceHook delegate (System.Windows.Interop)

Добрый день, почему то не работает данный код...
ReplyDeleteСообщения приходят... но заветного M_DRAWCLIPBOARD
при вставке в буфер обмена нового текста так и нет.. И в чем же проблема?