鼠标不在窗体内
同时窗体不是激活的
当鼠标点左/右键时 我要执行代码
现在的问题就是
如何捕获到 鼠标左右键?

解决方案 »

  1.   

    用api 自己百度下win32 api 学习下 可以操作控制很多东西。
      

  2.   

    btn_MouseDown(object sender, MouseEventArgs e)
    事件
    e.Button判断是鼠标哪个键
            
      

  3.   

    http://www.codeproject.com/KB/cs/globalhook.aspx
      

  4.   

    http://blog.csdn.net/Nocky/archive/2010/12/28/6103875.aspx
    时面用到了WIN32 API SetWindowsHookEx,修改一下参数设成全局的就行了,可以捕捉到鼠标消息
      

  5.   

     private void panel_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)/ if (e.Button == MouseButtons.right)
    ……
    ……
      

  6.   

    showModalDialog并不创建新的浏览器窗口,也不创建新的浏览器对象,而是在WebBrowser的同一个线程中创建的窗口,而showModelessDialog( )则是在新的线程中创建的窗口,所以处理方式不相同。当showModalDialog( )被调用后,浏览器线程会创建一个对话框,该对话框包含两个窗口,父窗口的类为“Internet Explorer_TridentDlgFrame”,子窗口的类为“Internet Explorer_Server”,其子窗口即为IE内核的窗口,可以通过给该窗口发送消息,进行一些自动化操作(如按键、鼠标点击等)。当子窗口创建时,父窗口会收到WM_PARENTNOTIFY消息,hwnd值即为父窗口的值,wParam的值即为Internet Explorer_Server的窗口。我们捕获窗口后就可以捕捉到IE内核窗口的句柄了。 
    STEP 1: 建立窗口事件的钩子函数 
    // 使用Windows API函数 [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr SetWindowsHookEx(HookType hooktype, HookProcedureDelegate callback, IntPtr hMod, UInt32 dwThreadId); // Hook Types 
    public enum HookType 

        WH_JOURNALRECORD = 0, 
        WH_JOURNALPLAYBACK = 1, 
        WH_KEYBOARD = 2, 
        WH_GETMESSAGE = 3, 
        WH_CALLWNDPROC = 4, 
        WH_CBT = 5, 
        WH_SYSMSGFILTER = 6, 
        WH_MOUSE = 7, 
        WH_HARDWARE = 8, 
        WH_DEBUG = 9, 
        WH_SHELL = 10, 
        WH_FOREGROUNDIDLE = 11, 
        WH_CALLWNDPROCRET = 12, 
        WH_KEYBOARD_LL = 13, 
        WH_MOUSE_LL = 14 
    }[StructLayout(LayoutKind.Sequential)] 
            public struct CWPRETSTRUCT 
            { 
                public IntPtr lResult; 
                public IntPtr lParam; 
                public IntPtr wParam; 
                public UInt32 message; 
                public IntPtr hwnd; 
            };        // Delegate for the EnumChildWindows method 
            private delegate Boolean EnumerateWindowDelegate(IntPtr pHwnd, IntPtr pParam);private static Win32API.HookProcedureDelegate _WH_CALLWNDPROCRET_PROC = 
        new Win32API.HookProcedureDelegate(WH_CALLWNDPROCRET_PROC);// 在程序开始处调用该方法 
    public static void Hook( ) 

        if (_pWH_CALLWNDPROCRET == IntPtr.Zero) { 
            _pWH_CALLWNDPROCRET = Win32API.SetWindowsHookEx( 
                Win32API.HookType.WH_CALLWNDPROCRET 
                ,_WH_CALLWNDPROCRET_PROC 
                ,IntPtr.Zero 
                ,(uint)AppDomain.GetCurrentThreadId( ));    // current thread 
        } 
        if (_pWH_CALLWNDPROCRET == IntPtr.Zero) 
            throw new ApplicationException("Failed to install window hook via: SetWindowsHookEx( )"); 
    } // 自定义的消息钩子函数,在函数中捕捉PARENTNOTIFY消息,然后再检查该消息是否窗口创建或销毁窗口 
    // 然后创建一个个事件WindowLife,在WebBrowser中添加该事件的处理函数即可 
    public delegate void WindowLifeHandler(Win32Message msg, IntPtr parent, IntPtr child); 
    public static event WindowLifeHandler WindowLife; 
    private static Int32 WH_CALLWNDPROCRET_PROC(Int32 iCode, IntPtr pWParam, IntPtr pLParam) 

        if (iCode < 0) 
            return Win32API.CallNextHookEx(_pWH_CALLWNDPROCRET, iCode, pWParam, pLParam);    Win32API.CWPRETSTRUCT cwp = (Win32API.CWPRETSTRUCT)Marshal.PtrToStructure(pLParam, typeof(Win32API.CWPRETSTRUCT)); 
        Win32Message msg = Win32Message.WM_NULL; 
        try { 
            msg = (Win32Message)cwp.message; 
        } catch { 
            return Win32API.CallNextHookEx(_pWH_CALLWNDPROCRET, iCode, pWParam, pLParam); ; 
        } 
        if (msg == Win32Message.WM_PARENTNOTIFY) { 
            if ((int)cwp.wParam == (int)Win32Message.WM_CREATE || (int)cwp.wParam == (int)Win32Message.WM_DESTROY) { 
                System.Diagnostics.Debug.WriteLine("WM_PARENTNOTIFY hwnd=0x{0:x8}  wParam={1} lParam=0x{2:x8}" 
                    ,(int)cwp.hwnd, (Win32Message)cwp.wParam,(int)cwp.lParam); 
                if (WindowLife != null) 
                    WindowLife((Win32Message)cwp.wParam, cwp.hwnd, cwp.lParam); 
            } 
        } 
        return Win32API.CallNextHookEx(_pWH_CALLWNDPROCRET, iCode, pWParam, pLParam); 
    } STEP 2:继承WebBrowser并在派生类中添加WindowLife事件的处理函数,在派生类的构造函数中增加如下代码: 
    public class ExWebBrowser : System.Windows.Forms.WebBrowser 

         public ExWebBrowser( ) 
            { 
                _windowLifeDelegate = new WindowsMessageHooker.WindowLifeHandler(OnWindowLife); 
                WindowsMessageHooker.WindowLife += _windowLifeDelegate; 
                this.Disposed += (sender, e) => { 
                    WindowsMessageHooker.WindowLife -= _windowLifeDelegate; 
                }; private IntPtr _webPageDialogHandle = IntPtr.Zero; 
    private static readonly string IE_WebDialogClassName = "Internet Explorer_TridentDlgFrame"; 
    private static readonly string IE_ServerClassName = "Internet Explorer_Server"; public delegate void WebPageDialogHandler(IntPtr hwnd, string title); 
    // 创建网页对话框时触发的事件 
    public event WebPageDialogHandler ShowWebDialog; 
    // 关闭网页对话框时触发的事件 
    public event WebPageDialogHandler CloseWebDialog; 
    private WindowsMessageHooker.WindowLifeHandler _windowLifeDelegate = null;private void OnWindowLife(noock.windows.Win32Message msg, IntPtr parent, IntPtr child) 

        StringBuilder buffer = null; 
        string childClass = null; 
        string parentClass = null;        buffer = new StringBuilder(256); 
        if (child != _webPageDialogHandle) { 
            noock.windows.Win32API.GetClassName(child, buffer, buffer.Capacity); 
            childClass = buffer.ToString( ); 
            System.Diagnostics.Debug.WriteLine("child class:" + childClass); 
            if (childClass != IE_ServerClassName) 
                return; 
            noock.windows.Win32API.GetClassName(parent, buffer, buffer.Capacity); 
            parentClass = buffer.ToString( ); 
            System.Diagnostics.Debug.WriteLine("parent class:" + parentClass); 
            if (parentClass != IE_WebDialogClassName) 
                return; 
        }    noock.windows.Win32API.GetWindowText(parent, buffer, buffer.Capacity); 
        string title = buffer.ToString();    if (msg == noock.windows.Win32Message.WM_CREATE) { 
            _webPageDialogHandle = child; 
            System.Diagnostics.Debug.WriteLine(title, "showModalDialog( ) Opening:"); 
            if (ShowWebDialog != null) { 
                ShowWebDialog(_webPageDialogHandle, title); 
            } 
        } else if (msg == noock.windows.Win32Message.WM_DESTROY) { 
            _webPageDialogHandle = IntPtr.Zero; 
            System.Diagnostics.Debug.WriteLine(title, "showModalDialog( ) Closing:"); 
            if (CloseWebDialog != null) { 
                CloseWebDialog(child, title); 
            } 
        } 

            }这样就扩展了WebBrowser的事件,可以触发showModalDialog( )弹出对话框的弹出事件。 
    STEP3: 因为函数的钩子是使用API实现,是系统级的,所有必须在程序退出时释放钩子函数占用的资源 public static bool Hooked 

        get { return _pWH_CALLWNDPROCRET != IntPtr.Zero; } 

    public static void Unhook( ) 

        if ( ! Hooked) { 
            Win32API.UnhookWindowsHookEx(_pWH_CALLWNDPROCRET); 
        } 
    }但是,还有一个问题,这样只能捕捉到showModalDialog( )弹出的对话框,而不能捕捉到showModelessDialog( )弹出的非模态对话框,因为钩子函数在上面的代码中只捕捉主线程的消息,而非模态对话框则是单独的线程。遗憾的是SetWindowsHookEx( )不支持面向进程的钩子函数,除了面向线程就是面向全局的,捕捉整个桌面(一般相当于整个用户)的所有消息,虽然这样做也可以捕捉到相应的事件,但显然效率是比较低的。而且,非模态对话框在实际应用中并不多见。我们还可以通过一个折衷的方法,使用API来搜索WebBrowser窗口关系树中附近的窗口,看有没有其所有者是WebBrowser父窗口的网页对话框,例如代码: 
    public IntPtr WebPageDialogHandle 
            { 
                get 
                { 
                    InvokeMethod invoker = new InvokeMethod(( ) => 
                    { 
                        if (_webPageDialogHandle != IntPtr.Zero && Win32API.IsWindow(_webPageDialogHandle)) { 
                        } else { 
                            _webPageDialogHandle = SearchWebDialog(ParentForm.Handle, Win32API.GW_HWNDPREV); 
                            if (_webPageDialogHandle == IntPtr.Zero) 
                                _webPageDialogHandle = SearchWebDialog(ParentForm.Handle, Win32API.GW_HWNDNEXT); 
                        } 
                    } 
                    ); 
                    this.Invoke(invoker); 
                    return _webPageDialogHandle; 
                } 
            }private IntPtr SearchWebDialog(IntPtr start, uint direction) 
        { 
            int processId, nextProcId; 
            int threadId = Win32API.GetWindowThreadProcessId(ParentForm.Handle, out processId); 
            StringBuilder sb = new StringBuilder(256);        IntPtr nextWin = Win32API.GetNextWindow(ParentForm.Handle, direction); 
            int nextTh = Win32API.GetWindowThreadProcessId(nextWin, out nextProcId); 
            while (nextProcId == processId) { 
                if (ParentForm.Handle == Win32API.GetParent(nextWin)) { 
                    Win32API.GetClassName(nextWin, sb, sb.Capacity); 
                    if (sb.ToString() == IE_WebDialogClassName) { 
                        _webPageDialogHandle = Win32API.FindWindowExxx(nextWin, IntPtr.Zero, IE_ServerClassName, null); 
                        return _webPageDialogHandle; 
                    } 
                } 
                nextWin = Win32API.GetNextWindow(nextWin, direction); 
                nextTh = Win32API.GetWindowThreadProcessId(nextWin, out processId); 
            } 
            return IntPtr.Zero; 
        }public static IntPtr FindWindowExxx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle) 
            { 
                IntPtr res = FindWindowEx(parentHandle, childAfter, lclassName, windowTitle);             if (res != IntPtr.Zero) 
                    return res; 
                while ( (res = FindWindowEx(parentHandle, res, null, null)) != IntPtr.Zero) { 
                    IntPtr aim = FindWindowExxx(res, IntPtr.Zero, lclassName, windowTitle); 
                    if (aim != IntPtr.Zero) 
                        return aim; 
                } 
                return IntPtr.Zero; 
            } 
    其实窗口的句柄只是内核对象中的一个地址,同一个进程的窗口句柄一般也是连续,正如代码中所示,我们不需要搜索所有的窗口,而只需要进进程ID为边界在WebBrowser父窗口的附近搜索。非模态对话框的父窗口够本是桌面窗口,而不是WebBrowser所在的窗口,所以在SearchWebDialog函数中调用了GetParent函数,而没有使用GetAncestor,因为前者返回的不一定是父窗口,也可能是所有者,这正是非模态对话框与WebBrowser窗口的关系,浏览器窗口是模态对话框的父窗口,而只是非模态框的所有者,而不是其父窗口。 
    获取非模态对话框的句柄以后,就随便你对它做什么了,发送消息模拟按键、模拟鼠标点击、关闭等,都是可以的了。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Nocky/archive/2010/12/28/6103875.aspx