delphi中比较常用的是spcomm这个控件,或者直接用api写多线程程序

解决方案 »

  1.   

    如果,有什么问题,发邮件给我,我这里有源程序:[email protected]
      

  2.   

    下面的程序是我自己写的用在工业控制上的一个线程,你可以参考一下。   TMon = class(TThread)
          private
             pt : integer;
             ph: string;
             LineOff : Boolean;
             Lasttime : TDatetime;
             lastmodemstatus : Dword;
             CmdBuf : array [1..10] of _Cmd;
             lCmd,rCmd : integer;
             procedure WriteCmd;                    //写出命令并负责读回数据
             procedure CheckLineStatus;             //主循环调用,检测线路状态
             procedure SendToMaster(msgstr:string); //发送消息到主应用程序
          public
             ready : Boolean;
             constructor create(port:integer;phone:string);
             procedure WriteToCache(Cmd:_CMD);
          protected
             procedure Execute; Override;
       end;
      

  3.   

    procedure TMon.SendToMaster(msgstr:string);
    var
       s : string;
    begin
       if msgstr <> '' then begin
          s := msgstr +#0;
          PostMessage(application.handle,wm_mymessage,0,LongInt(s));
       end;
    end;
    procedure TMon.WriteToCache(Cmd:_Cmd);
    begin
       Cmdbuf[rCmd] := Cmd;
       inc(rCmd);
       if rCmd = 11 then rCmd := 1;
    end;
    procedure TMon.WriteCmd;
    procedure UPdateMeterInfo(Cmd:_CMD);
    var
       Q : TQuery;
       MeterNo : integer;
       metertype : integer;
       id,pwd : string;//还没有处理寄存器数据,因为寄存器数据必须是由系统设置
       Pm : Pchar;
       SQL : string;
    begin
       MeterNo := 0;
       Pm := @MeterNo;
       pm[0] := CMD[headlen+3];pm[1] := CMD[headlen+4];pm[2] := CMD[headlen+5];pm[3] := CMD[headlen+6];
       metertype := 0;
       pm := @Metertype;
       pm[0] := cmd[headlen+7];
       id := GetID(cmd);
       pwd := GetPwd(Cmd);
       Sql := 'update meterinfo set metertype ='+inttostr(metertype)+', id='''+id+''', pwd = '''+pwd+''''
                +' where (MeterNo='+inttostr(MeterNo)+') and (CenterID ='+inttostr(OPCenter)+')';
       Q := TQuery.Create(nil);
       Q.DatabaseName := 'A';
       Q.SQL.Text := SQL;
       Q.ExecSQL;
       Q.free;
    end;
    procedure EnterMeter(Cmd:_CMD);
    var
       Q,QInsert : TQuery;
       SQL,SQLInsert : String;
       MeterNums,i,MeterNo,Position : integer;
       PMeterNums : Pchar;
    begin
       MeterNums := 0;
       PMeterNums := @MeterNums;
       //取得表数
       PMeterNums[0] := Cmd[headlen+3]; PMeterNums[1] := Cmd[headlen+4];
       Position := HeadLen + 5;
       for i := 1 to MeterNums do
       begin
          PMeterNums := @MeterNo;
          PMeterNums[0] := cmd[Position+0];PMeterNums[1] := cmd[Position+1];
          PMeterNums[2] := cmd[Position+2];PMeterNums[3] := cmd[Position+3];
          Position := Position + 4;
          SQL := 'Select * from MeterInfo where (MeterNo = '+Inttostr(MeterNo)+') and (CenterID ='+inttostr(OpCenter)+')';
          Q := TQuery.Create(nil);
          Q.DatabaseName := 'A';
          Q.SQL.TExt := SQL;
          Q.Active := True;
          if Q.Eof then begin
             QInsert := TQuery.Create(nil);
             QInsert.DatabaseName := 'A';
             SQLInsert := 'Insert Into MeterInfo (MeterNo,MeterName,CenterID) values ('+Inttostr(meterNo)+',''读来的电能表'','+inttostr(OpCenter)+')';
             QInsert.SQL.Text := SQLInsert;
             QInsert.ExecSQL;
             QInsert.free;
          end;
          Q.Free;
       end;
    end;
    var
       s : string;
       l : integer;
       Code : char;
       thisCmd : _Cmd;
       ret : integer;
    begin
       if CmdBuf[lCmd] = '' then exit;
       thisCmd := CmdBuf[lCmd];
       CmdBuf[lCmd] := '';
       inc(lCmd);
       if lCmd = 11 then lcmd := 1;
       
       l := Ord(thisCmd[7])+6;
       sio_flush(pt,2); 
       ret := sio_write(pt,@thiscmd[1],l);
       if ret = l then lasttime := now;
       code := GetCode(thisCMD);
       CASE CODE OF
            KeepConnectCmd    :s :=timetostr(now)+'保持连接。';
            HangePhone        :s := '挂机。';
            ReadCenterTime    :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thiscmd,3) then
                                  s := '集中器当前时间:'+toTimestr(@thiscmd[9])
                               else
                                  s := '读集中器时间没有完成。';
            SetCenterTime     :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '设集中器时间完成。'
                               else
                                  s := '没集中器时间没有完成。';        ReadCenterVer     :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '集中器版本: '+inttostr(ord(thiscmd[8]))+' Ver'
                               else
                                  s := '读集中器版本没有完成。';
            ReadCenterInt     :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '集中器抄表间隔时间:'+GetCenterInt(@thiscmd)
                               else
                                  s := '读集中器抄表时间间隔没有完成。';
            SetCenterInt      :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '设集中器抄表间隔成功。'
                               else
                                  s := '设集中器抄表间隔没有完成。';
            ReadMeterNums     :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '集中器所属电表总数:'+GetCenterInt(@thiscmd)
                               else
                                  s := '读集中器所属电表总数没有完成。';
            ReadMetersNo      :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                               begin
                                  EnterMeter(THIScMD);
                                  s := '读集中器所有表号完成。'
                               end
                               else
                                  s := '读集中器所有表号没有完成。';
            ReadMetersInfo    :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                               begin
                                  UPdateMeterInfo(thisCmd);
                                  s := '读表信息完成。'
                               end
                               else
                                  s := '读表信息没有完成。';
            EditMeterInfo     :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '增加表信息完成。'
                               else
                                  s := '增加表信息没有完成。';
            DeleMeterInfo     :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '删除表记录完成。'
                               else
                                  s := '删除表记录没有完成。';
            ClearCenterInfo   :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '集中器数据清除完成。'
                               else
                                  s := '集中器数据清除没有完成。';
            ReadCenterRunTime :if WaitForChar(pt,#$FF,2) then
                               if WaitAnswer(pt,thisCmd,3) then
                                  s := '集中器起始时间:'+toTimestr(@thiscmd[9])
                               else
                                  s := '读集中器起始时间没有完成。';
            ReadCenterRecord  :   s :='该功能只在自动抄表时有效。';
       end;
       SendToMaster(s);
    end;
    procedure TMon.CheckLineStatus ;
    var
       thistime : Tdatetime;
       Cmd : _CMD;
       thismodemstatus : Dword;
    begin
       thismodemstatus := sio_lstatus(Pt);
       if (not((thismodemstatus and s_cd)=s_cd) and ((lastmodemstatus and s_cd)=s_cd)) then LineOff := true ;
       lastmodemstatus := thismodemstatus;
       thistime := now;
       if (thistime - lasttime) > (15/(24*60*60)) then begin
          Cmd := BuildCmd(KeepConnectCmd);
          WriteToCache(CMD);
       end;
       WriteCmd;
       LineOff := false;
    end;
    procedure TMon.Execute;
    var
       Cmd : _CMD;
    begin
       if DailAndWaitConnection(pt,ph) then
          While (Not Terminated) and (not LineOff) do
          begin
             Synchronize(CheckLineStatus);
             sleep(100);
             ready := true;
          end;
       ready := false;
       if LineOff then SendToMaster('断线了。')
       else begin
          Cmd := BuildCmd(HangePhone);
          WriteToCache(Cmd);writecmd;sleep(300);
          HangLine(pt);
          SendToMaster('线程结束。');
       end;
    end;
    constructor TMon.Create(port:integer;phone:string);
    begin
       pt  := port;
       ph := phone;
       FreeOnTerminate := True;
       LineOff := false;
       lCmd := 1;
       rcmd := 1;
       inherited Create(False);
    end;
      

  4.   

    Delphi中用MSCOMM控件我有例子(很简单),需要的话请说一声:[email protected]