http://www.csdn.net/develop/Article/21/21901.shtm

解决方案 »

  1.   

    C#中的消息处理:在C#中,程序采用了的驱动采用了事件驱动而不是原来的消息驱动,虽然.net框架提供的事件已经十分丰富,但是在以前的系统中定义了丰富的消息对系统的编程提供了方便的实现方法,因此在C#中使用消息有时候还是大大提高编程的效率的。  1 定义消息   在c#中消息需要定义成windows系统中的原始的16进制数字,比如   const int WM_Lbutton = 0x201; //定义了鼠标的左键点击消息    public const int USER = 0x0400 // 是windows系统定义的用户消息  2 消息发送   消息发送是通过windows提供的API函数SendMessage来实现的它的原型定义为  [DllImport("User32.dll",EntryPoint="SendMessage")] 
       private static extern int SendMessage( 
              int hWnd,   // handle to destination window 
              int Msg,    // message 
              int wParam, // first message parameter 
              int lParam // second message parameter 
        ); 3 消息的接受  在C#中,任何一个窗口都有也消息的接收处理函数,就是defproc函数 你可以在form中重载该函数来处理消息 protected override void DefWndProc ( ref System.WinForms.Message m ) 

    switch(m.msg) 

    case WM_Lbutton : 
     ///string与MFC中的CString的Format函数的使用方法有所不同 
     string message = string.Format("收到消息!参数为:{0},{1}",m.wParam,m.lParam); 
     MessageBox.Show(message);///显示一个消息框 
     break; 
    default: 
     base.DefWndProc(ref m);///调用基类函数处理非自定义消息。 
     break; 


    其实,C#中的事件也是通过封装系统消息来实现的,如果你在DefWndProc函数中不处理该 
    那么,他会交给系统来处理该消息,系统便会通过代理来实现鼠标单击的处理函数,因此你可以通过 
    defproc函数来拦截消息,比如你想拦截某个按钮的单击消息 4 C#中其他的消息处理方法 
      在C#中有的时候需要对控件的消息进行预处理,比如你用owc的spreedsheet控件来处理Excel文件,你不想让用户可以随便选中 
    数据进行编辑,你就可以屏蔽掉鼠标事件,这个时候就必须拦截系统预先定义好的事件(这在MFC中称为子类化),你可以通过C#提供的一个接口 
    IMessageFilter来实现消息的过滤 
    public class Form1: System.Windows.Forms.Form,IMessageFilter 

     const int WM_MOUSEMOVE = 0x200 
     public bool PreFilterMessage(ref Message m)  
     {  Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;  
       if(m.Msg == m.Msg==WM_MOUSEMOVE) //||m.Msg == WM_LBUTTONDOWN 
       { 
        //MessageBox.Show("Ignoring Escape...");   
        return true;  
       }  
        return false;  
     } 
    }
      

  2.   

    委托是用来把方法当作参数来传递的,委托的签名(参数)必须和所委托的方法一致。使用事件的步骤
    1。声明一个委托
    public delegete void delegateME();
    2。声明此委托的事件
    public event delegateME eventME;
    3。把方法订阅到一个事件
    eventME+=new delegete(objA.Method);
    括号里传递的是需要订阅事件的方法。
    然后在别处运行eventME将调用objA.Method方法。如果想进一步了解C#中的事件处理机制,编写自己的事件可参看
    http://www.csdn.net/develop/Read_Article.asp?Id=22951
      

  3.   

    代表使得这样的方案变为可能:其他语言-C++, Pascal, Modula 等可以用功能指针来定位。与C++的功能指针不同,代表完全是面向对象的;与C++指向成员功能不同,代表把一个对象实例和方法都进行封装。 一个代表声明定义了一个从类System.Delegate 延伸的类。一个代表实例封装一个方法,可调用实体。对于实例方法,一个可调用实体由一个实例和一个实例中的方法组成。对于静态方法,一个可调用实体完全只是由一个方法组成。如果你有一个代表实例和一个适当的参数集合,你就可以用参数来调用这个代表。 代表的一个有趣而又有用的特性是它不知道或不关心它引用的对象的类。只要方法的签名与代表的签名一致,任何对象都可以作。这使得代表适合作“匿名“调用”。
      

  4.   

    http://blog.sunmast.com/sunmast/posts/230.aspx或者在CSDN搜索下"事件",或者"委托",肯定要出来一大堆
      

  5.   

    谢谢各位的回复,我得先消化一下各位提供的资料楼上所说的“代表”是不是就是我所说的"委托"?
    >>一个代表声明定义了一个从类System.Delegate 延伸的类
      

  6.   

    事件是可以通过代码响应或“处理”的操作。事件可由用户操作(如单击鼠标或按某个键)、程序代码或系统生成。事件驱动的应用程序执行代码以响应事件。每个窗体和控件都公开一组预定义事件,您可根据这些事件进行编程。如果发生其中一个事件并且在相关联的事件处理程序中有代码,则调用该代码。对象引发的事件类型会发生变化,但对于大多数控件,很多类型是通用的。例如,大多数对象都处理 Click 事件,即如果用户单击窗体,将执行该窗体的 Click 事件处理程序中的代码。注意 很多事件与其他事件一起发生。例如,在发生 DoubleClick 事件的过程中,还发生 MouseDown、MouseUp 和 Click 事件。
    委托及其角色
    委托是 .NET 框架内的常用类,用于生成事件处理机制。委托大体上相当于常用于 C++ 和其他面向对象的语言中的函数指针。但与函数指针不同的是,委托是面向对象的、类型安全的和保险的。另外,函数指针只包含对特定函数的引用,而委托由对对象的引用以及对该对象内一个或多个方法的引用组成。此事件模型使用“委托”将事件绑定到用来处理它们的方法。委托允许其他类通过指定处理程序方法注册事件通知。当发生事件时,委托调用绑定的方法。委托可绑定到单个方法或多个方法,后者又称为多路广播。当创建事件的委托时,您(或“Windows 窗体设计器”)通常创建多路广播事件。极少的例外情况是,某个事件会导致特定过程(如显示对话框),而该过程在逻辑上不在每个事件中重复多次。多路广播委托维护它所绑定到的方法的调用列表。多路广播委托支持将方法添加到调用列表的 Combine 方法以及移除它的 Remove 方法。 当应用程序记录某个事件时,控件通过调用该事件的委托引发事件。委托接着调用绑定的方法。最常见的情况(多路广播委托)是,委托依次调用调用列表中的每个绑定方法,这样可提供一对多通知。此策略意味着控件不需要维护事件通知的目标对象的列表,即委托处理所有注册和通知。 委托也允许将多个事件绑定到同一个方法,从而允许多对一通知。例如,单击按钮事件和单击菜单命令事件可调用同一委托,然后该委托调用单个方法以相同方式处理各个事件。委托使用的绑定机制是动态的,即委托可在运行时绑定到其签名与事件处理程序的签名匹配的任何方法。此功能使您得以根据条件设置或更改绑定的方法,并动态地将事件处理程序附加到控件上。
    ms-help://MS.NETFrameworkSDK.CHS/cpguidenf/html/cpconWhatIsEvent.htm
    这是2002的sdk文档
      

  7.   

    楼上所说的“代表”是不是就是我所说的"委托"?
    >>一个代表声明定义了一个从类System.Delegate 延伸的类
    正是!
      

  8.   

    再次感谢各位的热心帮忙!
        先解释一下:在下来论坛的次数不多,所以论坛的有些功能不是很熟,比如搜索,我都不知道在那里,让大家见笑了,请大家顺手指点一下。另外想问一下论坛有没有离线资料包和阅读器下载,谢谢。
        回到问题中,举一个例子来说,比如要设计一个button类,并要使这个类的实例能响应onclick事件, 我这样做:
       1、在 button类中申明一个委托类
          public delegate void myclick(object sender);
       2、在 button类中申明一个onclick事件,这个事件是上边委托类的实例
          public event  myclick onclick;
    -----------在button类中作这两步是不是就齐活了?(语法不一定对,就这个意思了)   另外有一个form对象中创建了一个上边的button的实例button1,而且要在单击button1调用这个form的一个方法  public void button1click(object sender);,也就是把form的button1click方法注册到button1的onclick事件,是不是在form的构造方法中
        button1.onclick+=button1click  (这里不对吧,应该怎么做?)---------------------我上边的理解肯定有问题吧,大虾们给指导一下。
      

  9.   

    button1.onclick+=new delegete(this.button1click) 
      这样吗?好像也不对吧
      

  10.   

    我的问题是:
      1、我上边在button类中申明onclick事件的做法对不对?
      2、我在form中把button1click方法注册到button1的onclick事件的做法对不对?
      另外,楼上所说的本来是我搞清楚基本概念之后接下来要问的:
      事件的调用列表是一什么样的形式放在那里的?
      

  11.   

    不是函数指针,因为它是类型安全的,更接近STL中的仿函数,或者叫做函数对象
      

  12.   

    如果上面我说的不清楚,我用代码演示一遍:
    一个现实中的例子:
    小王委托小张帮他监视小李,只要他一跳舞就去揍他,呵呵,好吧,我就用这个例子来说说C#中的DELEGATE,现在有三个类,呵呵,是小王,小张,小李。那么小张就是委托。
    下面例子public class 小李
    {
        public 小李(小张 obj)
        {
            // 构造器,传递小张的实例进来
        }    // 下面是小李的跳舞方法
        public void 跳舞()
        {
            // 跳舞方法
            把这个方法传递给小张
            实例小张(this);
        }
    }下面我们来定义委托小张。
    // 定义参数,把小李给传递进来,下面的object实际上就是小李的实例。
    public delegate 小张(object sender);下面定义小王,小王不会别的,就会打人。:-)
    public class 小王
    {
        public 小王
        {
           // 构造器
        }
        
        // 小王打人方法
        public void 揍(object obj) // obj参数就是要打的对象
        {
            // 我打,我打打打!!
        }
    }下面是场景
    public class 舞厅
    {
        public int main()
        {
            new 实例小王;        new 实例小张(小王.揍);
            \\这句是小王委托小张去监视小李
            new 实例小李(小张);
            
            实例小李.跳舞; 
            // 小李一跳舞,那就要被打了。:-)
        }
    }
      

  13.   

    非常感谢 TomMax(笑望人生) 我就要这样的例子!
    不过在你的例子中在下还有一些疑问,请再指教一下:
    1、    public 小李(小张 obj)
           {
            // 构造器,传递小张的实例进来
           }
        --------------这里,委托小张的实例是在外边创建,然后通过小李的构造方法传入吗?
                      我觉得应该在小李的构造方法中创建,不知我的理解对不对?
    2、如果我还要在小李跳舞的时候,执行 小赵.关门,小钱.放狗...怎么作? 也就是有多个对象监视小李跳舞,并采取相应的措施?
      

  14.   

    委托/事件 前者是主动执行,后者是被动执行。
    事件得需什么东西激活它,而委托则是主动执行的.这个是个相对的概念.委托有点类似于VC的callback.搂主可以看看delegate的一般使用就能够体会到的.
      

  15.   

    如果我给一个委托类的实例注册了多个方法,是不是在这个实例中会维护一个调用列表?类方法和静态方法可以共存于同一个调用列表吗?能不能访问这个调用列表来获得一个委托类实例都注册了那些方法及这些方法的相关信息?
               ----顺便问一句,vc的事件也用的是callback机制吗?我对vc一窍不通。
      

  16.   

    TomMax(笑望人生)
    讲的很精彩,鼓掌!!!
      

  17.   

    up!
       TomMax(笑望人生) 讲的确实很精彩,但是取不见得对(我认为 : )  也许是我理解错了)
    请大侠回来再指点一二,谢谢
      

  18.   

    even是delegate的一个集合?这个我还是不够明白,是不是说一个even定义的对象中可以+=多个delegate??如果如此,那么怎么调用到这个delegate呢?我怎么不明白event的存在意义
    感觉好像又没有他都可以阿!
      

  19.   

    TomMax(笑望人生)
    讲的很精彩,鼓掌!!!
      

  20.   

    TomMax(笑望人生)
    的例子中没有使用到 event,
    可否再用同样的方式阐述一下。
      

  21.   

    委托就是一种方法容器,是方法指针的peer。
    通俗一点就像马桶,可以不同的人坐上去,排泄物可以通到不同的地方,但是屁股必须要和马桶尺寸完全一样
      

  22.   

    呵呵,好长时间没有看这个帖子,好吧,我重新说一次。
    还是上次的那个例子:比如说一个公司(场景),你是老板,手下有两个员工,小张和小李。你命令小张注意小李,在开发软件工作的时候如果上网打游戏,你就记录下来,从小李工资里扣100元钱。这个实际上就是现实中的委托。现在给出一个代码,C#控制台程序,编译运行通过
    using System;namespace CSharpConsole
    {
    public class 场景
    {
    [STAThread]
    public static void Main(string[] args)
    {
    Console.WriteLine("场景开始了....");
    // 生成小王
    小王 w = new 小王();
    // 生成小账
    小张 z = new 小张(); // 指定监视
    z.PlayGame += new PlayGameHandler(w.扣钱);

    // 开始玩游戏
    z.玩游戏(); Console.WriteLine("场景结束...");
    Console.ReadLine();
    }
    } // 负责扣钱的人
    public class 小王
    {
    public 小王()
    {
    Console.WriteLine("生成小王...");
    } public void 扣钱(object sender,EventArgs e)
    {
    Console.WriteLine("小王:好小子,上班时间胆敢玩游戏...");
    Console.WriteLine("小王:看看你小子有多少钱...");
    小张 f = (小张)sender;
    Console.WriteLine("小张的钱: " + f.钱.ToString());
    Console.WriteLine("开始扣钱......");
    System.Threading.Thread.Sleep(500);
    f.钱 = f.钱 - 500;
    Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString());
    }
    } // 如果玩游戏,则引发事件
    public class 小张
    {
    // 先定义一个事件,这个事件表示“小张”在玩游戏。
    public event PlayGameHandler PlayGame;
    // 保存小张钱的变量
    private int m_Money; public 小张()
    {
    Console.WriteLine("生成小张....");
    m_Money = 1000; // 构造函数,初始化小张的钱。
    } public int 钱 // 此属性可以操作小张的钱。
    {
    get
    {
    return m_Money;
    }
    set
    {
    m_Money = value;
    }
    } public void 玩游戏()
    {
    Console.WriteLine("小张开始玩游戏了.....");
    Console.WriteLine("小张:CS好玩,哈哈哈! 我玩.....");
    System.Threading.Thread.Sleep(500);
    System.EventArgs e = new EventArgs();
    OnPlayGame(e);
    } protected virtual void OnPlayGame(EventArgs e)
    {
    if(PlayGame != null)
    {
    PlayGame(this,e);
    }
    }
    } // 定义委托处理程序
    public delegate void PlayGameHandler(object sender,System.EventArgs e);
    }
      

  23.   

    TO: TomMax(笑望人生)  精彩!!!!!!!!学习中.........