轉帖|其它|編輯:郝浩|2012-01-29 23:41:49.000|閱讀 429 次
概述:前篇說了對消息監聽的一些粗的實現,現在具體說說消息監聽。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
前篇說了對消息監聽的一些粗的實現,現在具體說說消息監聽:
在實現IMessageFilter接口的成員方法PreFilterMessage做處理。
在這里,實現需要監聽的Windows消息只要有:
Code highlighting produced by Actipro CodeHighlighter (freeware)//www.CodeHighlighter.com/--> const int WM_KEYDOWN = 0x100;
const int WM_SYSKEYDOWN = 0x104;
const int WM_KEYUP = 0x101;
const int WM_SYSKEYUP = 0x105;
const int WM_MOUSEMOVE = 0x200;
const int WM_MOUSEHOVER = 0x2a1;
const int WM_MOUSELEAVE = 0x2a3;
const int WM_LBUTTONDOWN = 0x201;
const int WM_LBUTTONUP = 0x202;
const int WM_LBUTTONDBLCLK = 0x203;
const int WM_RBUTTONDOWN = 0x204;
const int WM_RBUTTONUP = 0x205;
const int WM_RBUTTONDBLCLK = 0x206;
const int WM_NCMOUSEMOVE = 0xa0;
const int WM_NCLBUTTONDOWN = 0xa1;
const int WM_NCLBUTTONUP = 0xa2;
const int WM_MOUSEWHEEL = 0x20a;
同時很感謝大家提供的精彩對鼠標消息轉換的代碼
Code highlighting produced by Actipro CodeHighlighter (freeware)//www.CodeHighlighter.com/--> //----------開源代碼----------------------
int zDelta;
private const int MK_LBUTTON = 0x0001;
private const int MK_RBUTTON = 0x0002;
private const int MK_SHIFT = 0x0004;
private const int MK_CONTROL = 0x0008;
private const int MK_MBUTTON = 0x0010;
private const int MK_XBUTTON1 = 0x0020;
private const int MK_XBUTTON2 = 0x0040;
public static int GetXLParam(int lparam) { return LowWord(lparam); }
public static int GetYLParam(int lparam) { return HighWord(lparam); }
public static int LowWord(int word) { return word & 0xFFFF; }
public static int HighWord(int word) { return word >> 16; }
public static int GetWheelDeltaWParam(int wparam) { return HighWord(wparam); }
public static MouseButtons GetMouseButtonWParam(int wparam)
{
int mask = LowWord(wparam);
if ((mask & MK_LBUTTON) == MK_LBUTTON) return MouseButtons.Left;
if ((mask & MK_RBUTTON) == MK_RBUTTON) return MouseButtons.Right;
if ((mask & MK_MBUTTON) == MK_MBUTTON) return MouseButtons.Middle;
if ((mask & MK_XBUTTON1) == MK_XBUTTON1) return MouseButtons.XButton1;
if ((mask & MK_XBUTTON2) == MK_XBUTTON2) return MouseButtons.XButton2;
return MouseButtons.None;
}
對消息的處理邏輯如下:
其他 ShowCursor(); 是一個附加的自動隱藏光標類的一個顯示方法,當我們接收到鼠標或鍵盤的動作時,就必需要顯示光標。
Code highlighting produced by Actipro CodeHighlighter (freeware)//www.CodeHighlighter.com/--> #region IMessageFilter 成員
public bool PreFilterMessage(ref Message m)
{
////System.Diagnostics.Debug.WriteLine(m);
bool isCancel = false;
switch (m.Msg)
{
case WM_MOUSEHOVER:
ProcessMouseHover(m.HWnd);
break;
case WM_MOUSEWHEEL: //鼠標滾輪
ProcessMouseWheel(ref m, ref isCancel);
break;
case WM_LBUTTONDOWN: //要處理MouseClick事件
case WM_RBUTTONDOWN:
ProcessMouseDown(ref m, ref isCancel);
break;
case WM_LBUTTONDBLCLK: //MouseDoubleClick事件
case WM_RBUTTONDBLCLK:
ProcessMouseDBCLK(ref m, ref isCancel);
break;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
ProcessMouseUp(ref m, ref isCancel);
break;
case WM_MOUSEMOVE:
ShowCursor(); //顯示光標。
ProcessMouseMove(ref m, ref isCancel);
break;
case WM_MOUSELEAVE:
ProcessMouseLeave(ref m, ref isCancel);
break;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
ShowCursor();
ProcessKeyDown(ref m, ref isCancel);
break;
case WM_SYSKEYUP:
case WM_KEYUP:
ProcessKeyUp(ref m, ref isCancel);
break;
}
return isCancel;
}
#endregion
需要注意的事項:
作為一個事件的消息控件,當控件的某一子控件產生了消息,如果控件訂閱了該消息,系統會自動調用控件相對應的方法,如OnMouseEnter等,如有需要對消息進行過濾,該消息就不會發往子控件了。對消息過濾也會產生副作用,如過濾了WM_MOUSELEAVE 消息后,當下一次鼠標再離開該子控件,就不會再發送鼠標離開的消息了,不是很Windows系統的消息機制,希望有經驗的高手作下說明。
還有,沒有鼠標進入的消息,只有鼠標移動的消息,因此,實現中要保存上一次鼠標移動的控件的標志,通過比較實現鼠標進入和移出事件。MouseUp消息也沒有 wparam 也沒有值,不能使用GetMouseButtonWParam方法。的MouseDown消息中要實現MouseClick事件,在MouseMove消息中實現MouseEnter,MouseLeave事件等。
至此一個對控件事先整體的消息控制功能完成了,該程序經測試通過,并應用到現有項目,效果非常好,只要應用在如浮動式窗口的自動隱藏、復合控件對鼠標進出而進行邊框的渲染等,希望大家能挖掘出更多的應用,并留言說說。下面附上原碼,其他有個自動隱藏光標的類,邏輯簡單,不再累贅。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:網絡轉載