C#是否有Delphi的等价物';s消息关键字?

C#是否有Delphi的等价物';s消息关键字?,c#,delphi,windows-messages,C#,Delphi,Windows Messages,在delphi中,我可以像这样创建我自己的消息 const MY_MESSAGE = WM_USER+100; procedure MyMessage(var Msg: TMessage); message MY_MESSAGE; procedure TForm1.MyMessage(var Msg: TMessage); begin .... end; 但在c#我可以这样做 public static uint ms; protected override void WndProc(ref

在delphi中,我可以像这样创建我自己的消息

const MY_MESSAGE = WM_USER+100;
procedure MyMessage(var Msg: TMessage); message MY_MESSAGE;

procedure TForm1.MyMessage(var Msg: TMessage);
begin
....
end;
但在c#我可以这样做

public static uint ms;
protected override void WndProc(ref Message m)
{       
 if(m.Msg == ms) 
    MessageBox.Show("example");
    else
    base.WndProc(ref m);        
}

void Button1Click(object sender, EventArgs e)
{
    PostMessage(HWND_BROADCAST,ms,IntPtr.Zero,IntPtr.Zero);
}
但我不想重写WndProc(),我想创建自己的MyMessage()函数,当我发布消息时,它将运行

我该怎么做?
谢谢。

这是Delphi的一个特殊功能,在C#中没有类似的功能。在C#中,您需要重写
WndProc()

可以使用
.NET
反射和自定义属性来完成一些看起来非常相似的操作。我认为性能对于生产使用是可以的,但不值得,因为这仍然需要重写
WndProc
来调用自定义调度程序,并且一旦
WndProc
就位,就需要一行代码来调用自定义调度程序,或者需要三行代码来编写适当的
switch
语句。如果代码是从“基类”调用的,那么从它继承的代码可能是值得的

万一你想知道,我这么做是因为我在学习C++.NET,并且很好奇能做些什么。 下面是“管道”完成后代码的样子:

这是“管道”。更多的代码实现了识别所有windows消息处理程序例程(基于自定义属性)的代码,并使用两个字典缓存所有这些结果(因此繁重的工作只需完成一次)

//设置消息ID的自定义属性
类WinMessageHandler:System.Attribute
{
公共信息;
公共WinMessageHandler(int Msg){this.Msg=Msg;}
}    
类WinMessageDispatcher
{
//这是在应用程序的生命周期内缓存的,它保存每种类型所需的
//调度信息。
私有类WinMessageDispatcher\u PerType
{
私人词典;
//通用处理程序
public bool HandleMessage(object OnInstance,ref Message msg)
{
System.Reflection.MethodInfo方法;
if(dict.TryGetValue(msg.msg,out方法))
{
//打电话
object[]p=新对象[1];
p[0]=味精;
return(bool)方法调用(OnInstance,p);
msg=p[0];
}
其他的
{
返回false;
}
}
//构造函数,初始化“dict”
公共WinMessageDispatcher_PerType(类型t)
{
dict=新字典();
foreach(t.GetMethods()中的var方法)
{
var attribs=method.GetCustomAttributes(typeof(WinMessageHandler),true);
如果(attribs.Length>0)
{
//检查返回类型
如果(method.ReturnParameter.ParameterType!=typeof(bool))抛出新异常(string.Format(“{0}不返回bool”,method.Name));
//检查方法参数
var param=method.GetParameters();
如果(param.Length!=1)抛出新异常(string.Format(“{0}不接受1个参数”,method.Name));
//哎呀!我如何检查“ref”参数的类型?
如果(!param[0].ParameterType.IsByRef)引发新异常(string.Format(“{0}不接受System.Windows.Forms.Message类型的ref参数,但接受{1}”类型的参数),则为method.Name,param[0].ParameterType.ToString());
//将该方法添加到字典中
dict.Add(((WinMessageHandler)attribs[0]).Msg,方法);
}
}
}
}
//字典将“类型”链接到每种类型的缓存实现
专用静态字典dict;
//静态类型初始值设定项
静态WinMessageDispatcher()
{
dict=新字典();
}
//消息调度器
公共静态布尔调度(对象对象对象,参考消息消息消息)
{
if(ObjInstance==null)返回false;
其他的
{
WinMessageDispatcher_PerType PerType;
锁(dict)
{
if(!dict.TryGetValue(ObjInstance.GetType(),out PerType))
{
PerType=新的WinMessageDispatcher_PerType(ObjInstance.GetType());
dict.Add(ObjInstance.GetType(),PerType);
}
}
返回PerType.HandleMessage(对象,参考消息);
}
}
}
public partial class Form1 : Form
{
    private const int WM_MOUSEMOVE = 0x0200;
    
    // This is the Delphi-lookalike declaration for the WM_MOUSEMOVE handler.
    // I'd say it looks very much "alike!"
    [WinMessageHandler(WM_MOUSEMOVE)]
    public bool UnHandler(ref Message X)
    {
        this.Text = "Movement";
        return false;
    }

    // While simple, this is unfortunately a deal-breaker. If you need to go through the
    // trouble of writing this stub WndProc, might as well write a proper switch statement
    // and call the handler directly.
    protected override void WndProc(ref Message m)
    {
        if (!WinMessageDispatcher.Dispatch(this, ref m)) base.WndProc(ref m);
    }
}
// Custom attribute to set message ID
class WinMessageHandler : System.Attribute
{
    public int Msg;
    public WinMessageHandler(int Msg) { this.Msg = Msg; }
}    

class WinMessageDispatcher
{
    
    // This is cached for the life of the application, it holds the required per-type
    // dispatching information.
    private class WinMessageDispatcher_PerType
    {
        private Dictionary<int, System.Reflection.MethodInfo> dict;

        // generic handler
        public bool HandleMessage(object OnInstance, ref Message msg)
        {
            System.Reflection.MethodInfo method;
            if (dict.TryGetValue(msg.Msg, out method))
            {
                // Set up the call
                object[] p = new object[1];
                p[0] = msg;
                return (bool)method.Invoke(OnInstance, p);
                msg = p[0];
            }
            else
            {
                return false;
            }
        }

        // Constructor, initializes the "dict"
        public WinMessageDispatcher_PerType(Type t)
        {
            dict = new Dictionary<int, System.Reflection.MethodInfo>();
            foreach (var method in t.GetMethods())
            {
                var attribs = method.GetCustomAttributes(typeof(WinMessageHandler), true);
                if (attribs.Length > 0)
                {
                    // Check return type
                    if (method.ReturnParameter.ParameterType != typeof(bool)) throw new Exception(string.Format("{0} doesn't return bool", method.Name));

                    // Check method parameters
                    var param = method.GetParameters();
                    if (param.Length != 1) throw new Exception(string.Format("{0} doesn't take 1 parameter", method.Name));
                    // Ooops! How do I check the TYPE of the "ref" parameter?
                    if (!param[0].ParameterType.IsByRef) throw new Exception(string.Format("{0} doesn't take a ref parameter of type System.Windows.Forms.Message but a parameter of type {1}", method.Name, param[0].ParameterType.ToString()));

                    // Add the method to the dictionary
                    dict.Add(((WinMessageHandler)attribs[0]).Msg, method);
                }
            }
        }
    }

    // Dictionary to link "Types" to per-type cached implementations
    private static Dictionary<Type, WinMessageDispatcher_PerType> dict;

    // Static type initializer
    static WinMessageDispatcher()
    {
        dict = new Dictionary<Type, WinMessageDispatcher_PerType>();
    }

    // Message dispatcher
    public static bool Dispatch(object ObjInstance, ref Message msg)
    {
        if (ObjInstance == null) return false;
        else
        {
            WinMessageDispatcher_PerType PerType;
            lock (dict)
            {
                if (!dict.TryGetValue(ObjInstance.GetType(), out PerType))
                {
                    PerType = new WinMessageDispatcher_PerType(ObjInstance.GetType());
                    dict.Add(ObjInstance.GetType(), PerType);
                }
            }
            return PerType.HandleMessage(ObjInstance, ref msg);
        }
    }
    
}