如果有高手能详细解释最好不过。

解决方案 »

  1.   

    帮你顶,有的话,给我也发一个,谢谢了。
    [email protected]
      

  2.   

    就简单的读写吗?你用API写了以后封装到DLL就可以了。
      

  3.   

    API没用过,
    能用控件吗?
    如SPCOMM
      

  4.   

    unit comdemou;
    interface
    uses
      Windows, Messages, SysUtils, Classes, 
    Graphics, Controls, Forms, Dialogs;const
         Wm_commNotify=Wm_User+12;
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        Procedure comminitialize;
    Procedure MsgcommProcess(Var 
    Message:Tmessage); Message Wm_commnotify;
        { Private declarations }
      public
        { Public declarations }
      end;  //线程声明
      TComm=Class(TThread)
      protected
         procedure Execute;override;
      end;var
      Form1: TForm1;
      hcom,Post_Event:Thandle;
      lpol:Poverlapped;
    implementation{$R *.DFM}Procedure TComm.Execute; //线程执行过程
    var
    dwEvtMask:Dword;
    Wait:Boolean;
    Begin
    fillchar(lpol,sizeof(toverlapped),0);
    While True do Begin
          dwEvtMask:=0;
          Wait:=WaitCommEvent(hcom,dwevtmask,lpol);  
     //等待串行口事件;
          if Wait Then Begin
             waitforsingleobject(post_event,infinite); 
    //等待同步事件置位;
             resetevent(post_event);  //同步事件复位;
             PostMessage(Form1.Handle,
    WM_COMMNOTIFY,0,0);//发送消息;
             end;
          end;
    end;procedure Tform1.comminitialize;  
    //串行口初始化
    var
    lpdcb:Tdcb;
    Begin
    hcom:=createfile('com2',generic_read or
     generic_write,0,nil,open_existing,
    file_attribute_normal or
     file_flag_overlapped,0);//打开串行口
        if hcom=invalid_handle_value then
        else
            setupcomm(hcom,4096,4096); 
    //设置输入,输出缓冲区皆为4096字节
            getcommstate(hcom,lpdcb); 
    //获取串行口当前默认设置
            lpdcb.baudrate:=2400;
            lpdcb.StopBits:=1;
            lpdcb.ByteSize:=8;
            lpdcb.Parity:=EvenParity;     //偶校验
            Setcommstate(hcom,lpdcb);
            setcommMask(hcom,ev_rxchar); 
    //指定串行口事件为接收到字符;
    end;Procedure TForm1.Msgcomm
    Process(Var Message:Tmessage);
    var
    Clear:Boolean;
    Coms:Tcomstat;
    cbNum,ReadNumber,lpErrors:Integer;
    Read_Buffer:array[1..100]of char;
    Begin
    Clear:=Clearcommerror(hcom,lpErrors,@Coms);
    if Clear Then Begin
       cbNum:=Coms.cbInQue;
       ReadFile(hCom,Read_Buffer,
    cbNum,ReadNumber,lpol);
       //处理接收数据
       SetEvent(Post_Event);    
    //同步事件置位
       end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    comminitialize;
    post_event:=CreateEvent
    (nil,true,true,nil); //创建同步事件;
    Tcomm.Create(False);   
    //创建串行口监视线程;
    end;end.
      

  5.   

    写成DLL没什么区别的
    自己改一下
      

  6.   

    代码我就不贴上来了,你过去看看人家是怎么写的,参考一下:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1349809
      

  7.   

    mscomm32.ocx微软的串口控件,
    vc++的盘上就有
      

  8.   

    接口函数应用实例(DELPHI开发示例) --------------------------------------------------------------------------------
     
    一、函数声明:procedure PostPara(port:integer;syspara:pchar);stdcall;external 'lock739.dll'; 
    function Reset:integer; stdcall;external 'lock739.dll'; 
    function OpenCom:boolean;stdcall;external 'lock739.dll'; 
    procedure CloseCom;stdcall;external 'lock739.dll'; 
    function ChkCard:integer;stdcall;external 'lock739.dll'; 
    function CmpSc(sc:pchar):integer;stdcall;external 'lock739.dll'; 
    function WriteSc(sc:pchar):integer;stdcall;external 'lock739.dll'; 
    function ReadSc(inbuff:pchar;sclen:integer):integer;stdcall; external 'lock739.dll'; 
    function RdDat(cardtype,start,len:integer;inbuff:pchar):integer;stdcall; external 'lock739.dll'; 
    function WrDat(cardtype,start,len:integer;outbuff:pchar):integer;stdcall;external 'lock739.dll'; 二、源码节选: unit fMain; 
    interface 
    uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,ExtCtrls,ComCtrls ; 
    type 
    TForm1 = class(TForm) 
    RG1: TRadioGroup; 
    StatusBar1: TStatusBar; 
    Edit1: TEdit; 
    Edit2: TEdit; 
    Edit3: TEdit; 
    Label1: TLabel; 
    Label2: TLabel; 
    Button1: TButton; 
    Button2: TButton; 
    Button3: TButton; 
    Label3: TLabel; 
    Label4: TLabel; 
    procedure FormShow(Sender: TObject); 
    procedure Button3Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure RG1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    sc:array[0..3] of char; //存储卡密码; 
    iStart,iLen:integer; //读写卡起始地址及读写字节长度; 
    Procedure ErrorMessage(iError:integer); //显示错误信息 
    { Public declarations }
    end; var 
    Form1: TForm1;
    implementation 
    uses DllDef; //接口函数声明; 
    {$R *.DFM} 
    procedure TForm1.FormShow(Sender: TObject); 
    begin 
    //卡密码3个Byte: 
    sc[0]:=chr(strtoint('$FF')); 
    sc[1]:=chr(strtoint('$FF')); 
    sc[2]:=chr(strtoint('$FF')); 
    //传入读写器使用串口 
    PostPara(RG1.ItemIndex+1,NIL); 
    end; procedure TForm1.Button3Click(Sender: TObject); 
    begin 
    Application.Terminate; 
    end; //读到卡数据 
    procedure TForm1.Button2Click(Sender: TObject); 
    var 
    i:integer; 
    str1:array[0..255] of char; //存储读取的卡数据 
    str2:string; 
    begin 
    try 
    iStart:=strtoint(Edit2.Text); 
    iLen:=strtoint(edit3.Text); 
    except 
    Application.MessageBox('请正确输入读写起始地址和长度!','提示信息',64); 
    StatusBar1.Panels[1].Text:=''; 
    Exit; 
    end; //打开串口 
    if not OpenCom() then begin 
    Application.MessageBox('串口连接失败!','提示信息',64); 
    StatusBar1.Panels[1].Text:=''; 
    Exit;
    end; 
    //检查卡是否到位 
    i:=ChkCard(); 
    if (i<>0) then begin 
    ErrorMessage(i); 
    StatusBar1.Panels[1].Text:=''; 
    CloseCom(); 
    Exit; 
    end; 
    //读卡信息;
    i:=RdDat(1,iStart,iLen,str1); 
    if (i<>0) then begin 
    ErrorMessage(i); 
    CloseCom(); 
    Exit; 
    end; 
    for i:=0 to iLen-1 do 
    str2:=str2+str1[i]; 
    StatusBar1.Panels[1].Text:=str2; 
    end; //写卡数据 
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
    i:integer; 
    begin 
    try 
    iStart:=strtoint(Edit2.Text); 
    iLen:=strtoint(edit3.Text); 
    except 
    Application.MessageBox('请正确输入读写起始地址和长度!','提示信息',64); 
    StatusBar1.Panels[1].Text:=''; 
    Exit; 
    end; //打开串口 
    if not OpenCom() then begin 
    Application.MessageBox('串口连接失败!','提示信息',64); 
    StatusBar1.Panels[1].Text:=''; 
    Exit; 
    end; 
    //检查卡是否到位 
    i:=ChkCard(); 
    if (i<>0) then begin 
    ErrorMessage(i); 
    StatusBar1.Panels[1].Text:=''; 
    CloseCom(); 
    Exit; 
    end; 
    //核对卡密码 
    i:=CmpSc(sc); 
    if (i<>0) then begin 
    ErrorMessage(i); 
    CloseCom(); 
    Exit; 
    end; 
    i:=WrDat(1,iStart,iLen,pchar(edit1.Text)); 
    if (i<>0) then begin 
    ErrorMessage(i); 
    CloseCom(); 
    Exit; 
    end 
    else begin 
    Application.MessageBox('写卡成功!','提示信息',64); 
    CloseCom(); 
    end; 
    end; procedure TForm1.RG1Click(Sender: TObject); 
    begin 
    PostPara(RG1.ItemIndex+1,NIL); 
    end; procedure TForm1.ErrorMessage(iError:integer); 
    begin 
    case iError of 
    1: Application.MessageBox('写入错误或密码错误','提示信息',64);
    2: Application.MessageBox('卡已损坏或参数越界','提示信息',64);
    3: Application.MessageBox('请插卡!','提示信息',64);
    4: Application.MessageBox('通信错误!','提示信息',64) 
    else
    Application.MessageBox('未知错误!','提示信息',64); 
    end; 
    end; 
    end. 
     
      

  9.   

    With MSComm
            If .PortOpen = True Then .PortOpen = False
            .CommPort = 1  '这里是串口号
            .Settings = "9600,N,8,1"  '设置参数
            .InputLen = 0  
            .InputMode = comInputModeBinary  ' 以二进制的方式读入
            .PortOpen = True   '打开串口
            .RThreshold = 83 '当缓冲区接受大于设置时引起ONCOMM事件
            
     End With
    然后:
    Public Sub DoComPort(oComm As MSComm)
       
        Dim InString As Variant
        InString = oComm.Input '这里的InStrig 是读入的东西了
        
    End Sub
      

  10.   

    To:hsmserver(撒哈拉之雨的悲伤) 你用的是API函数做的,可是这里的代码里只有一部分的API函数,那像向串口发送数据这样的API函数是什么呢?还有一些相关的API函数呢?
      

  11.   

    已经在用的节选
    library TonyDLL;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      SysUtils,
      Windows,
      Classes,
      Graphics;
    Type
      TSimpleComm = Packed Record
        CommName : Pchar;
        BaudRate : Dword;           //current baud rate
        ByteSize : Byte;             // number of bits/byte, 4-8
        Parity : Byte;               // 0-4=no,odd,even,,space
        StopBits : Byte;            // 0,1,2 = 1, 1.5, 2
      end;{$R *.res}Function OpenComm(SimpleComm:TSimpleComm;var CommHandle:Thandle):Byte;stdcall;
    var
      DCB:TDCB;
    begin
      Result:=0;
      CommHandle := CreateFile(SimpleComm.CommName,
                   Generic_Read Or Generic_Write,
                   0,
                   nil,
                   OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL,0);
                   //Generic_Read or Generic_Write, 0,nil,Open_Existing,File_Attribute_Normal,0
      if CommHandle =INVALID_HANDLE_VALUE then
      begin
        Result:=9;
        Exit;
      end;
      if not SetupComm(CommHandle,1024,1024) then
      begin
        CloseHandle(CommHandle);
        Result:=11;
        Exit;
      end;
      if not PurgeComm(CommHandle,Purge_TXClear or Purge_RXClear or
                                    Purge_RXAbort or Purge_TxAbort)then
      begin
        Result:=14;
        exit;
      end;
      If not GetCommState(CommHandle,DCB) then
      begin
        CloseHandle(Commhandle);
        Result:=12;
        Exit;
      end;
      DCB.BaudRate := SimpleComm.BaudRate ;
      DCB.ByteSize := SimpleComm.ByteSize ;
      DCB.StopBits := SimpleComm.StopBits ;
      DCB.Parity := SimpleComm.Parity ;
      If not SetCommState(CommHandle,DCB) then
      begin
        CloseHandle(Commhandle);
        Result:=13;
        Exit;
      end;
    end;Function ReadLongCom(Const CommHandle:THandle;
                         Var DataBlk:TDataBlock;
                         var DataSize:LongWord;
                         Const TimeOutSec:Byte;
                         Var ErrorVal:Byte):Boolean;stdcall;
    var
      ComStat:TComStat;
      Time:TDateTime;
      Comm_Read_Bytes:LongWord;
      Buf:Byte;
    begin
      Result:=true;
      ErrorVal:=0;
      Time:=now+TimeOutSec/(3600*24);
      DataSize:=0;
      if not chkdog then
      begin
        Result:=false;
        ErrorVal:=71;
        exit;
      end;  
      While true do
      begin
        ClearCommError(Commhandle,Comm_Read_Bytes,@Comstat);
        if Comstat.cbInQue = 0 then
        begin
          If Time < Now then
          begin
            Result:=false;
            ErrorVal:=10;
            Break;
          end
          else
          begin
            continue;
            sleep(1);
          end;
        end;
        //the cbInQue > 1 the
        Time:=now+TimeOutSec/(3600*24); //reset the timeout begin
        inc(DataSize);
        Setlength(DataBlk,DataSize);
        Result:=ReadFile(commhandle,Buf,1,Comm_Read_Bytes,nil);
        if not Result then
        begin
          Errorval:=15;
          Break
        end;
        DataBlk[DataSize-1]:=buf;
        if buf = 27 then //识别结束,或者是操作字符
        begin
          Result:=ReadFile(commhandle,Buf,1,Comm_Read_Bytes,nil);
          if not Result then
          begin
            Errorval:=15;
            Break;
          end;
          if buf <> 27 then
          begin
            inc(DataSize);
            Setlength(DataBlk,DataSize);
            DataBlk[DataSize-1]:=buf;
            if buf =3 then
            Break;
          end;
        end;
      end;
      if Result then
      begin
        if DataBlk[1] = 21 then
        begin
          Result:=false;
          Errorval := DataBlk[3];
        end;
      end;
    end;
    exports
    Opencomm;
    begin
    end.