c# - 从静态方法调用实例方法
问题描述
我正在尝试使用全局挂钩来检测输入事件(鼠标单击、键盘键)并使用检测来触发另一个事件,例如存储鼠标坐标。我找到的代码确实有效,但我不能以相同的形式调用另一个方法,因为 hookProc 设置为静态。
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 消息框会显示。我知道 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);
}
}
}
解决方案
正如您已经猜到的那样,问题在于您正在创建 Form1 的新实例并尝试更新新实例中的 TextBox 值。您需要的是当前打开的相同实例。
假设您只有一个 Form1 实例,您可以使用它 Application.OpenForms
来获取所有 Open Forms 的集合并用于Enumerable.OfType
过滤 Form1 类型。
例如
var formInstance = Application.OpenForms.OfType<Form1>().Single();
formInstance.TriggeredEvent();
formInstance.textBox1.Text = "3";
推荐阅读
- swt - 我应该如何在 SWT 中显示 Pagebook 控件?
- angular - 在 Visual Studio 中以本地生产模式构建 Angular
- python - 用 PyQt5 绘制轮廓非常慢
- python-3.x - Python3 抓取一页的所有信息
- python - 来自不同行的增长文本文件的Python readline增量
- php - 在 drupal 8 自定义模块中,创建 Excel 文件,写入数据并使用密码锁定文件?
- php - PHP如何计算一个数组?
- transactions - Italian Action 上的交易 API
- scala - 在 pyspark 集群纱线提交中的 spark-sftp jar 中出现错误
- python - 使用 Scrapy 提取所有正文(仅限文本)