各位兄弟,请问怎样去检测计算机的COM口数据已经发完?(100分)

  • 主题发起人 主题发起人 dxwleaf
  • 开始时间 开始时间
D

dxwleaf

Unregistered / Unconfirmed
GUEST, unregistred user!
各位兄弟,请问怎样用WINAPI函数去检测计算机的COM口的数据已经发完?
 
读文件ReadFile
 
用异步(Overlappped)方式打开串口.
var
Overlapped: TOverlapped;
FillChar(Overlapped, SizeOf(Overlapped), 0);
Overlapped.hEvent := CreateEvent(nil, True, True, nil);
WaitCommEvent(FComPort.Handle, Mask, @Overlapped);
if (EV_TXEMPTY and Mask) <> 0 then
串口数据已发完。
详细用法可以参考MSDN.
放多COM控件都用OnTxEmpty事件,提示用户响应COM数据发完。
 
我这有个用API监听串口的DEMO,你看一下吧
unit frmComm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, shellapi;
const MAXBLOCK = 160;
type
TComm = record
idComDev: THandle;
fConnected: Boolean;
end;

TCommForm = class(TForm)
ComboBox1: TComboBox;
Button1: TButton;
Button2: TButton;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

TCommThread = class(TThread)
protected
procedure Execute;
override;
public
constructor Create;
end;

var
CommForm: TCommForm;
CommHandle: THandle;
Connected: Boolean;
CommThread: TCommThread;
implementation
{$R *.dfm}
procedure TCommThread.Execute;
var
dwErrorFlags, dwLength: DWORD;
ComStat: PComStat;
fReadStat: Boolean;
InChar: Char;
AbIn: string;
XX, YY:do
uble;
//file;
//经度、纬度
VID: string;
//file: //车号
begin
while Connecteddo
begin
GetMem(ComStat, SizeOf(TComStat));
ClearCommError(CommHandle, dwErrorFlags, ComStat);
if (dwErrorFlags > 0) then
begin
PurgeComm(CommHandle, (PURGE_RXABORT and PURGE_RXCLEAR));
// return 0;
end;
dwLength := ComStat.cbInQue;
if (dwLength > 0) then
begin
fReadStat := ReadFile(CommHandle, InChar, 1, dwLength, nil);
if (fReadStat) then
begin
if (InChar <> Chr(13)) and (Length(abIn) < MAXBLOCK + 5) then
AbIn := AbIn + InChar
else
begin
//...{接收完毕,}
end;
//if (fReadStat>0){
end;
//file: //if (dwLength>0){
FreeMem(ComStat);
end;
{while}
end;
end;

constructor TCommThread.Create;
begin
FreeOnTerminate := TRUE;
inherited Create(FALSE);
//file: //Createsuspended = false
end;

procedure TCommForm.Button1Click(Sender: TObject);
var
CommTimeOut: TCOMMTIMEOUTS;
DCB: TDCB;
fRetVal: Boolean;
begin
StatusBar1.SimpleText := '连接中...';
CommHandle := CreateFile(PChar(ComboBox1.Text), GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL
, 0);
if CommHandle = INVALID_HANDLE_VALUE then
begin
StatusBar1.SimpleText := '连接失败';
Exit;
end;
StatusBar1.SimpleText := '已同端口' + ComboBox1.Text + '连接!';
CommTimeOut.ReadIntervalTimeout := MAXDWORD;
CommTimeOut.ReadTotalTimeoutMultiplier := 0;
CommTimeOut.ReadTotalTimeoutConstant := 0;
SetCommTimeouts(CommHandle, CommTimeOut);
GetCommState(CommHandle, DCB);
DCB.BaudRate := 9600;
DCB.ByteSize := 8;
DCB.Parity := NOPARITY;
DCB.StopBits := ONESTOPBIT;
fRetVal := SetCommState(CommHandle, DCB);
if (fRetVal) then
begin
Connected := TRUE;
try
CommThread := TCommThread.Create;
except
Connected := FALSE;
CloseHandle(CommHandle);
fRetVal := FALSE;
StatusBar1.SimpleText := '线程建立失败';
Exit;
end;
end
else
begin
Connected := FALSE;
CloseHandle(CommHandle);
end;
end;

procedure TCommForm.Button2Click(Sender: TObject);
begin
if Connected then
begin
Connected := FALSE;
CloseHandle(CommHandle);
{终止线程}
CommThread.Terminate;
StatusBar1.SimpleText := '关闭端口' + ComboBox1.Text;
end
else
StatusBar1.SimpleText := '已关闭端口' + ComboBox1.Text;
end;

procedure TCommForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if Connected then
begin
Connected := FALSE;
CloseHandle(CommHandle);
CommThread.Terminate;
StatusBar1.SimpleText := '关闭端口' + ComboBox1.Text;
end;
end;

end.
 
谢谢两位的支持!
请问app2001:
 如果我这样写可以吗?
 int GetOUTBuffCount()
{
COMSTAT coms;
ClearCommError(hComm,0,&amp;coms);
return coms.cbOutQue;
}
bool __stdcall _export Polling(int MachNo,unsigned char *Result,int delay, int Wait10)
{
while (GetOUTBuffCount()!=0)
{
}



}
当不为0在此做空循环,到它为0止。
 
报歉,俺的C实在拙得很,这方面给不了你什么好意见了。
 
to:app2001
如用:
int GetInBuffCount()
{
COMSTAT coms;
ClearCommError(hComm,0,&amp;coms);
return coms.cbInQue;
}
if (GetInBuffCount()>0)
{
}
这样可以检测到串口有没有数据输入,可以执行里面的内容
但是如果用:
int GetOUTBuffCount()
{
COMSTAT coms;
ClearCommError(hComm,0,&amp;coms);
return coms.cbOutQue;
}
//----------------------------
while GetOUTBuffCount()!=0)
{
}
我想当它为0时执行空操作,我也是初学BCB对通讯也不是很了解,
不知这样写能不能检测到 串口中的数据已经发完了!
谢谢!
 
这样,你去下一个SPCOMM来看一下,那也是直接用API来做的,从哪里面也许你能看出些门道来呢?
 
看了一下,没瞧去什么道道!
大家都很忙吗?怎没回答了?
 
"用异步(Overlappped)方式打开串口."
请问打开串口的方式有多少种啊?每种方式有什么优缺点啊?
那位大虾给讲讲课好吗?3Q
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部