ActiveX对象自定义事件不显示结果

时间:2015-02-08 15:07:51

标签: javascript c# html com event-handling

TL / DR

我创建的托管C#COM可见对象有一个事件。在" OnCardRead"方法(触发实际事件)我检查事件是否订阅,它是。 javascript中的事件回调代码似乎永远不会被调用。

故事

项目很简单。创建一个"打开"一个rfid设备并返回卡的序列号。那部分有自己的单元测试,工作得很好。如果串行端口地址设置为0,以帮助我自我调试,那么它使用我的MockRfidSDK。但是为了彻底彻底,这里的代码(减去实际的RFID代码)。

IRfidDevice

[Guid("E86A9038-368D-4e8f-B389-FDEF38935B2F"), InterfaceType(ComInterfaceType.InterfaceIsDual), ComVisible(true)]
public interface IRfidDevice
{
    [DispId(1)]
    int Open();

    [DispId(2)]
    int Close();

    [DispId(3)]
    void SetComPort(int comport);

    [DispId(4)]
    void FlashLed(int led);
}

IRfidEvent

[ComVisible(true), GuidAttribute("0422D916-C11A-474e-947D-45A107038D12"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface IRfidEvent
{
    [DispIdAttribute(0x60020000)]
    void CardUidReceived(byte sak, ushort atq, string uid);
}

RfidSdk / EmptyRfidSdk

internal interface RfidSdk
{
    void Open();
    int GetCard();
    byte[] SelectCard();
    int Close();
    void FlashLed(int led);
}

class EmptyRfidSdk : RfidSdk
{
    public void Open()
    {
    }

    public int GetCard()
    {
        System.Threading.Thread.Sleep(10);
        return 0x0344;
    }

    public byte[] SelectCard()
    {
        System.Threading.Thread.Sleep(2000);
        return new byte[] { 0x20, 0x44, 0x03, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 };
    }

    public int Close()
    {
        return 0;
    }

    public void FlashLed(int led)
    {
    }
}

RfidDevice

[Guid("873355E1-2D0D-476f-9BEF-C7E645024C32"), ProgId("MasterRDActiveX.RfidDevice"), ClassInterface(ClassInterfaceType.None), ComDefaultInterface(typeof(IRfidDevice)), ComVisible(true), ComSourceInterfaces(typeof(IRfidEvent))]
public class RfidDevice : InternetSafeObject, IRfidDevice
{
    private RfidSdk sdk;
    private bool _searchForCard = false;

    [ComVisible(false)]
    public delegate void RfidEventHandler(byte sak, ushort atq, string uid);

    public event RfidEventHandler CardUidReceived;

    public int Open()
    {
        try
        {
            sdk.Open();
            _searchForCard = true;
            Task.Factory.StartNew(SearchForCard);
            return 0;
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.Message);
            return -1;
        }
    }

    public int Close()
    {
        try
        {
            _searchForCard = false;
            sdk.Close();
            sdk = null;
            return 0;
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.Message);
            return -1;
        }
    }

    public void SetComPort(int comport)
    {
        if (sdk != null) Close();
        if (comport < 1)
        {
            sdk = new EmptyRfidSdk();
        }
        else
        {
            sdk = new MasterRDWrapper.MasterRD(comport);
        }
    }

    public void FlashLed(int led)
    {
        sdk.FlashLed(led);
    }

    private void SearchForCard()
    {
        while (_searchForCard)
        {
            int temp = 0;
            while ((temp = sdk.GetCard()) == 0)
            {
            }
            if (temp == sdk.GetCard())
            {
                var card = sdk.SelectCard();
                FireCardUidReceived(card[0], BitConverter.ToUInt16(card, 1), card.Skip(3).ToArray());
            }
        }
    }

    private void FireCardUidReceived(byte sak, ushort atq, byte[] uid)
    {
        if (CardUidReceived != null)
        {
            Console.Beep(1000,100);
            CardUidReceived(sak, atq, BitConverter.ToString(uid));
        }
        else
        {
            Console.Beep(2000, 2000);
        }
    }

所以代码工作得很好。记住哔哔声。短蜂鸣声表示事件已订阅,长蜂鸣声表示它未被订阅。

现在网页上的内容对我来说有点模糊。我在这里看了很多ActiveX教程是关于HTML代码的一些规则。它不能使用已弃用的HTML标记(IE ... OBJECT)。到目前为止,这是我的解决方案

rfidScript.js

function onRfidCard(a, b, c) {
    console.log('I am in your event');
    document.getElementById('result').innerHTML = c;
    console.log('all done in your event');
}
function tryRfid(rfidDevice) {
    var uidTag = document.getElementById('result');
    var comPort =  parseInt(document.getElementById('comPortBox').value);

    if (rfidDevice != null) {
        rfidDevice.SetComPort(comPort);
        if (rfidDevice.Open() === 0) {
            uidTag.innerHTML = "Please Tap Card";
        }
        else {
            document.getElementById('error').innerHTML = "Failed to Open";
        }
    }
}
function closeRfid(rfidDevice) {
    rfidDevice.Close();
}

最后一位是html代码

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>RFID ActiveX Test</title>
    <!--//C:\Users\snyder\Source\Repos\xPD\MasterRDActiveX\MasterRDActiveX\bin\Debug\testRfid.html-->
    <script type="text/javascript">
        var ctrl = new ActiveXObject('MasterRDActiveX.RfidDevice');
        eval('function ctrl::CardUidReceived(a,b,c){ onRfidCard(a,b,c); }');
    </script>
    <script src="rfidScript.js"></script>
</head>
<body>
    <h1>This is our Active X Test Page for RFID</h1>
    <input type="text" id="comPortBox" /> <br />
    <button type="button" onclick="tryRfid(ctrl);">Open</button>
    <button type="button" onclick="closeRfid(ctrl);">Close</button>
    <h2>
        <output id="error" style="color: red;"></output>
        <output id="result"></output>
    </h2>

</body>
</html>

我启动IE,在文本框中输入0,单击打开,我听到一声短促的哔声(只有一个......不知道为什么在那个上面,因为我希望每2秒发出一声哔声看到note1 ),但我没有看到结果输出标签中显示任何文字(我尝试使用警报无效。)为什么??????我错过了什么?

注1 - 早些时候,当我发出长长的哔哔声时,它会像我期望的那样一遍又一遍地发出哔哔声。

0 个答案:

没有答案