在程序里频繁使用Sleep();后果会怎样???(50分)

  • 主题发起人 主题发起人 jmlwz
  • 开始时间 开始时间
J

jmlwz

Unregistered / Unconfirmed
GUEST, unregistred user!
在写端口时,使用“它”等待硬件返回数据,可我在程序里多处使用Sleep(),“它”使我的程序变得很慢很慢。老是在等待..........!<br>各位有更好的方法解决吗?<br><br>
 
可以使用一个线程专门来处理这些呀!不要在主线程中使用过多的Sleep。
 
多谢"phoex",你的方法应该是对的,可我想问你,线程里好象不能放其它控件?如果我要在线程里使用时钟,那应该怎么办好呢?(是不是必须在主线程里放时钟控件,在主线程里的时钟会不会使主程变慢呢?)<br>(我的程序必须要用时钟读取端口,用SLEEP()等待接收数据的)
 
还有可以用WaitForSingleObject()来代替Sleep(),第一个参数可以是你的端口句柄,当端口写完了,WaitForSingleObject()会自动唤醒的
 
写个小函数延时啊<br>repeat <br>until <br>strtodatetime('00:00:10')+t1&lt;=now;
 
var<br>&nbsp; NumSec: Integer;<br>&nbsp; StartTime: Double;<br>begin<br>&nbsp; NumSec := 1;<br>&nbsp; StartTime := Now;<br>&nbsp; repeat<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; until Now &gt; StartTime + NumSec * (1/24/60/60);<br>我用这法子
 
To app2001:<br>你的法子太占CPU时间片了吧,用ProcessMessages强制消息循环不好吧,不如换成WaitForSingleObject来得节省能源[:)]。
 
"app2001"你的方法好象占用太多CPU了,<br>"qince"使用了WaitForSingleObject();后读端口好象容易出错!<br>我在想用线程来做,可线程里不能放控件是吧!?
 
线程中可以方控件呀,只是需要自己创建,例如:<br>private<br>&nbsp; aaa: TTimer; &nbsp; &nbsp; &nbsp;// 声明<br>......<br><br>begin<br>&nbsp; aaa := TTimer.Create(nil); &nbsp; &nbsp;// 创建<br>&nbsp; ......<br>&nbsp; if Assigned(aaa) then FreeAndNil(aaa); &nbsp;// 释放<br>end;<br>&nbsp;
 
不过就算写成TThread,你将来也会用到WaitForSingleObject的,出错原因可能是你调用的方式有问题。
 
是的:)我刚刚试过在线程里使用SLEEP(),同样使主程序很慢!<br>"qince"我想再试一试你说的方法看,可在DELPHI里找一到关于WaitForSingleObject()函数的帮助,你能说一说“它”的功能与使用方法吗?多谢!
 
WaitForSingleObject<br><br>The WaitForSingleObject function returns when one of the following occurs:<br><br><br>The specified object is in the signaled state. <br>The time-out interval elapses. <br>To enter an alertable wait state, use the WaitForSingleObjectEx function. To wait for multiple objects, use the WaitForMultipleObjects.<br><br><br>DWORD WaitForSingleObject(<br>&nbsp; HANDLE hHandle,<br>&nbsp; DWORD dwMilliseconds<br>);<br><br>Parameters<br>hHandle <br>[in] Handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section. <br>If this handle is closed while the wait is still pending, the function's behavior is undefined.<br><br>The handle must have the SYNCHRONIZE access right. For more information, see Standard Access Rights.<br><br>dwMilliseconds <br>[in] Time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If dwMilliseconds is zero, the function tests the object's state and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses. <br>Return Values<br>If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values.<br><br>Return Code Description <br>WAIT_ABANDONED The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled. <br>WAIT_OBJECT_0 The state of the specified object is signaled. <br>WAIT_TIMEOUT The time-out interval elapsed, and the object's state is nonsignaled. <br><br><br>If the function fails, the return value is WAIT_FAILED. To get extended error information, call GetLastError.<br><br><br>Remarks<br>The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters the wait state. It uses no processor time while waiting for the object state to become signaled or the time-out interval to elapse.<br><br>The function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one.<br><br>The WaitForSingleObject function can wait for the following objects:<br><br><br><br>Change notification <br>Console input <br>Event <br>Job <br>Memory resource notification <br>Mutex <br>Process <br>Semaphore <br>Thread <br>Waitable timer <br><br>Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForSingleObject.<br><br>For more information, see Using Mutex Objects.<br><br>Requirements<br>Client: Requires Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.<br>Server: Requires Windows Server 2003, Windows 2000 Server, or Windows NT Server.<br>Header: Declared in Winbase.h; include Windows.h.<br>Library: Use Kernel32.lib.<br><br><br>See Also <br>
 
如果你能上网,请直接连接 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/waitforsingleobject.asp 查看帮助
 
同意qince的方法
 
procedure MyDelay(AiMSecond:integer);<br>var iBeginTime,iCurTime, iPassed:integer;<br>begin<br>&nbsp; iBeginTime := MilliSecondOfTheMinute(now);<br>&nbsp; iPassed := 0;<br>&nbsp; while iPassed &lt; AiMSecond do<br>&nbsp; begin<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; iCurTime := MilliSecondOfTheMinute(now);<br>&nbsp; &nbsp; iPassed := iCurTime - iBeginTime;<br>&nbsp; &nbsp; if iPassed &lt; 0 then iPassed := 60000 + iPassed;<br>&nbsp; end;<br>end;
 
让线程自己去等<br>下面代码希望对你有帮助,要源码请留下(win98+delphi5,无第三方控件)<br>e_main<br><br><br>unit MyComm;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, ComCtrls, Buttons, ExtCtrls;<br>&nbsp; &nbsp; const<br>&nbsp; WM_COMMNOTIFY = WM_USER + 1; // 通讯消息<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; OpenDialog1: TOpenDialog;<br>&nbsp; &nbsp; RichEdit1: TRichEdit;<br>&nbsp; &nbsp; RichEdit2: TRichEdit;<br>&nbsp; &nbsp; SaveDialog1: TSaveDialog;<br>&nbsp; &nbsp; BitBtn1: TBitBtn;<br>&nbsp; &nbsp; BitBtn2: TBitBtn;<br>&nbsp; &nbsp; fsdk: TRadioGroup;<br>&nbsp; &nbsp; RadioGroup2: TRadioGroup;<br>&nbsp; &nbsp; RadioGroup3: TRadioGroup;<br>&nbsp; &nbsp; RadioGroup4: TRadioGroup;<br>&nbsp; &nbsp; RadioGroup5: TRadioGroup;<br>&nbsp; &nbsp; StatusBar1: TStatusBar;<br>&nbsp; &nbsp; RadioGroup6: TRadioGroup;<br>&nbsp; &nbsp; BitBtn3: TBitBtn;<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; Button3: TButton;<br>&nbsp; &nbsp; Button5: TButton;<br>&nbsp; &nbsp; Label3: TLabel;<br>&nbsp; &nbsp; ComboBox1: TComboBox;<br>&nbsp; &nbsp; Timer1: TTimer;<br>&nbsp; &nbsp; CheckBox1: TCheckBox;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure BitBtn1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure fsdkClick(Sender: TObject);<br>&nbsp; &nbsp; procedure RadioGroup2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure RadioGroup3Click(Sender: TObject);<br>&nbsp; &nbsp; procedure RadioGroup4Click(Sender: TObject);<br>&nbsp; &nbsp; procedure RadioGroup6Click(Sender: TObject);<br>&nbsp; &nbsp; procedure RadioGroup5Click(Sender: TObject);<br>&nbsp; &nbsp; procedure BitBtn3Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button3Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button5Click(Sender: TObject);<br>&nbsp; &nbsp; procedure ComboBox1Change(Sender: TObject);<br>&nbsp; &nbsp; procedure BitBtn2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Timer1Timer(Sender: TObject);<br>&nbsp; &nbsp; procedure CheckBox1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; &nbsp;procedure WMCOMMNOTIFY(var Message :TMessage);message WM_COMMNOTIFY;<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; 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 &nbsp; : byte=0;<br>ComStopBits : byte=0;<br>ComByteSize : byte=8;<br>ComFile1 :Pchar='Com1' ;<br>ComFile2 :Pchar='Com2' ;<br>reLen :dword =0;<br>DWBuffer :Dword =1024 ;//发送、接收缓冲区的大小<br>ReadString1 :String='' ;<br>ReadString2 :String='' ;<br>AutoWriteComm :Boolean = False;<br><br>procedure SetStatusBar ; //Set状态栏<br>var sText :string ;<br>Begin<br>&nbsp; sText :=inttostr(ComBaudRate)+';';<br>&nbsp; case ComParity of<br>&nbsp; &nbsp; 0 : sText:=sText+'N;';<br>&nbsp; &nbsp; 1 : sText:=sText+'O;';<br>&nbsp; &nbsp; 2 : sText:=sText+'E;';<br>&nbsp; end;<br>&nbsp; sText:=sText+inttostr(ComByteSize)+';';<br>&nbsp; case ComStopBits of<br>&nbsp; &nbsp; 0 : sText:=sText+'1';<br>&nbsp; &nbsp; 1 : sText:=sText+'1.5';<br>&nbsp; &nbsp; 2 : sText:=sText+'2';<br>&nbsp; end;<br>&nbsp; form1.StatusBar1.Panels[4].Text := '通信参数:'+sText;<br>end ;<br>procedure SetControlEnabed( ComPortID:integer;ControlState:Boolean ) &nbsp;;<br>//Set通信参数控件的Enabled状态<br>begin<br><br>&nbsp; if ComPortID = 1 then<br>&nbsp; begin<br>&nbsp; &nbsp; Form1.fsdk.Enabled :=ControlState ;<br>&nbsp; &nbsp; Form1.Button2.Enabled :=ControlState ;<br>&nbsp; end<br>&nbsp; else &nbsp;Form1.RadioGroup2.Enabled:=ControlState ;<br>&nbsp; //如果正在发送或接收,通信参数控件的Enabled状态取消恢复True<br>&nbsp; if &nbsp;ControlState &nbsp;then<br>&nbsp; &nbsp; if (Form1.BitBtn3.Caption='终止接收数据')<br>&nbsp; &nbsp; &nbsp; or (Form1.Button2.Enabled = False) then exit ;<br><br>&nbsp; Form1.RadioGroup5.Enabled:=ControlState ;<br>&nbsp; Form1.RadioGroup6.Enabled:=ControlState ;<br>&nbsp; Form1.RadioGroup4.Enabled:=ControlState ;<br>&nbsp; Form1.RadioGroup3.Enabled:=ControlState ;<br>&nbsp; Form1.ComboBox1.Enabled:=ControlState ;<br>end;<br><br>procedure AddToMemo(Str:PChar;Len:Dword); // 接收的数据送入显示区<br>begin<br>&nbsp; str[Len]:=#0;<br>&nbsp; Form1.RichEdit2.Text:=Form1.RichEdit2.Text+StrPas(str);<br>&nbsp; Readstring1 :=StrPas(str);<br>&nbsp; reLen:= &nbsp;reLen+ Len &nbsp; ;<br>&nbsp; Form1.Timer1.Enabled := true ;<br>&nbsp; Form1.StatusBar1.Panels[3].Text :=inttostr(Len)+ '已收数据:'+inttostr(ReLen);<br>&nbsp; Application.ProcessMessages;<br>end;<br><br>procedure CommWatch(Ptr:Pointer);stdcall; // 通讯监视线程<br>var<br>&nbsp; dwEvtMask,dwTranser : Dword;<br>&nbsp; Ok : Boolean;<br>&nbsp; Os : Toverlapped;<br>begin<br>&nbsp; Receive :=True;<br>&nbsp; FillChar(Os,SizeOf(Os),0);<br>&nbsp; Os.hEvent :=CreateEvent(nil,True,False,nil); // 创建重叠读事件对象<br>&nbsp; if Os.hEvent=null then<br>&nbsp; begin<br>&nbsp; &nbsp; MessageBox(0,'创建重叠读事件对象发生错误 !','提示信息',MB_OK);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br>&nbsp; if (not SetCommMask(hNewCommFile2,EV_RXCHAR)) then<br>&nbsp; begin<br>&nbsp; &nbsp; //MessageBox(0,'SetCommMask Error !','Notice',MB_OK);<br>&nbsp; &nbsp; MessageBox(0,'设置串口发生错误!','提示信息',MB_OK);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br>&nbsp; while(Receive) do<br>&nbsp; begin<br>&nbsp; &nbsp; dwEvtMask:=0;<br>&nbsp; &nbsp;// 等待通讯事件发生<br>&nbsp; &nbsp; if not WaitCommEvent(hNewCommFile2,dwEvtMask,@Os) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if ERROR_IO_PENDING=GetLastError then<br>&nbsp; &nbsp; &nbsp; &nbsp; GetOverLappedResult(hNewCommFile2,Os,dwTranser,True);<br>&nbsp; &nbsp; &nbsp; {Form1.StatusBar1.Panels[3].Text := '无数据接收';<br>&nbsp; &nbsp; &nbsp; Application.ProcessMessages; &nbsp;//Zxy Add}<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; if ((dwEvtMask and EV_RXCHAR)=EV_RXCHAR) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; // 等待允许传递WM_COMMNOTIFY通讯消息<br>&nbsp; &nbsp; &nbsp; WaitForSingleObject(Post_event,INFINITE);<br>&nbsp; &nbsp; // 处理WM_COMMNOTIFY消息时不再发送WM_COMMNOTIFY消息<br>&nbsp; &nbsp; &nbsp; ResetEvent(Post_Event);<br>&nbsp; &nbsp; // 传递WM_COMMNOTIFY通讯消息<br>&nbsp; &nbsp; &nbsp; Ok:=PostMessage(Form1.Handle,WM_COMMNOTIFY,hNewCommFile2,0);<br>&nbsp; &nbsp; &nbsp; if (not Ok) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; //MessageBox(0,'PostMessage Error !','Notice',MB_OK);<br>&nbsp; &nbsp; &nbsp; &nbsp; MessageBox(0,'发送消息时产生错误 !','提示信息',MB_OK);<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; CloseHandle(Os.hEvent); // 关闭重叠读事件对象<br>end;<br><br>procedure TForm1.WMCOMMNOTIFY(var Message :TMessage); // 消息处理函数<br>var<br>&nbsp; CommState : ComStat;<br>&nbsp; dwNumberOfBytesRead : Dword;<br>&nbsp; ErrorFlag : Dword;<br>&nbsp; InputBuffer : Array[0..4096] of Char ;<br>begin<br><br>&nbsp; if not ClearCommError(hNewCommFile2,ErrorFlag,@CommState) then<br>&nbsp; begin<br>&nbsp; &nbsp; //MessageBox(0,'ClearCommError !','Notice',MB_OK);<br>&nbsp; &nbsp; MessageBox(0,'无法清除串口错误 !','提示信息',MB_OK);<br>&nbsp; &nbsp; PurgeComm(hNewCommFile2,Purge_Rxabort or Purge_Rxclear);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br>&nbsp; if (CommState.cbInQue&gt;0) then<br>&nbsp; begin<br>&nbsp; &nbsp; fillchar(InputBuffer,CommState.cbInQue,#0);<br>&nbsp; &nbsp; // 接收通讯数据<br>&nbsp; &nbsp; if (not ReadFile(hNewCommFile2,InputBuffer,CommState.cbInQue,dwNumberOfBytesRead,@Read_os)) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; ErrorFlag := GetLastError();<br>&nbsp; &nbsp; &nbsp; {if (ErrorFlag =0) or (ErrorFlag = ERROR_IO_PENDING) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Form1.StatusBar1.Panels[3].Text := '无数据接收';<br>&nbsp; &nbsp; &nbsp; &nbsp; Application.ProcessMessages; &nbsp;//Zxy Add<br>&nbsp; &nbsp; &nbsp; end ;}<br>&nbsp; &nbsp; &nbsp; if (ErrorFlag &lt;&gt; 0) and (ErrorFlag &lt;&gt; ERROR_IO_PENDING) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; //MessageBox(0,'ReadFile Error!','Notice',MB_OK);<br>&nbsp; &nbsp; &nbsp; &nbsp; MessageBox(0,'接收数据发生错误!','提示信息',MB_OK);<br>&nbsp; &nbsp; &nbsp; &nbsp; Receive :=False;<br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(Post_Event);<br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; WaitForSingleObject(hNewCommFile2,INFINITE); // 等待操作完成<br>&nbsp; &nbsp; &nbsp; &nbsp; GetOverlappedResult(hNewCommFile2,Read_os,dwNumberOfBytesRead,False);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; if dwNumberOfBytesRead&gt;0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Read_Os.Offset :=Read_Os.Offset+dwNumberOfBytesRead;<br>&nbsp; &nbsp; &nbsp; ReceiveData := Read_Os.Offset;<br>&nbsp; &nbsp; &nbsp; // 处理接收的数据<br>&nbsp; &nbsp; &nbsp; AddToMemo(InputBuffer,dwNumberOfBytesRead);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; // 允许发送下一个WM_COMMNOTIFY消息<br>&nbsp; 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>&nbsp; CheckBox1.Checked:=False ;<br>&nbsp; close;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>var<br>&nbsp; dcb : TDCB;<br>&nbsp; Error :Boolean;<br>&nbsp; dwNumberOfBytesWritten,dwNumberOfBytesToWrite,<br>&nbsp; ErrorFlag,dwWhereToStartWriting : DWORD;<br>&nbsp; pDataToWrite : PChar;<br>&nbsp; write_os: Toverlapped;<br>begin<br>&nbsp; // 打开通讯端口COM1<br>&nbsp; SetControlEnabed(1,False);<br>&nbsp; StatusBar1.Panels[2].Text :='打开发送端口...!';<br>&nbsp; hNewCommFile1:=CreateFile( COMFile1,GENERIC_WRITE,0,nil, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0 );<br>&nbsp; if hNewCommFile1 = INVALID_HANDLE_VALUE then<br>&nbsp; begin<br>&nbsp; &nbsp; //MessageBox(0,'Error opening com port!','Notice',MB_OK);<br>&nbsp; &nbsp; MessageBox(0,'发送端口不存在或已占用!','提示信息',MB_OK);<br>&nbsp; &nbsp; CloseHandle(hNewCommFile1);<br>&nbsp; &nbsp; SetControlEnabed(1,True);<br>&nbsp; &nbsp; exit;<br>&nbsp; end ;<br>&nbsp; SetupComm(hNewCommFile1,DWBuffer,DWBuffer); // 设置缓冲区大小及主要通讯参数<br>&nbsp; GetCommState( hNewCommFile1,dcb);<br>&nbsp; dcb.BaudRate :=ComBaudRate ;<br>&nbsp; dcb.ByteSize :=ComByteSize;<br>&nbsp; dcb.Parity :=ComParity;<br>&nbsp; dcb.StopBits := ComStopBits;<br>&nbsp; Error := SetCommState( hNewCommFile1, dcb );<br>&nbsp; if (not Error) then<br>&nbsp; begin<br>&nbsp; &nbsp; //MessageBox(0,'SetCommState Error!','Notice',MB_OK);<br>&nbsp; &nbsp; MessageBox(0,'设置串口参数错误!','提示信息',MB_OK);<br>&nbsp; &nbsp; CloseHandle(hNewCommFile1);<br>&nbsp; &nbsp; SetControlEnabed(1,True);<br>&nbsp; &nbsp; exit ;<br>&nbsp; end;<br>&nbsp; dwWhereToStartWriting := 0;<br>&nbsp; dwNumberOfBytesWritten := 0;<br>&nbsp; dwNumberOfBytesToWrite :=RichEdit1.GetTextLen+1;<br>&nbsp; //不知为什么要+1,否则最后一个字符就没有传出去,当然就收不到了<br>&nbsp; if (dwNumberOfBytesToWrite - 1 =0) then<br>&nbsp; begin<br>&nbsp; &nbsp; ShowMessage('无发送数据!');<br>&nbsp; &nbsp; Button2.Enabled :=true;<br>&nbsp; &nbsp; CloseHandle(hNewCommFile1);<br>&nbsp; &nbsp; SetControlEnabed(1,True);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end<br>&nbsp; else begin<br>&nbsp; &nbsp; pDataToWrite:=StrAlloc(dwNumberOfBytesToWrite+1);<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RichEdit1.GetTextBuf(pDataToWrite,dwNumberOfBytesToWrite);<br>&nbsp; &nbsp; &nbsp; FillChar(Write_Os,SizeOf(write_os),0);<br>&nbsp; &nbsp; &nbsp; // 为重叠写创建事件对象<br>&nbsp; &nbsp; &nbsp; Write_Os.hEvent := CreateEvent(nil,True,False,nil);<br>&nbsp; &nbsp; &nbsp; SetCommMask(hNewCommFile1,EV_TXEMPTY);<br>&nbsp; &nbsp; &nbsp; StatusBar1.Panels[2].Text :='正在发送...!';<br>&nbsp; &nbsp; repeat<br>&nbsp; &nbsp; &nbsp; // 发送通讯数据<br>&nbsp; &nbsp; &nbsp; if not WriteFile( hNewCommFile1,pDataToWrite[dwWhereToStartWriting],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwNumberOfBytesToWrite,dwNumberOfBytesWritten,@write_os ) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ErrorFlag :=GetLastError;<br>&nbsp; &nbsp; &nbsp; &nbsp; if ErrorFlag&lt;&gt;0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ErrorFlag=ERROR_IO_PENDING then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WaitForSingleObject(Write_Os.hEvent,INFINITE);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetOverlappedResult(hNewCommFile1,Write_os,dwNumberOfBytesWritten,False);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MessageBox(0,'发送数据时产生错误!','提示信息',MB_OK);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Receive :=False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(Post_Event);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile1);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetControlEnabed(1,True);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Dec(dwNumberOfBytesToWrite, dwNumberOfBytesWritten );<br>&nbsp; &nbsp; &nbsp; Inc( dwWhereToStartWriting, dwNumberOfBytesWritten );<br>&nbsp; &nbsp; &nbsp; StatusBar1.Panels[2].Text :='发送中..'+IntToStr(dwWhereToStartWriting);<br>&nbsp; &nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; &nbsp;until (dwNumberOfBytesToWrite &lt;= 0); // Write the whole thing!<br>&nbsp; &nbsp; // &nbsp; &nbsp; &nbsp;Form1.Caption:=IntToStr(dwWhereToStartWriting);<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; StrDispose(pDataToWrite);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; CloseHandle(hNewCommFile1);<br>&nbsp; end;<br>&nbsp; StatusBar1.Panels[2].Text :='发送:'+IntToStr(dwWhereToStartWriting);<br>&nbsp; SetControlEnabed(1,True);<br>&nbsp; if CheckBox1.Checked then<br>&nbsp; begin<br>&nbsp; &nbsp; Sleep(1000);<br>&nbsp; &nbsp; Button2Click(Button2);<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.fsdkClick(Sender: TObject);<br>begin<br>&nbsp; case fsdk.ItemIndex of<br>&nbsp; &nbsp; 0: ComFile1 := 'Com1' &nbsp;;<br>&nbsp; &nbsp; 1: ComFile1 := 'Com2' &nbsp;;<br>&nbsp; &nbsp; 2: ComFile1 := 'Com3' &nbsp;;<br>&nbsp; &nbsp; 3: ComFile1 := 'Com4' &nbsp;;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.RadioGroup2Click(Sender: TObject);<br>begin<br>&nbsp; case RadioGroup2.ItemIndex of<br>&nbsp; &nbsp; 0: ComFile2 := 'Com1' &nbsp;;<br>&nbsp; &nbsp; 1: ComFile2 := 'Com2' &nbsp;;<br>&nbsp; &nbsp; 2: ComFile2 := 'Com3' &nbsp;;<br>&nbsp; &nbsp; 3: ComFile2 := 'Com4' &nbsp;;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.RadioGroup3Click(Sender: TObject);<br>begin<br>&nbsp; case &nbsp;RadioGroup3.ItemIndex of<br>&nbsp; &nbsp; 0: ComBaudRate := 110 &nbsp; ;<br>&nbsp; &nbsp; 1: ComBaudRate := 300 &nbsp; ;<br>&nbsp; &nbsp; 2: ComBaudRate := 600 &nbsp; &nbsp;;<br>&nbsp; &nbsp; 3: ComBaudRate := 1200 &nbsp;;<br>&nbsp; &nbsp; 4: ComBaudRate := 2400 &nbsp; ;<br>&nbsp; &nbsp; 5: ComBaudRate := 4800 &nbsp; ;<br>&nbsp; &nbsp; 6: ComBaudRate := 9600 &nbsp; ;<br>&nbsp; &nbsp; 7: ComBaudRate := 14400 &nbsp;;<br>&nbsp; &nbsp; 8: ComBaudRate := 19200 &nbsp;;<br>&nbsp; &nbsp; 9: ComBaudRate := 38400 &nbsp; ;<br>&nbsp; &nbsp; 10: ComBaudRate := 56000 &nbsp;;<br>&nbsp; &nbsp; 11: ComBaudRate := 57600 &nbsp;;<br>&nbsp; &nbsp; 12: ComBaudRate := 115200 &nbsp;;<br>&nbsp; end;<br>&nbsp; SetStatusBar ;<br>end;<br><br>procedure TForm1.RadioGroup4Click(Sender: TObject);<br>begin<br>&nbsp; ComParity := RadioGroup4.ItemIndex ;<br>&nbsp; SetStatusBar;<br>end;<br><br>procedure TForm1.RadioGroup6Click(Sender: TObject);<br>begin<br>&nbsp; ComByteSize := RadioGroup6.ItemIndex +4;<br>&nbsp; SetStatusBar;<br>end;<br><br>procedure TForm1.RadioGroup5Click(Sender: TObject);<br>begin<br>&nbsp; ComStopBits:= RadioGroup5.ItemIndex ;<br>&nbsp; SetStatusBar;<br>end;<br><br>procedure TForm1.BitBtn3Click(Sender: TObject);<br>var<br>&nbsp; Ok : Boolean;<br>&nbsp; dcb : TDCB;<br>&nbsp; com_thread: Thandle;<br>&nbsp; ThreadID:DWORD;<br>begin<br>&nbsp; if BitBtn3.Caption='开始接收数据' then<br>&nbsp; begin<br>&nbsp; &nbsp; SetControlEnabed(2,False);<br>&nbsp; &nbsp; ReceiveData :=0;<br>&nbsp; &nbsp; // 打开接收端口<br>&nbsp; &nbsp; hNewCommFile2:=CreateFile( ComFile2,GENERIC_READ,0, nil, OPEN_EXISTING,<br>&nbsp; &nbsp; &nbsp; FILE_FLAG_OVERLAPPED,0 );<br>&nbsp; &nbsp; if hNewCommFile2 = INVALID_HANDLE_VALUE then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; MessageBox(0,'接收端口不存在或已占用!','提示',MB_OK);<br>&nbsp; &nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Ok:=SetCommMask(hNewCommFile2,EV_RXCHAR);<br>&nbsp; &nbsp; if (not Ok) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; MessageBox(0,'设置通信串口错误!','提示信息',MB_OK);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Post_Event);<br>&nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; SetupComm(hNewCommFile2,DWBuffer,DWBuffer);<br>&nbsp; &nbsp; GetCommState( hNewCommFile2, dcb );<br>&nbsp; &nbsp; dcb.BaudRate :=ComBaudRate ;<br>&nbsp; &nbsp; dcb.ByteSize :=ComByteSize;<br>&nbsp; &nbsp; dcb.Parity :=ComParity;<br>&nbsp; &nbsp; dcb.StopBits := ComStopBits;<br>&nbsp; &nbsp; Ok := SetCommState( hNewCommFile2, dcb );<br>&nbsp; &nbsp; if (not Ok) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; MessageBox(0,'设置通信参数错误!','提示',MB_OK);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Post_Event);<br>&nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; &nbsp; &nbsp; Exit ;<br>&nbsp; &nbsp; end ;<br>&nbsp; &nbsp; FillChar(Read_Os,SizeOf(Read_Os),0);<br>&nbsp; &nbsp; Read_Os.Offset := 0;<br>&nbsp; &nbsp; Read_Os.OffsetHigh := 0;<br>&nbsp; &nbsp; // Create Event for Overlapped Read<br>&nbsp; &nbsp; Read_Os.hEvent :=CreateEvent(nil,true,False,nil);<br>&nbsp; &nbsp; if Read_Os.hEvent=null then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; MessageBox(0,'建立接收进程错误!','提示',MB_OK);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Post_Event);<br>&nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; // Create Event for PostMessage<br>&nbsp; &nbsp; Post_Event:=CreateEvent(nil,True,True,nil);<br>&nbsp; &nbsp; if Post_Event=null then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; MessageBox(0,'建立接收事件发生错误!','提示',MB_OK);<br>&nbsp; &nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; // 建立通信监视线程<br>&nbsp; &nbsp; Com_Thread:=CreateThread(nil,0,@CommWatch,nil,0,ThreadID);<br>&nbsp; &nbsp; if (Com_Thread=0) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; MessageBox(Handle,'No CraeteThread!',nil,mb_OK);<br>&nbsp; &nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; &nbsp; &nbsp; exit ;<br>&nbsp; &nbsp; end ;<br>&nbsp; &nbsp; EscapeCommFunction(hNewCommFile2,SETDTR);<br>&nbsp; &nbsp; BitBtn3.Caption:='终止接收数据' ;<br>&nbsp; &nbsp; StatusBar1.Panels[3].Text :='正在等待数据...!';<br>&nbsp; &nbsp; StatusBar1.Panels[1].Text :='接收端口已开○';<br>&nbsp; &nbsp; //Label1.Caption:='正在接收数据...!';<br>&nbsp; end<br>&nbsp; else begin<br>&nbsp; &nbsp; StatusBar1.Panels[3].Text :='接收数据已终止!';<br>&nbsp; &nbsp; StatusBar1.Panels[1].Text:='接收端口未开●';<br>&nbsp; &nbsp; BitBtn3.Caption:='开始接收数据';<br>&nbsp; &nbsp; CloseHandle(Read_Os.hEvent);<br>&nbsp; &nbsp; CloseHandle(Post_Event);<br>&nbsp; &nbsp; CloseHandle(hNewCommFile2);<br>&nbsp; &nbsp; SetControlEnabed(2,True);<br>&nbsp; end;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; if OpenDialog1.Execute then<br>&nbsp; &nbsp; RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);<br>end;<br><br>procedure TForm1.Button3Click(Sender: TObject);<br>begin<br>&nbsp; RichEdit1.clear;<br>end;<br><br>procedure TForm1.Button5Click(Sender: TObject);<br>begin<br>&nbsp; RichEdit2.clear;<br>&nbsp; reLen :=0;<br>end;<br><br>procedure TForm1.ComboBox1Change(Sender: TObject);<br>//var aa :string;<br>begin<br>&nbsp; DWBuffer := strtoint(ComboBox1.text);<br>&nbsp; //ShowMessage(inttostr(DwBuffer));<br>end;<br><br>procedure TForm1.BitBtn2Click(Sender: TObject);<br>var EditSize :Dword ;<br><br>&nbsp; MySavefile : TextFile;<br><br>begin<br>&nbsp; EditSize :=RichEdit2.GetTextLen;<br>&nbsp; if EditSize &lt;= 0 then<br>&nbsp; &nbsp; showmessage('没有需要数据保存的数据')<br>&nbsp; else begin<br>&nbsp; &nbsp; if SaveDialog1.Execute then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if FileExists(SaveDialog1.FileName) then<br>&nbsp; &nbsp; &nbsp; &nbsp; if MessageDlg('文件:'+SaveDialog1.FileName+'已存在,是否覆盖?',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mtConfirmation, mbYesNoCancel, 0) &lt;&gt; idYes then Exit;<br>&nbsp; &nbsp; &nbsp; AssignFile(MySaveFile,SaveDialog1.FileName);<br>&nbsp; &nbsp; &nbsp; Rewrite(MySaveFile);<br>&nbsp; &nbsp; &nbsp; Write(MySaveFile,RichEdit2.Lines.text);<br>&nbsp; &nbsp; &nbsp; CloseFile(MySaveFile);<br>&nbsp; &nbsp; &nbsp; //RichEdit2.Lines.SaveToFile(SaveDialog1.FileName);<br>&nbsp; &nbsp; end ;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>begin<br>&nbsp; if Readstring1 = Readstring2 then<br>&nbsp; begin<br>&nbsp; &nbsp; StatusBar1.Panels[3].Text :='接收完成:'+inttostr(ReLen);<br>&nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; reLen :=0 ;<br>&nbsp; &nbsp; Timer1.Enabled := False ;<br>&nbsp; end<br>&nbsp; else begin<br>&nbsp; &nbsp; Readstring2:= Readstring1 ;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.CheckBox1Click(Sender: TObject);<br>begin<br>&nbsp; if CheckBox1.Checked = True then<br>&nbsp; begin<br>&nbsp; &nbsp; repeat<br>&nbsp; &nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; &nbsp; Sleep(500) ;<br>&nbsp; &nbsp; until Button2.Enabled ;<br>&nbsp; &nbsp; //sleep(10000);<br>&nbsp; &nbsp; Button2Click(Button2);<br>&nbsp; end ;<br>end;<br><br>end.<br>
 
多人接受答案了。
 
后退
顶部