首页 > 代码库 > 类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法 续集

类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法 续集

类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法 续集

接上文

今天突然发现键盘控制不行了,结果还是那个问题搞的鬼,原以为解决了,但是紧接着问题又来了,汗颜啊,将钩子封装成dll

前台调用实例如下

CHW.HookHelper hook;  //钩子

<span style="font-family:Microsoft YaHei;font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:18px;">private void MainForm_Activated(object sender, EventArgs e)
        {
            //注册事件
            hook = new CHW.HookHelper();
            hook.SetHook();
            hook.OnKeyDownEvent += new KeyEventHandler(hook_OnKeyDownEvent);
            hook.OnKeyUpEvent += new KeyEventHandler(hook_OnKeyUpEvent);
        }</span></span>

<span style="font-family:Microsoft YaHei;font-size:18px;"><pre name="code" class="csharp">private void MainForm_Leave(object sender, EventArgs e)
        {
            //注销钩子事件
            hook.UnHook();
        }
void hook_OnKeyUpEvent(object sender, KeyEventArgs e)
        {
            if (chkbAllowKeyboard.Checked)
            {
                //按了左键  按了右键  按了上键  按了下键 之后放起操作
                if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
                    btn_MouseUp(sender, null);
            }
        }

        /// <summary>
        /// 钩子程序控制,键盘作用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void hook_OnKeyDownEvent(object sender, KeyEventArgs e)
        {
            if (chkbAllowKeyboard.Checked)
            {
                if (e.KeyCode == Keys.Left)
                {
                    //按下左键
                    btnLeft.Focus();
                    btnLeft_MouseDown(sender, null);
                }
                if (e.KeyCode == Keys.Right)
                {
                    //按下右键
                    btnRight.Focus();
                    btnRight_MouseDown(sender, null);
                }
                if (e.KeyCode == Keys.Up)
                {
                    //按下上键
                    btnFront.Focus();
                    btnFront_MouseDown(sender, null);
                }
                if (e.KeyCode == Keys.Down)
                {
                    //按下下键
                    btnBack.Focus();
                    btnBack_MouseDown(sender, null);
                }
            }
        }
</span>
然后经过一般搜索查找,方法如下:

<span style="font-family:Microsoft YaHei;font-size:18px;"><pre name="code" class="csharp">private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            try
            {
                //如果该消息被丢弃(nCode<0)或者没有事件绑定处理程序则不会触发事件
                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct KeyDataFromHook = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                    Keys keyData = http://www.mamicode.com/(Keys)KeyDataFromHook.vkCode;>
</pre><pre name="code" class="csharp"><span style="font-family:Microsoft YaHei;font-size:18px;">如果将上述修改为:return 0;则不会出问题,此时只有一个钩子的话就没有问题,如果有多个钩子大于2个以上就会有问题了</span>
</pre><p><span style="font-family:Microsoft YaHei;font-size:18px;"></span></p><p><span style="font-family:Microsoft YaHei;font-size:18px;">上篇文章代码中出现问题的部分代码改成源代码如下:</span></p><p><pre name="code" class="csharp"><span style="font-family:Microsoft YaHei;font-size:18px;">public void SetHook()
        {
            //KeyboardHookDelegate = KeyboardHookProc;
            KeyboardHookDelegate = new HookProc(KeyboardHookProc);
            Process cProcess = Process.GetCurrentProcess();
            ProcessModule cModule = cProcess.MainModule;
            IntPtr intPtr = GetModuleHandle(cModule.ModuleName);
            hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, intPtr, 0);
            if (hHook == 0)
            {
                UnHook();
                //throw new Exception(Marshal.GetLastWin32Error().ToString());
            }
        }</span>








类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法 续集