从静态方法中调用实例方法

时间:2019-12-25 05:25:44

标签: c# winforms

我正在尝试使用全局挂钩来检测输入事件(单击鼠标,键盘键),并使用该检测来触发另一个事件,例如存储鼠标坐标。我找到的代码可以正常工作,但是由于hookProc设置为static,因此无法以相同的形式调用其他方法。

public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);

                if (vkCode.ToString() == "162") //162 is ASCI CTRL
                {
                    MessageBox.Show("CTRL");            
                    Form1 Trigger = new Form1(); // Supposed to allow calls to Form1, specifically textBox1
                    Trigger.textBox1.Text = "3"; // Will not change the Text value
                }
                return (IntPtr)1;
            }
            else
                return CallNextHookEx(hhook, code, (int)wParam, lParam);
        }

我知道代码有效,因为将显示CTRL MessageBox。我知道textBox1.Text =“ 3”;因为我可以在实例中的其他地方使用该代码而不会出现问题。我搜索并发现我需要创建一个form1的新实例,以便调用在静态hookProc之外找到的方法。我的代码没有给我任何构建错误,但对textBox1没有任何作用。即使我想在检测到CTRL时调用另一个方法,也无法链接到hookProc之外的任何内容。帮助吗?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetHook(); // Set the hook
        }
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            UnHook(); // Remove the hook
        }

        // GLOBAL HOOK
        [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);

        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);

        [DllImport("user32.dll")]
        static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

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

        const int WH_KEYBOARD_LL = 13; // Number of global LowLevel- hook on the keyboard
        const int WM_KEYDOWN = 0x100; // Messages pressing

        private LowLevelKeyboardProc _proc = hookProc;

        private static IntPtr hhook = IntPtr.Zero;

        public void SetHook()
        {
            IntPtr hInstance = LoadLibrary("User32");
            hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
        }

        public static void UnHook()
        {
            UnhookWindowsHookEx(hhook);
        }

        public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);

                if (vkCode.ToString() == "162") //162 is ASCI CTRL
                {
                    MessageBox.Show("CTRL");            
                    Form1 Trigger = new Form1(); // Allows called to Form1, specifically textBox3
                    Trigger.TriggeredEvent(); //Visual confirmation of CTRL has been detected
                    Trigger.textBox1.Text = "3";
                }
                return (IntPtr)1;
            }
            else
                return CallNextHookEx(hhook, code, (int)wParam, lParam);
        }

    }
}

1 个答案:

答案 0 :(得分:2)

您可能已经猜到了,问题在于您正在创建Form1的新实例,并尝试在新实例中更新TextBox Value。您需要的是当前打开的同一实例。

假设您只有一个Form1实例,则可以使用Application.OpenForms获取所有打开的表单的集合,并使用Enumerable.OfType来过滤Form1类型。

例如

var formInstance = Application.OpenForms.OfType<Form1>().Single();
formInstance.TriggeredEvent();
formInstance.textBox1.Text = "3";