NachoTaco
NachoTaco

Reputation: 29

Calling instance method from static method

I am trying to use global hooks to detect input events (a mouse click, keyboard keys) and use the detection to trigger another event, such as storing the mouse coordinates. The code I've found does work, but I cannot call on another method in the same form because the hookProc is set to 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);
        }

I know the code works because the CTRL MessageBox will show. I know textBox1.Text = "3"; because I can use the code elsewhere in an instance without issue. I searched and found I need to create a new instance of form1 in order to call on methods found outside the static hookProc. My code does not give me any build errors but does not do anything in regards to textBox1. Even if I wanted to call on another method when CTRL is detected, I cannot link to anything outside hookProc. Help?

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);
        }

    }
}

Upvotes: 0

Views: 228

Answers (1)

Anu Viswan
Anu Viswan

Reputation: 18155

As you would have guessed, the issue is that you are creating a new instance of Form1 and attempting to update the TextBox Value in the new instance. What you require is the same instance which is currently open.

Assuming you have only a single instance of Form1, you can use Application.OpenForms to get collection of all Open Forms and use Enumerable.OfType to filter the Form1 Type.

For Example

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

Upvotes: 2

Related Questions