windows 案頭開發 – 子類化控制項(不用任何WinAPI),示範攔截Button的WM_LBUTTONDBLCLK

來源:互聯網
上載者:User

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.