2012-03-12 67 views
0

这似乎是一个我不明白的基本概念。修改传递给事件处理程序的结构体?

在写一个.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事件修改structStroke

下不起作用:

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

在此先感谢。

+0

使'stroke'为空可以将你的实际值放入一个包含指示值是否存在的布尔值的包装器中。包装值从一开始就是一个值类型。 – 2012-03-12 04:24:55

+1

除了@ EricJ。的评论,可以为null的类型本身也是值类型,尽管值类型从编译器中获得了很多特殊的处理。 – phoog 2012-03-13 04:43:45

回答

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

给你的用户的副本,然后将其复制回本地值一旦他们用它做。

或者,您可以创建自己的代表击键的类并将其传递给用户?

+0

完美地工作,对于简单的问题抱歉。 – Jason 2012-03-12 05:08:48

1

在KeyPressedEventArg的构造函数中传递你的结构体是通过引用传递的,但那就是它,任何时候中风变量被修改它都是通过值传递的。如果你不断传递这个结构体,你可能会考虑为它创建一个包装类。长远来看,更好的设计决策。

相关问题