本文介绍了如何事件附加到动态对象或COM对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得跟我有同样的问题。不过,对我来说,没有可行的解决方案。

I think this article has the same problem with me. However, there's no workable solution for my case.

我在我的程序使用Windows Media Player的ActiveX。

I'm using Windows Media Player ActiveX in my program.

由于某种原因,我不希望添加它的一个参考,并转换为AxHost由IDE自动。

For some reason, I don't want to add a reference of it and convert to AxHost automatically by IDE.

我创建通过激活和进程id

protected const string WMP_PROG_ID = "WMPlayer.OCX.7";

private dynamic _wmp;

protected virtual bool init(){
    try{
        _wmp = Activator.CreateInstance(Type.GetTypeFromProgID(WMP_PROG_ID));
    }
    catch{ return false; }
    return true;
}



我试图通过来做到这一点的反思,但我发现动态适合我的情况。

I was tried to do this by Reflection, but I found that dynamic is suitable to my case.

每个属性和方法的作品好吧,像这样的:

Every property and method works alright, like these:

protected override bool setSpeed(float speed){
    try{
        _wmp.settings.rate = speed;
    }
    catch { return false; }
    return true;
}

protected override int getLength(){
    double res;
    try{
        res = _wmp.currentMedia.duration;
    }
    catch { return 0; }
    return (int)(res * 1000);
}



不幸的是,当我想附上事件类似的表示//stackoverflow.com/questions/8694235/attach-event-to-dynamic-object\">the文章,它有没有工作。

Unfortunately, when I want to attach event like the article I indicated in the top, it got no work.

我这样的代码:

protected bool connectEvent(){
_wmp.StatusChange += new EventHandler(_wmp_StatusChange);
    return true;
}

protected void _wmp_StatusChange(object sender, EventArgs e){
    Console.WriteLine(_wmp.Status);
}



我检查的事件处理程序的类型StatusChange ,这是事件处理程序

这些代码编译好,我可以加载一些音乐,播放,暂停,......做任何我喜欢的。

These codes compiled well, and I can load some music, play it, pause it, ...do anything I like.

StatusChange 事件触发从未

我试图设置为 connectEvent 一个突破点。

I tried to set a break-point at connectEvent.

当在 _wmp.StatusChange + =新的EventHandler运行(...)中,的IntelliTrace给我一些信息。

When run at _wmp.StatusChange += new EventHandler(...), the IntelliTrace give me some information.

这些信息写在岛。中国人,我认为这意味着:

Those information had written in Trad. Chinese, I think it means:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException :无法使用操作符+ = 键入 System.Dynamic.DynamicObject System.EventHandler

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Could not apply operator "+=" to type System.Dynamic.DynamicObject and System.EventHandler

虽然有一个例外,但就像我说的,编译通过后,一切仍然工作 - 除了我不能听的事件。

Even though there's an exception, but just like I said, compile was passed, everything still work -- except I could not listen event.

那么,如何才能我在动态对象 _wmp

So, how can I attach event successfully in the dynamic object _wmp?

任何可能的解决方案(如反射成功地把事件),对我来说非常有用。

Any possible solution (like Reflection) is useful to me.

此外,在上述的情况下,处理器类型 StatusChange 事件处理程序

Also, in the case above, the handler type of StatusChange is EventHandler.

但是,如果我想处理 PlayStateChange 事件,这是一个未知的手柄,如果我不加wmp.dll文件的参考。

But if I want to handle PlayStateChange event, it is an "Unknown handle" if I don't add a reference of wmp.dll.

我希望的解决方案是适合这种情况下,了。

I hope the solution is suitable to this case, too.

谢谢大家提前为您的支持,并请原谅我的英语不好。

Thanks everyone in advance for all of your support, and please forgive me for my poor English.

推荐答案

打开使用早期绑定到后期绑定调用COM对象的程序通用的策略是为第一写早期绑定。智能感知将帮助你成功的坑下降,确保使用正确命名方法,通过正确的参数,特别有用,帮助您找出事件处理程序的签名应该是什么样子。

The generic strategy to turn a program that uses a COM object from early bound to late bound calling is to first write it early bound. IntelliSense will help you fall in the pit of success, ensuring that you use correctly named methods, pass the right kind of arguments and particularly useful to help you find out what the event handler signatures should look like.

- 生成测试这段代码:

Which produces this bit of test code:

    void testEarlyBound() {
        var wmp = new WMPLib.WindowsMediaPlayer();
        wmp.StatusChange += new WMPLib._WMPOCXEvents_StatusChangeEventHandler(wmp_StatusChange);
    }

    void wmp_StatusChange() {
        throw new NotImplementedException();
    }



随着StatusChange事件处理程序分配和方法的身体完全自动生成通过智能感知。注意事件处理程序的签名,它的的一个事件处理程序。刚刚返回void和不带参数的方法,它的动作委托类型相匹配。现在你已经在编写后期绑定版本没有undiagnosable运行时异常好球:

With the StatusChange event handler assignment and method body completely auto-generated by IntelliSense. Note the signature of the event handler, it is not an EventHandler. Just a method that returns void and takes no arguments, it matches the Action delegate type. Now you have a good shot at writing the late-bound version without the undiagnosable runtime exceptions:

    void testLateBound() {
        dynamic wmp = Activator.CreateInstance(Type.GetTypeFromProgID("WMPlayer.OCX"));
        wmp.StatusChange += new Action(wmp_StatusChange);
    }

这篇关于如何事件附加到动态对象或COM对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

查看更多