轉(zhuǎn)帖|其它|編輯:郝浩|2012-01-29 23:38:08.000|閱讀 407 次
概述:本文主要介紹通過監(jiān)聽Windows消息對復合控件進行整體控制,希望對大家有幫助。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在開發(fā)Winform復合控件時,有很多時候需要對控件進行整體的控制,比如監(jiān)聽鼠標的進入、移出而對控件進行渲染,對鍵盤事件時行控件,而這些對一個復合控件來說,實現(xiàn)起來是相當困難的,假如一個復合控件里面有10子控件,很難對每個控件進行事件監(jiān)聽,而且邏輯也不好做。在本人開發(fā)的控件中,起先曾試過對每個控件的事件時行監(jiān)聽,一大堆地代碼和實現(xiàn)算法,最終也達不到效果,后來決定放棄這種做法。有一次,做一個模仿VS的IDE的設計器功能,最初沒有探索到使用VS自帶的DesignSurface的類,就通過監(jiān)聽Windows的消息來實現(xiàn),完成后雖然沒有VS的IDE設計器的效果好,但使用的感覺也比較接近(后幾次改進,最終還是使用DesignSurface類實現(xiàn)一個通過的設計器,非常好的應用到所有項目中去),雖然設計器的最后沒有使用到消息監(jiān)聽,但回過頭想下以前的復合控件,如通過消息機制實現(xiàn),既簡單,又能完全解決需求,于是對現(xiàn)在的監(jiān)聽消息代碼作重新設計,完成一個通用的對復合控件進行整體監(jiān)聽的一個功能類。主要思想是:
1、監(jiān)聽進程的有關的鼠標和鍵盤消息。
2、通過反射調(diào)用控件的標準的鼠標和鍵盤方法(保護方法,如:OnMouseMove、OnMouseEnter等)。
3、允許用戶過濾部分消息。(參考Framework中相關事件參數(shù)中的Cancel屬性)
主要實現(xiàn):
實現(xiàn) IMessageFilter 接口,同時訂閱Applaction的消息。
Code highlighting produced by Actipro CodeHighlighter (freeware)//www.CodeHighlighter.com/-->using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Drawing;
namespace LC.MessageListen
{
/// <summary>
/// 監(jiān)聽應用程序的消息,對復合控件的部分消息進行一個整體的控件,
/// 允許控件訂閱消息,自動執(zhí)行控件的方法,包括私有方法等。
/// MessageListener會自動調(diào)用AddMessageFilter和移除,當控件銷毀前應執(zhí)行UnRegist方法。
/// 父與子同時做訂閱,如不能達到要求,可以父與子各創(chuàng)建一個MessageListener實例。
/// </summary>
public class MessageListener : IMessageFilter
{
通過一個集合保存需要進行控件的復合控件
Dictionary<int, RegistControlWrapper> m_RegistControls = new Dictionary<int, RegistControlWrapper>();
int 為控件的句柄,RegistControlWrapper封裝了控件訂閱了哪些事件。
訂閱的事件種類規(guī)定如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)//www.CodeHighlighter.com/--> const string _OnMouseHover = "OnMouseHover";
const string _OnMouseWheel = "OnMouseWheel";
const string _OnKeyDown = "OnKeyDown";
const string _OnKeyUp = "OnKeyUp";
const string _OnMouseEnter = "OnMouseEnter";
const string _OnMouseLeave = "OnMouseLeave";
const string _OnMouseDown = "OnMouseDown";
const string _OnMouseUp = "OnMouseUp";
const string _OnMouseMove = "OnMouseMove";
const string _OnMouseClick = "OnMouseClick";
const string _OnMouseDoubleClick = "OnMouseDoubleClick";
兩個公有方法,一個注冊控件,和取消控件注冊的方法
Code highlighting produced by Actipro CodeHighlighter (freeware)//www.CodeHighlighter.com/--> /// <summary>
/// 注冊一個監(jiān)聽的控件。
/// </summary>
/// <param name="wrapper"></param>
public void Regist(RegistControlWrapper wrapper)
{
lock (m_lckObj)
{
m_RegistControls[wrapper.Handle] = wrapper;
if (m_RegistControls.Count == 1)
{
Application.AddMessageFilter(this);
}
}
}
/// <summary>
/// 取消控件的監(jiān)聽消息。
/// </summary>
/// <param name="handle"></param>
public void UnRegist(int handle)
{
lock (m_lckObj)
{
if (m_RegistControls.ContainsKey(handle))
m_RegistControls.Remove(handle);
if (m_RegistControls.Count <= 0)
{
Application.RemoveMessageFilter(this);
}
}
}
這兩個方法根據(jù)集合是否為空自動增加和移除對進程消息的監(jiān)聽。
還有一個單例的方法
public static MessageListener GetInstance()
{
lock (insLock)
{
if (instance == null)
instance = new MessageListener();
}
return instance;
}
同時保留用戶可能創(chuàng)建多實例的功能,這個在后來的應用中還是解決了其他的問題。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡轉(zhuǎn)載