windows 桌面开发 - 子类化控件(不用任何WinAPI),演示拦截Button的WM_LBUTTONDBLCLK

最近在博客里看见,有位朋友在研究如何实现 button 的双击
网址: http://www.cnblogs.com/adaiye/archive/2008/10/16/button_doubleclick2.html

    他是用代码实现的其实他的精神是值得学习的,不过在按钮上加双击事件事情本身是比较囧的呵呵、我看过了了这篇文章后感慨万分,看来很多窗口开发相关的技能(所谓技能就是组成某种技术的最小单元,技术是指如何运用技能)可能园子里很多朋友还不是很熟悉(没有卖弄的意思啊),特此化几分钟时间写了点代码贴在这里,供大家学习参考、windows 开发老鸟可以直接无视这篇文章;

    其实本代码段最主要是以一种外挂的方式,拦截窗口上的控件事件(windows 消息)前提是控件本身并没有实现,比如代码中的 WM_LBUTTONDBLCLK 消息 button 并没有提供相应的事件封装 (按钮双击没有意义,请不要模仿),主要为了解决一些代码比较少的操作,如果是比较多的代码最好封装成控件,便于重用;

    多年不进行 windows 桌面开发了很多地方可能写的有些问题,请见谅,代码很简单我就不过多注释了;

 

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;

namespace  WindowsApplication1
{
    
public   partial   class  Form1 : Form
    {
        
// 窗口上就一个按钮 Form1.Designer.cs 就不贴了

        
// 这个类在代码后边有说明
        SubClassManager scm;
        
public  Form1()
        {
            InitializeComponent();
            
// 1) 子类化控件并映射处理函数
            scm  =   new  SubClassManager( this .button1.Handle); 
            scm.SubClassWindowProc 
+=  button1_WndProc;  // 事件映射
        }

        
protected   override   void  OnHandleDestroyed(EventArgs e)
        {
            
// 3) 释放
            scm.Dispose();
            
base .OnHandleDestroyed(e);
        }
                
        
        
protected   bool  button1_WndProc( ref  Message m)
        {
            
// 2)这里可以接到 button1 的任何消息
            
            
// 按钮双击, .net 没有封装这个事件,这里只是为了演示子类话
            
// 按钮双击没有意义,请不要模仿
             const   int  WM_LBUTTONDBLCLK  =   0x0203 ;
            
            
if  (m.Msg  ==  WM_LBUTTONDBLCLK)
            {
                Console.WriteLine(
" WM_LBUTTONDBLCLK " );  // 填写你的处理代码
            }        
            
            
return   true ;
        }

        
    }
    
    
///   <summary>
    
///  本类用于子类化控件或窗口,拦截一些.net 没有封装的消息(窗口重写 WndProc 即可不要使用本类)
    
///   </summary>
     public   class  SubClassManager : System.Windows.Forms.NativeWindow,IDisposable
    {
        
public   delegate   bool  SubClassWndProc( ref  Message m);  // 消息处理函数委托
        
        
private  IntPtr handle;        
        
private   bool  disposed  =   false ;

        
        
public   event  SubClassWndProc SubClassWindowProc;  // 消息处理事件
        
        
public  SubClassManager(IntPtr hWnd)
        {
            handle 
=  hWnd;
            
this .AssignHandle(handle);            
        }

        
protected   override   void  WndProc( ref  Message m)
        {
            
if  (SubClassWindowProc  !=   null )
            {
                
if (SubClassWindowProc( ref  m))
                {
//  如果返回 true 调用基础类
                     base .WndProc( ref  m);
                }
            }            
        }

        
#region  IDisposable 成员
        
~ SubClassManager()
        {
            Console.WriteLine(
" 请释放 SubClassManager " );
            Dispose(
false );
        }
        
private   void  Dispose( bool  disposing)
        {
        
            
if  ( ! this .disposed)
            {
                
if  (disposing)
                {
                    
this .ReleaseHandle();
                }                
                
            }
            disposed 
=   true ;
        }

        
public   void  Dispose()
        {
            Dispose(
true );
        }

        
#endregion
    }
}

你可能感兴趣的:(windows)