这似乎是一个我不理解的非常基本的概念。
在为键盘驱动程序编写.NET包装器时,我正在为每个按键广播一个事件,如下所示(简化代码):
// The event handler applications can subscribe to on each key press
public event EventHandler<KeyPressedEventArgs> OnKeyPressed;
// I believe this is the only instance that exists, and we just keep passing this around
Stroke stroke = new Stroke();
private void DriverCallback(ref Stroke stroke...)
{
if (OnKeyPressed != null)
{
// Give the subscriber a chance to process/modify the keystroke
OnKeyPressed(this, new KeyPressedEventArgs(ref stroke) );
}
// Forward the keystroke to the OS
InterceptionDriver.Send(context, device, ref stroke, 1);
}
笔划是struct
,其中包含按下的键的扫描码和状态。
在上面的代码中,由于我通过引用传递了值类型结构,因此对结构体所做的任何更改都将在传递给操作系统时被“记住”(以便按下并修改按下的键)。这很好。
但是,如何让OnKeyPressed
个struct
活动的订阅者修改Stroke
public class KeyPressedEventArgs : EventArgs
{
// I thought making it a nullable type might also make it a reference type..?
public Stroke? stroke;
public KeyPressedEventArgs(ref Stroke stroke)
{
this.stroke = stroke;
}
}
// Other application modifying the keystroke
void interceptor_OnKeyPressed(object sender, KeyPressedEventArgs e)
{
if (e.stroke.Value.Key.Code == 0x3f) // if pressed key is F5
{
// Doesn't really modify the struct I want because it's a value-type copy?
e.stroke.Value.Key.Code = 0x3c; // change the key to F2
}
}
?
以下不起作用:
{{1}}
提前致谢。
答案 0 :(得分:1)
这样的事情可以解决问题:
if (OnKeyPressed != null)
{
// Give the subscriber a chance to process/modify the keystroke
var args = new KeyPressedEventArgs(stroke);
OnKeyPressed(this, args);
stroke = args.Stroke;
}
为订阅者提供副本,然后在完成后将其复制回本地值。
或者,您可以创建自己的类来表示击键并将其传递给订阅者吗?
答案 1 :(得分:1)
在KeyPressedEventArg的构造函数中传递结构是通过引用传递的,但就是这样,只要修改了描边变量,它就会通过值传递。如果你继续通过ref
传递这个结构,你可能要考虑为它创建一个包装类。从长远来看,更好的设计决策。