views:

118

answers:

3

I'm attempting to get the TwainDotNet solution I found here (http://stackoverflow.com/questions/476084/c-twain-interaction) to compile, and I'm at my wits end.

This solution was obviously developed in VS 2008, and I'm working in 2005 (no choice at the moment). I've spent probably WAY to much time getting this all to compile in 2005, and I've whittled my errors down to two, both errors being the same one issue.

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;
    }
  }

}

The compile fails on the property accessing the delegate instance.

ERROR: 'TwainDotNet.WinFroms.WinFormsWindowMessageHook.FilterMessageCallback.get' must declare a body because it is not marked abstract or extern

Here is the interface IWindowsMessageHook that this class implements:

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);
}

I admit to being a delegate newbie, and I'm at a loss here. How can I duplicate this functionality in VS 2005?

Thanks for the time.

A: 

An event may be desirable, but as a delegate property:

private FilterMessage filterMessageCallback;
public FilterMessage FilterMessageCallback 
{
  get {return filterMessageCallback;}
  set { filterMessageCallback = value;}
}

To avoid an edge-case (thread-race / null), you might also want:

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;
}
Marc Gravell
A: 

Fill in the blanks in the property declaration -- nothing magic is happening:

private FilterMessage _filterMessageCallback;

public FilterMessage FilterMessageCallback
{
    get { return _filterMessageCallback; }
    set { _filterMessageCallback = value; }
}
Tim Robinson
A: 

Just use a backing field:

private FilterMessage m_FilterMessageCallback;
public FilterMessage FilterMessageCallback 
{
  get { return m_FilterMessageCallback; }
  set { m_FilterMessageCallback = value; }
}

The code in your interface

FilterMessage FilterMessageCallback { get; set; }

has btw. nothing to do with C#2.0/3.0, that is a normal inteface definition with setter and getter.

tanascius
Thanks much guys. I just didn't know what the VS 2008 compiler might be doing under the hood - I'm assuming it does a version of this very thing?
Ducain
Yes, it does quite exactly the same.
tanascius