最近遇到需要屏蔽工作列的右鍵快顯功能表問題,小費了番周折,寫出來希望對需要的人有協助。
網上查了半天資料,修改註冊表可以實現,但有個缺點需要重啟機器,甚為不爽。還有用滑鼠鉤子截獲滑鼠右鍵訊息來達到目的,這裡需要注意一點,當滑鼠右鍵釋放時菜單才會彈出(由於開始只截獲了滑鼠按下的訊息,程式一直不靈,一度懷疑用鉤子實現的可能性,哎,細心細心啊)。
關於c#調用Windows API和鉤子的使用,資料很多就不細說了。可以參考
http://blog.csdn.net/LeoMaya/archive/2007/05/18/1615052.aspx
http://blog.csdn.net/wztgq/archive/2006/08/02/1012132.aspx
還有兩個Api的瀏覽器,相當不錯
FoxAPI中文函數瀏覽器V1.5(有詳細的Api函數的說明)
API Explorer V2.82(可以把Api函數轉換成C#和VB.Net代碼)
在Visual Studio 2005中調試通過,工程可在http://download.csdn.net/source/536490下載
///Author:danseshi///Email:danseshi@yahoo.com.cn///Bolg:http://blog.csdn.net/danseshi////Date:2008.7.12using System;using System.Windows.Forms;using System.Drawing;using System.Runtime.InteropServices;using System.Diagnostics;namespace MouseHook{ public partial class Form1 : Form { #region Fields private int hMouseHook = 0; //全域鉤子常量 private const int WH_MOUSE_LL = 14; //聲明訊息的常量,滑鼠按下和釋放 private const int WM_RBUTTONDOWN = 0x204; private const int WM_RBUTTONUP = 0x205; //儲存工作列的矩形地區 private Rectangle taskBarRect; private Rectangle newTaskBarRect; //定義委託 public delegate int HookProc(int nCode, int wParam, IntPtr lParam); private HookProc MouseHookProcedure; #endregion #region 聲明Api函數,需要引入空間(System.Runtime.InteropServices) //尋找合格視窗 [DllImport("user32.dll", EntryPoint = "FindWindow")] public static extern int FindWindow( string lpClassName, string lpWindowName ); //擷取視窗的矩形地區 [DllImport("user32.dll", EntryPoint = "GetWindowRect")] public static extern int GetWindowRect( int hwnd, ref Rectangle lpRect ); //安裝鉤子 [DllImport("user32.dll")] public static extern int SetWindowsHookEx( int idHook, HookProc lpfn, IntPtr hInstance, int threadId ); //卸載鉤子 [DllImport("user32.dll", EntryPoint = "UnhookWindowsHookEx")] public static extern bool UnhookWindowsHookEx( int hHook ); //調用下一個鉤子 [DllImport("user32.dll")] public static extern int CallNextHookEx( int idHook, int nCode, int wParam, IntPtr lParam ); //擷取當前線程的標識符 [DllImport("kernel32.dll")] public static extern int GetCurrentThreadId(); //擷取一個應用程式或動態連結程式庫的模組控制代碼 [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name); //滑鼠結構,儲存了滑鼠的資訊 [StructLayout(LayoutKind.Sequential)] public struct MOUSEHOOKSTRUCT { public Point pt; public int hwnd; public int wHitTestCode; public int dwExtraInfo; } #endregion public Form1() { InitializeComponent(); } /// <summary> /// 安裝鉤子 /// </summary> private void StartHook() { if (hMouseHook == 0) { hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); if (hMouseHook == 0) {//如果設定鉤子失敗. this.StopHook(); MessageBox.Show("Set windows hook failed!"); } } } /// <summary> /// 卸載鉤子 /// </summary> private void StopHook() { bool stop = true; if (hMouseHook != 0) { stop = UnhookWindowsHookEx(hMouseHook); hMouseHook = 0; if (!stop) {//卸載鉤子失敗 MessageBox.Show("Unhook failed!"); } } } private int MouseHookProc(int nCode, int wParam, IntPtr lParam) { if (nCode >= 0) { //把參數lParam在記憶體中指向的資料轉換為MOUSEHOOKSTRUCT結構 MOUSEHOOKSTRUCT mouse = (MOUSEHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MOUSEHOOKSTRUCT));//滑鼠 //這句為了看滑鼠的位置 this.Text = "MousePosition:" + mouse.pt.ToString(); if (wParam == WM_RBUTTONDOWN || wParam == WM_RBUTTONUP) { //滑鼠按下或者釋放時候截獲 if (newTaskBarRect.Contains(mouse.pt)) { //當滑鼠在工作列的範圍內 //如果返回1,則結束訊息,這個訊息到此為止,不再傳遞。 //如果返回0或調用CallNextHookEx函數則訊息出了這個鉤子繼續往下傳遞,也就是傳給訊息真正的接受者 return 1; } } } return CallNextHookEx(hMouseHook, nCode, wParam, lParam); } #region Events private void Form1_Load(object sender, EventArgs e) { MouseHookProcedure = new HookProc(MouseHookProc); //taskBarHandle為返回的工作列的控制代碼 //Shell_TrayWnd為工作列的類名 int taskBarHandle = FindWindow("Shell_TrayWnd", null); //獲得工作列的地區 //有一點要注意,函數返回時,taskBarRect包含的是視窗的左上方和右下角的螢幕座標 //就是說taskBarRect.Width和taskBarRect.Height是相對於螢幕左上方(0,0)的數值 //這與c#的Rectangle結構是不同的 GetWindowRect(taskBarHandle, ref taskBarRect); this.richTextBox1.Text = "taskBarRect.Location:" + taskBarRect.Location.ToString() + "/n"; this.richTextBox1.Text += "taskBarRect.Size:" + taskBarRect.Size.ToString() + "/n/n"; //構造一個c#中的Rectangle結構 newTaskBarRect = new Rectangle( taskBarRect.X, taskBarRect.Y, taskBarRect.Width - taskBarRect.X, taskBarRect.Height - taskBarRect.Y ); this.richTextBox1.Text += "newTaskBarRect.Location:" + newTaskBarRect.Location.ToString() + "/n"; this.richTextBox1.Text += "newTaskBarRect.Size:" + newTaskBarRect.Size.ToString(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.StopHook(); } private void button1_Click(object sender, EventArgs e) { this.StartHook(); this.button1.Enabled = false; this.button2.Enabled = true; } private void button2_Click(object sender, EventArgs e) { this.StopHook(); this.button1.Enabled = true; this.button2.Enabled = false; } #endregion }}