2013-07-23 85 views
1

設置全局鉤子SetWindowsHookEx標準窗體的按鈕後奇怪地工作。例如,如果我點擊關閉按鈕,然後鼠標凍結5-10秒,並形成。SetWindowsHookEx並單擊窗體凍結時的最小化/最大化/關閉按鈕

我發現有同樣問題的主題C# low level mouse hook and form event handling 但只有一個答案。我不喜歡這種解決方案,因爲它需要每次Hook,當表單停用時,以及UnHook,當程序激活時...

有沒有更好的方法來解決這個問題?

編輯

這裏是我的代碼:

using System.Windows.Forms; 
using Gma.UserActivityMonitor; 
using System; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace WinFormsHook 
{ 
    public partial class Form1 : Form 
    { 
     int s_MouseHookHandle; 

     public Form1() 
     { 
      InitializeComponent(); 
      IntPtr hInst = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); 
      s_MouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInst, 0); 
     } 

     private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      UnhookWindowsHookEx(s_MouseHookHandle); 
     } 

     private int MouseHookProc(int nCode, int wParam, IntPtr lParam) 
     { 
      if (nCode >= 0) 
      { 
       Debug.WriteLine(wParam); 
       if (wParam == WM_LBUTTONDOWN) 
       { 
        Action action =() => this.Text += "."; 
        this.Invoke(action); 
       } 
      } 

      //call next hook 
      return CallNextHookEx(s_MouseHookHandle, nCode, wParam, lParam); 
     } 

     private const int WH_MOUSE_LL = 14; 
     private const int WM_LBUTTONDOWN = 0x201; 

     private delegate int HookProc(int nCode, int wParam, IntPtr lParam); 

     [DllImport("kernel32.dll")] 
     public static extern IntPtr GetModuleHandle(string name); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] 
     private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] 
     private static extern int UnhookWindowsHookEx(int idHook); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
     private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); 
    } 
} 
+0

這是一種全球性的鉤子嗎? –

+0

@KingKing,是的。這是MouseDoubleClick事件的鉤子 –

+0

一旦用戶雙擊,你會做什麼?你需要使用鉤子嗎?我問的是爲什麼你這樣做,因爲可能有另一種方式。 – TheKingDave

回答

1

你需要一個句柄本機模塊。不要指望這會作爲全局鉤子工作:你的鉤子實現需要.NET JIT執行!

事實上,每個非託管進程都無法執行您的處理程序!我想這是系統塊的原因。

...

後重新閱讀你的代碼看起來你不想全局鉤子(「本」在其他流程的meanng)。因此,SetWindowsHookEx的RTFM並適當地設置最後一個參數。我建議an old question of mine

相關問題