如何建立能调用串口控件的线程(200分)

  • 主题发起人 主题发起人 liuxiaoqing
  • 开始时间 开始时间
L

liuxiaoqing

Unregistered / Unconfirmed
GUEST, unregistred user!
我用了一个串口控件,它在发送数据是需要不停的检查端口状态,因而当我执行发送命令时,程序不能响应其它的消息,而我想不停的在数据库中查询数据来发送数据,不用线程,程序当然是不能响应其它任何操作,不知怎样用线程来解决这个问题(保留当前的控件),从帮助上看大多VCL是线程不安全的,请大虾们指教。
 
使用TTread建立一个线程来查询Port不就可以了?如果要在查询中通知主程序,可以使用消息或事件。
 
用TThread的synchronize函数可以从线程里调用VCL.让你的线程成为程序主线程的
一部分.当不再需要VCL的时候,中断代码的同步部分.
 
问题是我不能直接去查询端口,目前我只能调用构件的发送方法来发送数据,同时根据构件的事件来判断是不是发送成功了。
 
问题是我不能直接去查询端口,目前我只能调用构件的发送方法来发送数据,同时根据构件的事件来判断是不是发送成功了。
 
在你的线程中动态创建一个你使用的控件的实例,然后在处理控件事件的程序
代码中和主线程进行消息通信,不要将你的哪个什麽控件放在主窗体上.
这样可以在线程中正常使用,还不需要synchronize之类的东西.
 
unit ReadComm;
interface
uses
Windows, Messages, SysUtils, Classes, Forms;
const
TimerSpeed = 200;
type
TOopsCommPort = class
protected
hMainWnd : THandle;
Dcb : Tdcb;
Commtimeouts : Tcommtimeouts;
ComPortHandle : THANDLE;
public
TempInBuffer : pointer;
function Open(hOwner: THandle;
CommName: Pchar) :Boolean;
procedure Close;
function TimerWndProc:Byte;
end;

var CommPort: TOopsCommPort;
implementation
function TOopsCommPort.Open(hOwner: THandle ;
CommName: Pchar): Boolean;
begin
hMainWnd := hOwner;
GetMem( TempInBuffer, 1024);
ComPortHandle := CreateFile(CommName,GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ComPortHandle <= 0 then
begin
Result := False;
exit;
//Error Open Comm port;
end;
GetCommState(ComPortHandle, Dcb);
Dcb.BaudRate := 9600;// Baud rate to use
Dcb.Parity := 0;
// None parity to use
Dcb.StopBits := 0;
// 0 stop bits to use
Dcb.XONChar := #17;
// XON ASCII char - DC1, Ctrl-Q, ASCII 17
Dcb.XOFFChar := #19;
// XOFF ASCII char - DC3, Ctrl-S, ASCII 19
SetCommState(ComPortHandle, Dcb);
SetupComm( ComPortHandle, 512, 512);
GetCommTimeouts(ComPortHandle, Commtimeouts);
Commtimeouts.ReadIntervalTimeout := 1;
//maximum time in milliseconds
Commtimeouts.ReadTotalTimeoutMultiplier := 0;
Commtimeouts.ReadTotalTimeoutConstant := 1;
Commtimeouts.WriteTotalTimeoutMultiplier := 0;
Commtimeouts.WriteTotalTimeoutConstant := 0;
SetCommTimeouts(ComPortHandle, Commtimeouts);
SetTimer(hMainWnd, 1, TimerSpeed, nil );
Result := True;
end;

procedure TOopsCommPort.Close;
begin
KillTimer(hMainWnd, 1 );
CloseHandle(ComPortHandle);
ComPortHandle := 0;
FreeMem( TempInBuffer, 1024);
Destroy;
end;

function TOopsCommPort.TimerWndProc:Byte;
var nRead, nToRead, ComErrCode: UINT;
comStat: TComstat;
begin
Result:=$FF;
ClearCommError( ComPortHandle, ComErrCode, @comStat );
nRead := 0;
nToRead := ComStat.cbInQue;
if (nToRead > 0) and ReadFile(ComPortHandle, TempInBuffer^, nToRead, nRead, nil ) then
begin
if (nRead <> 0) then
Result:=(PByte(TempInBuffer))^;
end
end;

end.
 
能告诉我VB或Delphi中哪个控件可以读取串口的数据吗?非常感谢
 
mscomm
控件是通用的。
 
介绍一篇文章,呵呵 vc的,可 参考
http://www.ccidnet.com/html/tech/guide/2000/08/04/58_1051.html
 
串行通信必须独占一个线程,考虑用async32吧
 
spcomm也不错阿
 
其实用Win32 API直接编写串口检测程序最好,我做过检测串口、Modem报警的程序,
用控件其实也方便不了太多,利用API编写自己可以完全控制程序非常好调试,检测线程
得到数据(检查合理)后,给主窗体发一条通知消息就可以了,我做的程序效果和好,非常
实时,编写和调试也很简单。
 
只要注意CPU时间片的分配就行了
 
多人接受答案了。
 
后退
顶部