最近在部落格裡看見,有位朋友在研究如何? 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
}
}