这个条码枪会读取数据到“超级终端”好像就是COM口我找了个JustinIO.cs类,里面有读取方法,但是在什么触发事件里面写呢?VS2003,没有SerialPort控件JustinIO.cs里面有个字段:
public char EvtChar;            // 当接收到此字符时,会产生一个事件 received event character 
但是没有什么事件能触发的就算在里面写事件,怎么个写法呢?。。对COM不是很熟,谢谢

解决方案 »

  1.   

    2003中都用MSComm32.ocx。
    那个类库没有监听线程。要自己创建。
      

  2.   

    我用个while循环,不停的读取,有数据就行?这样行不?
      

  3.   

    最好别这么干,如果单用个线程这么死循环。会让cpu占用率是100%。2003还是就用MSCOMM32.OCX方便。或是找找其他的代码。微软貌似还有一个比较好使的。
    给你贴一个04年搜集的代码,基于2003的
      

  4.   

    /* 
     * 本程序主要使用WIN32中的操作文件的API函数来操作串口。
     * 考虑到操作的串口不能正常工作的情况,使用了事件驱动的异步机制,以及多线程技术。
     * 
     * 如在网上公开本程序的全部或核心源码,希望能保留这部分信息。谢谢!
     * 如有什么问题,可以和我(pantian)联系:[email protected] 或 [email protected]
    */
    using System;
    using System.Runtime.InteropServices;  //操作WIN32的API
    using System.Threading;                //操作多线程namespace TestComm
    {
    public class NetComm
    {
    #region 常量定义
    private  int  hComm = -1;
         
    //win32 api constants 
    private const uint GENERIC_READ = 0x80000000;
    private const uint GENERIC_WRITE = 0x40000000;
    private const int  OPEN_EXISTING = 3;
    private const int  INVALID_HANDLE_VALUE = -1;           //无效句柄
    private const uint FILE_FLAG_OVERLAPPED = 0x40000000;   //异步通讯 //pugre
    private const int PURGE_TXABORT  = 0x0001;   //中止后台写操作
    private const int PURGE_RXABORT  = 0x0002;   //中止后台读操作
    private const int PURGE_TXCLEAR  = 0x0004;   //清除发送缓冲区
    private const int PURGE_RXCLEAR  = 0x0008;   //清除接收缓冲区 //error
    private const int ERROR_IO_PENDING = 997;
    private const int ERROR_IO_INCOMPLETE = 996;
    private System.Windows.Forms.TextBox txtInput;
    private System.Windows.Forms.TextBox txtOutput;
    private System.Windows.Forms.Button btnNull; private const int EV_RXCHAR = 0x0001;
    #endregion #region Struct
    [StructLayout(LayoutKind.Sequential)]
    private struct DCB
    {
    public int DCBlength;      // sizeof(DCB)
    public int BaudRate;       //指定当前的波特率
    public int Flags; public ushort wReserved;  // not currently used
    public ushort XonLim;     // transmit XON threshold 
    public ushort XoffLim;    // transmit XOFF threshold  
    public byte ByteSize;     //指定端口当前使用的数据位
    public byte Parity;       //指定端口当前使用的奇偶校验方法
    public byte StopBits;     //指定端口当前使用的停止位数
    public sbyte XonChar;     //指定用于发送和接收字符XON的值
    public sbyte XoffChar;    //指定用于发送和接收字符XOFF值 
    public sbyte ErrorChar;   //本字符用来代替接收到的奇偶校验发生错误时的值
    public sbyte EofChar;     //当没有使用二进制模式时,本字符可用来指示数据的结束
    public sbyte EvtChar;     //当接收到此字符时,会产生一个事件
    public ushort wReserved1; //未使用
    } [StructLayout(LayoutKind.Sequential)]
    private struct COMMTIMEOUTS         //超时设置
    {
    public int ReadIntervalTimeout;
    public int ReadTotalTimeoutMultiplier;
    public int ReadTotalTimeoutConstant;
    public int WriteTotalTimeoutMultiplier;
    public int WriteTotalTimeoutConstant;
    } [StructLayout(LayoutKind.Sequential)]    
    private struct OVERLAPPED  
    {
    public int  Internal;  
    public int  InternalHigh;  
    public int  Offset;  
    public int  OffsetHigh;  
    public int  hEvent;  
    } [StructLayout(LayoutKind.Sequential)]    
    private struct COMSTAT  
    {
      public int fCtsHold; // Tx waiting for CTS signal
       public int fDsrHold; // Tx waiting for DSR signal
       public int fRlsdHold; // Tx waiting for RLSD signal
       public int fXoffHold; // Tx waiting, XOFF char rec`d
       public int fXoffSent; // Tx waiting, XOFF char sent
       public int fEof; // EOF character sent
       public int fTxim; // character waiting for Tx
       public int fReserved; // reserved
       public int cbInQue; // bytes in input buffer
       public int cbOutQue; // bytes in output buffer
    }
    #endregion #region DllImport
    [DllImport("kernel32")] 
    private static extern int CreateFile( 
    string lpFileName,                        //指明串口设备
    uint dwDesiredAccess,                     //指明串口存取方式
    int dwShareMode,                          //指明串口共享方式
    int lpSecurityAttributes,                 //指明串口的安全属性结构,NULL为缺省安全属性
    int dwCreationDisposition,                //必须为OPEN_EXISTIN
    uint dwFlagsAndAttributes,                //对串口唯一有意义的是FILE_FLAG_OVERLAPPED
    int hTemplateFile                         //必须为NULL
    ); [DllImport( "kernel32")] 
    private static extern bool ReadFile( 
    int hFile,                     // handle to file 
    byte[] lpBuffer,               // data buffer 
    int nNumberOfBytesToRead,      // number of bytes to read 
    ref int lpNumberOfBytesRead,   // number of bytes read 
    ref OVERLAPPED lpOverlapped    // overlapped buffer 
    ); [DllImport("kernel32")] 
    private static extern bool WriteFile( 
    int hFile,                         // handle to file 
    byte[] lpBuffer,                   // data buffer 
    int nNumberOfBytesToWrite,         // number of bytes to write 
    ref int lpNumberOfBytesWritten,    // number of bytes written 
    ref OVERLAPPED lpOverlapped        // overlapped buffer 
    ); [DllImport("kernel32")] 
    private static extern bool CloseHandle( 
    int hObject   // handle to object 
    ); [DllImport("kernel32")]
    private static extern bool PurgeComm(
    int hFile,
    int dwFlags
    ); [DllImport("kernel32")]
    private static extern bool GetCommState( 
    int hFile,       // handle to communications device 
    ref DCB lpDCB    // device-control block 
    ); [DllImport("kernel32")] 
    private static extern bool SetCommState( 
    int hFile,       // handle to communications device 
    ref DCB lpDCB    // device-control block 
    ); [DllImport("kernel32")]    
    private static extern bool SetCommTimeouts( 
    int hFile,                       // handle to comm device 
    ref COMMTIMEOUTS lpCommTimeouts  // time-out values 
    ); [DllImport("kernel32.dll")]
    static extern int CreateEvent(
    int eventAttributes, 
    bool manualReset, 
    bool initialState, 
    string name
    ); [DllImport("kernel32.dll")]
    private static extern bool GetOverlappedResult(
    int hFile, 
    ref OVERLAPPED lpOverlapped,
    ref int nNumberOfBytesTransferred, 
    bool bWait
    ); [DllImport("kernel32.dll")]
    private static extern uint GetLastError(); [DllImport("kernel32.dll")]
    private static extern bool SetupComm(
       int hFile, // handle of communications device
       int dwInQueue, // size of input buffer
       int dwOutQueue // size of output buffer
       ); [DllImport("kernel32.dll")]
    private static extern bool SetCommMask(
    int hFile,
    int dwEvtMask
    ); [DllImport("kernel32.dll")]
    private static extern bool WaitCommEvent(
    int hFile,
    ref int lpEvtMask,
    ref OVERLAPPED lpOverlapped
    ); [DllImport("kernel32.dll")]
    private static extern bool ClearCommError(
    int hFile,
    ref int lpErrors,
    ref COMSTAT lpStat
    );
    #endregion #region 变量定义
    public bool IsOpened = false;
    #endregion
    代码太长,分段
      

  5.   

    #region 打开串口
    /// <summary>
    /// 打开串口
    /// </summary>
    /// <param name="PortNum"><summary>串口号 1--COM1</summary></param>
    /// <param name="BaudRate"><summary>波特率</summary></param>
    /// <returns></returns>
    public bool OpenCom(int PortNum, int BaudRate)  
    {        
    //打开串口
    hComm = CreateFile("COM" + PortNum, GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); //如果串口已经被打开,
    if(hComm != INVALID_HANDLE_VALUE)  

    //设置输入(1024)、输出(512)缓冲区的大小
    SetupComm(hComm, 1024, 512); //清干净输入、输出缓冲区
    PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); /////////定义超时结构,并填写该结构
    COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); //设置读写操作所允许的超时,全部为0,则为无限等待,即无超时
    ctoCommPort.ReadIntervalTimeout = 0; 
    ctoCommPort.ReadTotalTimeoutConstant = 0; 
    ctoCommPort.ReadTotalTimeoutMultiplier = 0; 
    ctoCommPort.WriteTotalTimeoutMultiplier = 0; 
    ctoCommPort.WriteTotalTimeoutConstant = 0;   
    SetCommTimeouts(hComm,ref ctoCommPort);  ////////定义数据控制块结构
    DCB dcbCommPort = new DCB(); //读串口原来的参数设置
    GetCommState(hComm, ref dcbCommPort);  //设置串口的状态BaudRate,Parity,ByteSize,StopBits
    dcbCommPort.Flags =0;
    dcbCommPort.Flags |=1; dcbCommPort.BaudRate = BaudRate;    //波特率
    dcbCommPort.ByteSize = 8;           //数据位(默认=8)
    dcbCommPort.Parity   = 0;           //奇偶校验(默认=0,0-4=no,odd,even,,space)
    dcbCommPort.StopBits = 1;           //停止位(默认=0,0,1,2)
    SetCommState(hComm, ref dcbCommPort);  //设置事件驱动的类型,使用事件驱动异步机制
    SetCommMask(hComm, EV_RXCHAR);

    IsOpened = true;
    }
    return IsOpened;
    }
    #endregion #region 关闭串口
    /// <summary>
    /// 关闭串口
    /// </summary>
    public void CloseCom()  

    if (hComm!=INVALID_HANDLE_VALUE)  

    CloseHandle(hComm); 

    IsOpened = false;
    }
    #endregion #region 从串口读取数据
    private byte[] BufBytes;
    private int error =0;
    private bool WFlag = true;   //允许写 标志 /// <summary>
    /// 从串口读取数据
    /// </summary>
    /// <param name="NumBytes"><summary>需读取的字节的长度</summary></param>
    /// <param name="Time"><summary>设置取数据的最长时间,单位:毫秒</summary></param>
    /// <param name="OutBytes"><summary>读出来的数据</summary></param>
    /// <returns></returns>
    public int ReadForCom(int NumBytes, int Time, ref byte[] OutBytes)
    {
    BufBytes = new byte[NumBytes];
    error = 1;
    WFlag = false; ThreadStart ts = new ThreadStart( ReadComm );
    Thread t = new Thread(ts); t.IsBackground = true;
    t.Start();          //启动线程
    t.Join(Time);       //设置线程最长等待时间
    t.Abort();          //强行终止线程 if(error == 0)
    {
    OutBytes = new byte[NumBytes];
    Array.Copy(BufBytes,OutBytes,NumBytes);
    } WFlag = true;
    return error;
    } //从串口读数据
    private void ReadComm()  

    if( hComm!=INVALID_HANDLE_VALUE )

    OVERLAPPED ovlCommPort = new OVERLAPPED();
    ovlCommPort.hEvent = CreateEvent(0,true,false,null); int BytesRead = 0;
    bool t = true;
    while(t)
    {
    int dwEvent = 0;
    WaitCommEvent(hComm,ref dwEvent,ref ovlCommPort);   //等待串口通信事件的发生
    if(dwEvent == EV_RXCHAR)     //缓冲区中有数据到达
    {
    COMSTAT ComStat = new COMSTAT();
    int dwErrorFlags=0;
    ClearCommError(hComm, ref dwErrorFlags, ref ComStat);
    if(ComStat.cbInQue == 0)
    {
    bool hCommRead = false;
    hCommRead= ReadFile(hComm,BufBytes,BufBytes.Length,ref BytesRead,ref ovlCommPort);
    if((!hCommRead) && (GetLastError()==ERROR_IO_PENDING))
    {
    while(!GetOverlappedResult(hComm,ref ovlCommPort,ref BytesRead,true))

    if(GetLastError()==ERROR_IO_INCOMPLETE)   continue;
    break;
    }
    }
    if(BufBytes.Length == BytesRead) t = false;    //读完数据
    }
    }
    }
    error = 0;  //置错误标志位
    }  
    else  
    {
    throw(new ApplicationException("Comm Port Not Open")); 
    }
    }
    #endregion #region 往串口写数据
    /// <summary>
    /// 往串口写数据
    /// </summary>
    /// <param name="WriteBytes"><summary>需要往串口写的数据</summary></param>
    public void WriteToCom(byte[] WriteBytes)  

    while(!WFlag);  //判断是否可以往串口写数据 if(hComm!=INVALID_HANDLE_VALUE)  

    //清干净输入、输出缓冲区
    PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); OVERLAPPED ovlCommPort = new OVERLAPPED();
    ovlCommPort.hEvent = CreateEvent(0,true,false,null); COMSTAT ComStat = new COMSTAT();
    int dwErrorFlags=0;
    ClearCommError(hComm, ref dwErrorFlags, ref ComStat); int BytesWritten = 0;
    bool fWriteStat = WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort);
    if(!fWriteStat && GetLastError() == ERROR_IO_PENDING)
    {
    while(!GetOverlappedResult(hComm,ref ovlCommPort, ref BytesWritten, true))
    {
    if( GetLastError() == ERROR_IO_INCOMPLETE ) continue;
    }
    }
    CloseHandle(ovlCommPort.hEvent);//关闭事件

    else  

    throw(new ApplicationException("Comm Port Not Open"));
    }
    }
    #endregion }//public class
    }//namespace