让线程自己去等<br>下面代码希望对你有帮助,要源码请留下(win98+delphi5,无第三方控件)<br>e_main<br><br><br>unit MyComm;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> StdCtrls, ComCtrls, Buttons, ExtCtrls;<br> const<br> WM_COMMNOTIFY = WM_USER + 1; // 通讯消息<br>type<br> TForm1 = class(TForm)<br> Button1: TButton;<br> Button2: TButton;<br> OpenDialog1: TOpenDialog;<br> RichEdit1: TRichEdit;<br> RichEdit2: TRichEdit;<br> SaveDialog1: TSaveDialog;<br> BitBtn1: TBitBtn;<br> BitBtn2: TBitBtn;<br> fsdk: TRadioGroup;<br> RadioGroup2: TRadioGroup;<br> RadioGroup3: TRadioGroup;<br> RadioGroup4: TRadioGroup;<br> RadioGroup5: TRadioGroup;<br> StatusBar1: TStatusBar;<br> RadioGroup6: TRadioGroup;<br> BitBtn3: TBitBtn;<br> Label1: TLabel;<br> Label2: TLabel;<br> Button3: TButton;<br> Button5: TButton;<br> Label3: TLabel;<br> ComboBox1: TComboBox;<br> Timer1: TTimer;<br> CheckBox1: TCheckBox;<br> procedure FormCreate(Sender: TObject);<br> procedure BitBtn1Click(Sender: TObject);<br> procedure Button2Click(Sender: TObject);<br> procedure fsdkClick(Sender: TObject);<br> procedure RadioGroup2Click(Sender: TObject);<br> procedure RadioGroup3Click(Sender: TObject);<br> procedure RadioGroup4Click(Sender: TObject);<br> procedure RadioGroup6Click(Sender: TObject);<br> procedure RadioGroup5Click(Sender: TObject);<br> procedure BitBtn3Click(Sender: TObject);<br> procedure Button1Click(Sender: TObject);<br> procedure Button3Click(Sender: TObject);<br> procedure Button5Click(Sender: TObject);<br> procedure ComboBox1Change(Sender: TObject);<br> procedure BitBtn2Click(Sender: TObject);<br> procedure Timer1Timer(Sender: TObject);<br> procedure CheckBox1Click(Sender: TObject);<br> private<br> procedure WMCOMMNOTIFY(var Message :TMessage);message WM_COMMNOTIFY;<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br>var<br>hNewCommFile2,Post_Event: THandle;<br>hNewCommFile1 : THandle;<br>Read_os : Toverlapped;<br>Receive :Boolean;<br>ReceiveData : Dword;<br>ComBaudRate : Dword=9600;<br>ComParity : byte=0;<br>ComStopBits : byte=0;<br>ComByteSize : byte=8;<br>ComFile1
char='Com1' ;<br>ComFile2
char='Com2' ;<br>reLen :dword =0;<br>DWBuffer
word =1024 ;//发送、接收缓冲区的大小<br>ReadString1 :String='' ;<br>ReadString2 :String='' ;<br>AutoWriteComm :Boolean = False;<br><br>procedure SetStatusBar ; //Set状态栏<br>var sText :string ;<br>Begin<br> sText :=inttostr(ComBaudRate)+';';<br> case ComParity of<br> 0 : sText:=sText+'N;';<br> 1 : sText:=sText+'O;';<br> 2 : sText:=sText+'E;';<br> end;<br> sText:=sText+inttostr(ComByteSize)+';';<br> case ComStopBits of<br> 0 : sText:=sText+'1';<br> 1 : sText:=sText+'1.5';<br> 2 : sText:=sText+'2';<br> end;<br> form1.StatusBar1.Panels[4].Text := '通信参数:'+sText;<br>end ;<br>procedure SetControlEnabed( ComPortID:integer;ControlState:Boolean ) ;<br>//Set通信参数控件的Enabled状态<br>begin<br><br> if ComPortID = 1 then<br> begin<br> Form1.fsdk.Enabled :=ControlState ;<br> Form1.Button2.Enabled :=ControlState ;<br> end<br> else Form1.RadioGroup2.Enabled:=ControlState ;<br> //如果正在发送或接收,通信参数控件的Enabled状态取消恢复True<br> if ControlState then<br> if (Form1.BitBtn3.Caption='终止接收数据')<br> or (Form1.Button2.Enabled = False) then exit ;<br><br> Form1.RadioGroup5.Enabled:=ControlState ;<br> Form1.RadioGroup6.Enabled:=ControlState ;<br> Form1.RadioGroup4.Enabled:=ControlState ;<br> Form1.RadioGroup3.Enabled:=ControlState ;<br> Form1.ComboBox1.Enabled:=ControlState ;<br>end;<br><br>procedure AddToMemo(Str
Char;Len
word); // 接收的数据送入显示区<br>begin<br> str[Len]:=#0;<br> Form1.RichEdit2.Text:=Form1.RichEdit2.Text+StrPas(str);<br> Readstring1 :=StrPas(str);<br> reLen:= reLen+ Len ;<br> Form1.Timer1.Enabled := true ;<br> Form1.StatusBar1.Panels[3].Text :=inttostr(Len)+ '已收数据:'+inttostr(ReLen);<br> Application.ProcessMessages;<br>end;<br><br>procedure CommWatch(Ptr
ointer);stdcall; // 通讯监视线程<br>var<br> dwEvtMask,dwTranser : Dword;<br> Ok : Boolean;<br> Os : Toverlapped;<br>begin<br> Receive :=True;<br> FillChar(Os,SizeOf(Os),0);<br> Os.hEvent :=CreateEvent(nil,True,False,nil); // 创建重叠读事件对象<br> if Os.hEvent=null then<br> begin<br> MessageBox(0,'创建重叠读事件对象发生错误 !','提示信息',MB_OK);<br> Exit;<br> end;<br> if (not SetCommMask(hNewCommFile2,EV_RXCHAR)) then<br> begin<br> //MessageBox(0,'SetCommMask Error !','Notice',MB_OK);<br> MessageBox(0,'设置串口发生错误!','提示信息',MB_OK);<br> Exit;<br> end;<br> while(Receive) do<br> begin<br> dwEvtMask:=0;<br> // 等待通讯事件发生<br> if not WaitCommEvent(hNewCommFile2,dwEvtMask,@Os) then<br> begin<br> if ERROR_IO_PENDING=GetLastError then<br> GetOverLappedResult(hNewCommFile2,Os,dwTranser,True);<br> {Form1.StatusBar1.Panels[3].Text := '无数据接收';<br> Application.ProcessMessages; //Zxy Add}<br> end;<br> if ((dwEvtMask and EV_RXCHAR)=EV_RXCHAR) then<br> begin<br> // 等待允许传递WM_COMMNOTIFY通讯消息<br> WaitForSingleObject(Post_event,INFINITE);<br> // 处理WM_COMMNOTIFY消息时不再发送WM_COMMNOTIFY消息<br> ResetEvent(Post_Event);<br> // 传递WM_COMMNOTIFY通讯消息<br> Ok:=PostMessage(Form1.Handle,WM_COMMNOTIFY,hNewCommFile2,0);<br> if (not Ok) then<br> begin<br> //MessageBox(0,'PostMessage Error !','Notice',MB_OK);<br> MessageBox(0,'发送消息时产生错误 !','提示信息',MB_OK);<br> Exit;<br> end;<br> end;<br> end;<br> CloseHandle(Os.hEvent); // 关闭重叠读事件对象<br>end;<br><br>procedure TForm1.WMCOMMNOTIFY(var Message :TMessage); // 消息处理函数<br>var<br> CommState : ComStat;<br> dwNumberOfBytesRead : Dword;<br> ErrorFlag : Dword;<br> InputBuffer : Array[0..4096] of Char ;<br>begin<br><br> if not ClearCommError(hNewCommFile2,ErrorFlag,@CommState) then<br> begin<br> //MessageBox(0,'ClearCommError !','Notice',MB_OK);<br> MessageBox(0,'无法清除串口错误 !','提示信息',MB_OK);<br> PurgeComm(hNewCommFile2,Purge_Rxabort or Purge_Rxclear);<br> Exit;<br> end;<br> if (CommState.cbInQue>0) then<br> begin<br> fillchar(InputBuffer,CommState.cbInQue,#0);<br> // 接收通讯数据<br> if (not ReadFile(hNewCommFile2,InputBuffer,CommState.cbInQue,dwNumberOfBytesRead,@Read_os)) then<br> begin<br> ErrorFlag := GetLastError();<br> {if (ErrorFlag =0) or (ErrorFlag = ERROR_IO_PENDING) then<br> begin<br> Form1.StatusBar1.Panels[3].Text := '无数据接收';<br> Application.ProcessMessages; //Zxy Add<br> end ;}<br> if (ErrorFlag <> 0) and (ErrorFlag <> ERROR_IO_PENDING) then<br> begin<br> //MessageBox(0,'ReadFile Error!','Notice',MB_OK);<br> MessageBox(0,'接收数据发生错误!','提示信息',MB_OK);<br> Receive :=False;<br> CloseHandle(Read_Os.hEvent);<br> CloseHandle(Post_Event);<br> CloseHandle(hNewCommFile2);<br> Exit;<br> end<br> else begin<br> WaitForSingleObject(hNewCommFile2,INFINITE); // 等待操作完成<br> GetOverlappedResult(hNewCommFile2,Read_os,dwNumberOfBytesRead,False);<br> end;<br> end;<br> if dwNumberOfBytesRead>0 then<br> begin<br> Read_Os.Offset :=Read_Os.Offset+dwNumberOfBytesRead;<br> ReceiveData := Read_Os.Offset;<br> // 处理接收的数据<br> AddToMemo(InputBuffer,dwNumberOfBytesRead);<br> end;<br> end;<br> // 允许发送下一个WM_COMMNOTIFY消息<br> SetEvent(Post_Event);<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>RichEdit1.clear;<br>RichEdit2.clear;<br>StatusBar1.Panels[4].Text := '通信参数:9600;N;8;1';<br>end;<br><br><br>procedure TForm1.BitBtn1Click(Sender: TObject);<br>begin<br> CheckBox1.Checked:=False ;<br> close;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>var<br> dcb : TDCB;<br> Error :Boolean;<br> dwNumberOfBytesWritten,dwNumberOfBytesToWrite,<br> ErrorFlag,dwWhereToStartWriting : DWORD;<br> pDataToWrite : PChar;<br> write_os: Toverlapped;<br>begin<br> // 打开通讯端口COM1<br> SetControlEnabed(1,False);<br> StatusBar1.Panels[2].Text :='打开发送端口...!';<br> hNewCommFile1:=CreateFile( COMFile1,GENERIC_WRITE,0,nil, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0 );<br> if hNewCommFile1 = INVALID_HANDLE_VALUE then<br> begin<br> //MessageBox(0,'Error opening com port!','Notice',MB_OK);<br> MessageBox(0,'发送端口不存在或已占用!','提示信息',MB_OK);<br> CloseHandle(hNewCommFile1);<br> SetControlEnabed(1,True);<br> exit;<br> end ;<br> SetupComm(hNewCommFile1,DWBuffer,DWBuffer); // 设置缓冲区大小及主要通讯参数<br> GetCommState( hNewCommFile1,dcb);<br> dcb.BaudRate :=ComBaudRate ;<br> dcb.ByteSize :=ComByteSize;<br> dcb.Parity :=ComParity;<br> dcb.StopBits := ComStopBits;<br> Error := SetCommState( hNewCommFile1, dcb );<br> if (not Error) then<br> begin<br> //MessageBox(0,'SetCommState Error!','Notice',MB_OK);<br> MessageBox(0,'设置串口参数错误!','提示信息',MB_OK);<br> CloseHandle(hNewCommFile1);<br> SetControlEnabed(1,True);<br> exit ;<br> end;<br> dwWhereToStartWriting := 0;<br> dwNumberOfBytesWritten := 0;<br> dwNumberOfBytesToWrite :=RichEdit1.GetTextLen+1;<br> //不知为什么要+1,否则最后一个字符就没有传出去,当然就收不到了<br> if (dwNumberOfBytesToWrite - 1 =0) then<br> begin<br> ShowMessage('无发送数据!');<br> Button2.Enabled :=true;<br> CloseHandle(hNewCommFile1);<br> SetControlEnabed(1,True);<br> Exit;<br> end<br> else begin<br> pDataToWrite:=StrAlloc(dwNumberOfBytesToWrite+1);<br> try<br> RichEdit1.GetTextBuf(pDataToWrite,dwNumberOfBytesToWrite);<br> FillChar(Write_Os,SizeOf(write_os),0);<br> // 为重叠写创建事件对象<br> Write_Os.hEvent := CreateEvent(nil,True,False,nil);<br> SetCommMask(hNewCommFile1,EV_TXEMPTY);<br> StatusBar1.Panels[2].Text :='正在发送...!';<br> repeat<br> // 发送通讯数据<br> if not WriteFile( hNewCommFile1,pDataToWrite[dwWhereToStartWriting],<br> dwNumberOfBytesToWrite,dwNumberOfBytesWritten,@write_os ) then<br> begin<br> ErrorFlag :=GetLastError;<br> if ErrorFlag<>0 then<br> begin<br> if ErrorFlag=ERROR_IO_PENDING then<br> begin<br> WaitForSingleObject(Write_Os.hEvent,INFINITE);<br> GetOverlappedResult(hNewCommFile1,Write_os,dwNumberOfBytesWritten,False);<br> end<br> else begin<br> MessageBox(0,'发送数据时产生错误!','提示信息',MB_OK);<br> Receive :=False;<br> CloseHandle(Read_Os.hEvent);<br> CloseHandle(Post_Event);<br> CloseHandle(hNewCommFile1);<br> SetControlEnabed(1,True);<br> Exit;<br> end;<br> end;<br> end;<br> Dec(dwNumberOfBytesToWrite, dwNumberOfBytesWritten );<br> Inc( dwWhereToStartWriting, dwNumberOfBytesWritten );<br> StatusBar1.Panels[2].Text :='发送中..'+IntToStr(dwWhereToStartWriting);<br> Application.ProcessMessages;<br> until (dwNumberOfBytesToWrite <= 0); // Write the whole thing!<br> // Form1.Caption:=IntToStr(dwWhereToStartWriting);<br> finally<br> StrDispose(pDataToWrite);<br> end;<br> CloseHandle(hNewCommFile1);<br> end;<br> StatusBar1.Panels[2].Text :='发送:'+IntToStr(dwWhereToStartWriting);<br> SetControlEnabed(1,True);<br> if CheckBox1.Checked then<br> begin<br> Sleep(1000);<br> Button2Click(Button2);<br> Application.ProcessMessages;<br> end;<br>end;<br><br>procedure TForm1.fsdkClick(Sender: TObject);<br>begin<br> case fsdk.ItemIndex of<br> 0: ComFile1 := 'Com1' ;<br> 1: ComFile1 := 'Com2' ;<br> 2: ComFile1 := 'Com3' ;<br> 3: ComFile1 := 'Com4' ;<br> end;<br>end;<br><br>procedure TForm1.RadioGroup2Click(Sender: TObject);<br>begin<br> case RadioGroup2.ItemIndex of<br> 0: ComFile2 := 'Com1' ;<br> 1: ComFile2 := 'Com2' ;<br> 2: ComFile2 := 'Com3' ;<br> 3: ComFile2 := 'Com4' ;<br> end;<br>end;<br><br>procedure TForm1.RadioGroup3Click(Sender: TObject);<br>begin<br> case RadioGroup3.ItemIndex of<br> 0: ComBaudRate := 110 ;<br> 1: ComBaudRate := 300 ;<br> 2: ComBaudRate := 600 ;<br> 3: ComBaudRate := 1200 ;<br> 4: ComBaudRate := 2400 ;<br> 5: ComBaudRate := 4800 ;<br> 6: ComBaudRate := 9600 ;<br> 7: ComBaudRate := 14400 ;<br> 8: ComBaudRate := 19200 ;<br> 9: ComBaudRate := 38400 ;<br> 10: ComBaudRate := 56000 ;<br> 11: ComBaudRate := 57600 ;<br> 12: ComBaudRate := 115200 ;<br> end;<br> SetStatusBar ;<br>end;<br><br>procedure TForm1.RadioGroup4Click(Sender: TObject);<br>begin<br> ComParity := RadioGroup4.ItemIndex ;<br> SetStatusBar;<br>end;<br><br>procedure TForm1.RadioGroup6Click(Sender: TObject);<br>begin<br> ComByteSize := RadioGroup6.ItemIndex +4;<br> SetStatusBar;<br>end;<br><br>procedure TForm1.RadioGroup5Click(Sender: TObject);<br>begin<br> ComStopBits:= RadioGroup5.ItemIndex ;<br> SetStatusBar;<br>end;<br><br>procedure TForm1.BitBtn3Click(Sender: TObject);<br>var<br> Ok : Boolean;<br> dcb : TDCB;<br> com_thread: Thandle;<br> ThreadID
WORD;<br>begin<br> if BitBtn3.Caption='开始接收数据' then<br> begin<br> SetControlEnabed(2,False);<br> ReceiveData :=0;<br> // 打开接收端口<br> hNewCommFile2:=CreateFile( ComFile2,GENERIC_READ,0, nil, OPEN_EXISTING,<br> FILE_FLAG_OVERLAPPED,0 );<br> if hNewCommFile2 = INVALID_HANDLE_VALUE then<br> begin<br> MessageBox(0,'接收端口不存在或已占用!','提示',MB_OK);<br> SetControlEnabed(2,True);<br> Exit;<br> end;<br> Ok:=SetCommMask(hNewCommFile2,EV_RXCHAR);<br> if (not Ok) then<br> begin<br> MessageBox(0,'设置通信串口错误!','提示信息',MB_OK);<br> CloseHandle(Read_Os.hEvent);<br> CloseHandle(Post_Event);<br> CloseHandle(hNewCommFile2);<br> SetControlEnabed(2,True);<br> Exit;<br> end;<br> SetupComm(hNewCommFile2,DWBuffer,DWBuffer);<br> GetCommState( hNewCommFile2, dcb );<br> dcb.BaudRate :=ComBaudRate ;<br> dcb.ByteSize :=ComByteSize;<br> dcb.Parity :=ComParity;<br> dcb.StopBits := ComStopBits;<br> Ok := SetCommState( hNewCommFile2, dcb );<br> if (not Ok) then<br> begin<br> MessageBox(0,'设置通信参数错误!','提示',MB_OK);<br> CloseHandle(Read_Os.hEvent);<br> CloseHandle(Post_Event);<br> CloseHandle(hNewCommFile2);<br> SetControlEnabed(2,True);<br> Exit ;<br> end ;<br> FillChar(Read_Os,SizeOf(Read_Os),0);<br> Read_Os.Offset := 0;<br> Read_Os.OffsetHigh := 0;<br> // Create Event for Overlapped Read<br> Read_Os.hEvent :=CreateEvent(nil,true,False,nil);<br> if Read_Os.hEvent=null then<br> begin<br> CloseHandle(hNewCommFile2);<br> MessageBox(0,'建立接收进程错误!','提示',MB_OK);<br> CloseHandle(Read_Os.hEvent);<br> CloseHandle(Post_Event);<br> CloseHandle(hNewCommFile2);<br> SetControlEnabed(2,True);<br> Exit;<br> end;<br> // Create Event for PostMessage<br> Post_Event:=CreateEvent(nil,True,True,nil);<br> if Post_Event=null then<br> begin<br> CloseHandle(hNewCommFile2);<br> CloseHandle(Read_Os.hEvent);<br> MessageBox(0,'建立接收事件发生错误!','提示',MB_OK);<br> SetControlEnabed(2,True);<br> Exit;<br> end;<br> // 建立通信监视线程<br> Com_Thread:=CreateThread(nil,0,@CommWatch,nil,0,ThreadID);<br> if (Com_Thread=0) then<br> begin<br> MessageBox(Handle,'No CraeteThread!',nil,mb_OK);<br> CloseHandle(hNewCommFile2);<br> CloseHandle(Read_Os.hEvent);<br> SetControlEnabed(2,True);<br> exit ;<br> end ;<br> EscapeCommFunction(hNewCommFile2,SETDTR);<br> BitBtn3.Caption:='终止接收数据' ;<br> StatusBar1.Panels[3].Text :='正在等待数据...!';<br> StatusBar1.Panels[1].Text :='接收端口已开○';<br> //Label1.Caption:='正在接收数据...!';<br> end<br> else begin<br> StatusBar1.Panels[3].Text :='接收数据已终止!';<br> StatusBar1.Panels[1].Text:='接收端口未开●';<br> BitBtn3.Caption:='开始接收数据';<br> CloseHandle(Read_Os.hEvent);<br> CloseHandle(Post_Event);<br> CloseHandle(hNewCommFile2);<br> SetControlEnabed(2,True);<br> end;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> if OpenDialog1.Execute then<br> RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);<br>end;<br><br>procedure TForm1.Button3Click(Sender: TObject);<br>begin<br> RichEdit1.clear;<br>end;<br><br>procedure TForm1.Button5Click(Sender: TObject);<br>begin<br> RichEdit2.clear;<br> reLen :=0;<br>end;<br><br>procedure TForm1.ComboBox1Change(Sender: TObject);<br>//var aa :string;<br>begin<br> DWBuffer := strtoint(ComboBox1.text);<br> //ShowMessage(inttostr(DwBuffer));<br>end;<br><br>procedure TForm1.BitBtn2Click(Sender: TObject);<br>var EditSize
word ;<br><br> MySavefile : TextFile;<br><br>begin<br> EditSize :=RichEdit2.GetTextLen;<br> if EditSize <= 0 then<br> showmessage('没有需要数据保存的数据')<br> else begin<br> if SaveDialog1.Execute then<br> begin<br> if FileExists(SaveDialog1.FileName) then<br> if MessageDlg('文件:'+SaveDialog1.FileName+'已存在,是否覆盖?',<br> mtConfirmation, mbYesNoCancel, 0) <> idYes then Exit;<br> AssignFile(MySaveFile,SaveDialog1.FileName);<br> Rewrite(MySaveFile);<br> Write(MySaveFile,RichEdit2.Lines.text);<br> CloseFile(MySaveFile);<br> //RichEdit2.Lines.SaveToFile(SaveDialog1.FileName);<br> end ;<br> end;<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>begin<br> if Readstring1 = Readstring2 then<br> begin<br> StatusBar1.Panels[3].Text :='接收完成:'+inttostr(ReLen);<br> Application.ProcessMessages;<br> reLen :=0 ;<br> Timer1.Enabled := False ;<br> end<br> else begin<br> Readstring2:= Readstring1 ;<br> end;<br>end;<br><br>procedure TForm1.CheckBox1Click(Sender: TObject);<br>begin<br> if CheckBox1.Checked = True then<br> begin<br> repeat<br> Application.ProcessMessages;<br> Sleep(500) ;<br> until Button2.Enabled ;<br> //sleep(10000);<br> Button2Click(Button2);<br> end ;<br>end;<br><br>end.<br>