Как реализовать автоматические свойства в VS 2005 для делегата обратного вызова
Я пытаюсь скомпилировать решение TwainDotNet, которое я нашел здесь ( взаимодействие с C# TWAIN), и я нахожусь в своем уме.
Это решение, очевидно, было разработано в VS 2008, а я работаю в 2005 году (на данный момент выбора нет). Вероятно, я потратил много времени на сборку всего этого в 2005 году, и я сократил свои ошибки до двух, причем обе ошибки были одной и той же проблемой.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace TwainDotNet.WinFroms
{
/// <summary>
/// A windows message hook for WinForms applications.
/// </summary>
public class WinFormsWindowMessageHook : IWindowsMessageHook, IMessageFilter
{
IntPtr _windowHandle;
bool _usingFilter;
public WinFormsWindowMessageHook(Form window)
{
_windowHandle = window.Handle;
}
public bool PreFilterMessage(ref Message m)
{
if (FilterMessageCallback != null)
{
bool handled = false;
FilterMessageCallback(m.HWnd, m.Msg, m.WParam, m.LParam, ref handled);
return handled;
}
return false;
}
public IntPtr WindowHandle { get { return _windowHandle; } }
public bool UseFilter
{
get
{
return _usingFilter;
}
set
{
if (!_usingFilter && value == true)
{
Application.AddMessageFilter(this);
_usingFilter = true;
}
if (_usingFilter && value == false)
{
Application.RemoveMessageFilter(this);
_usingFilter = false;
}
}
}
public FilterMessage FilterMessageCallback
{
get;
set;
}
}
}
Сбой при компиляции свойства, обращающегося к экземпляру делегата.
ОШИБКА: 'TwainDotNet.WinFroms.WinFormsWindowMessageHook.FilterMessageCallback.get' должен объявить тело, поскольку оно не помечено как абстрактное или внешнее
Вот интерфейс IWindowsMessageHook, который реализует этот класс:
using System;
using System.Collections.Generic;
using System.Text;
namespace TwainDotNet
{
public interface IWindowsMessageHook
{
/// <summary>
/// Gets or sets if the message filter is in use.
/// </summary>
bool UseFilter { get; set; }
/// <summary>
/// The delegate to call back when the filter is in place and a message arrives.
/// </summary>
FilterMessage FilterMessageCallback { get; set; }
/// <summary>
/// The handle to the window that is performing the scanning.
/// </summary>
IntPtr WindowHandle { get; }
}
public delegate IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled);
}
Я признаю, что являюсь делегатом-новичком, и я в недоумении. Как я могу продублировать эту функциональность в VS 2005?
Спасибо за время.
3 ответа
Просто используйте вспомогательное поле:
private FilterMessage m_FilterMessageCallback;
public FilterMessage FilterMessageCallback
{
get { return m_FilterMessageCallback; }
set { m_FilterMessageCallback = value; }
}
Код в вашем интерфейсе
FilterMessage FilterMessageCallback { get; set; }
между прочим ничего не делать с C#2.0/3.0, это нормальное определение интерфейса с сеттерами и геттерами.
Заполните пробелы в декларации собственности - ничего волшебного не происходит:
private FilterMessage _filterMessageCallback;
public FilterMessage FilterMessageCallback
{
get { return _filterMessageCallback; }
set { _filterMessageCallback = value; }
}
Событие может быть желательным, но как свойство делегата:
private FilterMessage filterMessageCallback;
public FilterMessage FilterMessageCallback
{
get {return filterMessageCallback;}
set { filterMessageCallback = value;}
}
Чтобы избежать крайнего случая (thread-race / null
), вы также можете захотеть:
public bool PreFilterMessage(ref Message m)
{
FilterMessage callback = FilterMessageCallback;
if (callback != null)
{
bool handled = false;
callback(m.HWnd, m.Msg, m.WParam, m.LParam, ref handled);
return handled;
}
return false;
}