• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
flashelf
博客园    首页    新随笔    联系   管理    订阅  订阅

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
    }
}
posted @ 2008-10-18 09:50  曲滨*銘龘鶽  阅读(3547)  评论(7)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3