小弟用DELPHI创建了一个线程对象并加入一些串口通讯代码,可是在主线程(界面线程)启动这些代码时出错(accis,不知如何解决,请教代码如下
//////////////////////////////////////////////////////////
unit MIB;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Menus;type
TfrmMIB = class(TForm)
btnENT: TButton;
edtNUM: TEdit;
btnCALL: TButton;
btnCLR: TButton;
btnMMIN: TButton;
panDisplay: TPanel;
mnuMIB: TMainMenu;
N3: TMenuItem;
nExit: TMenuItem;
N1: TMenuItem;
nUsehelp: TMenuItem;
bAbout: TMenuItem;
cmbCOM: TComboBox;
ListBox1: TListBox;
Label1: TLabel;
dlgSaveLST: TSaveDialog;
btnSaveData: TButton;
btnAddData: TButton;
procedure FormShow(Sender: TObject);
procedure nExitClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure cmbCOMChange(Sender: TObject); private
{ Private declarations } procedure OpenComm(strPort: String);
procedure ExitSystem;
public
{ Public declarations } end;var
frmMIB: TfrmMIB;
hSerialPort: THandle;implementation
{$R *.dfm}uses DISPLAY;procedure TfrmMIB.FormShow(Sender: TObject);
begin
btnENT.SetFocus;
OpenComm(cmbCOM.Text);
DISPLAY.tDisp.Create(FALSE); //不能启动/////////////////////////////////////////////
end;
procedure TfrmMIB.nExitClick(Sender: TObject);
begin
frmMIB.Close;
end;procedure TfrmMIB.OpenComm(strPort: String);
var
cc:TCOMMCONFIG;
Temp:String;begin
Temp:=cmbCOM.Text;
hSerialPort:=CreateFile(PChar(Temp),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
0,
0);
if (hSerialPort=INVALID_HANDLE_VALUE) then
begin
{MessageBox(0,
'打开串口时发生错误',
'',
MB_OK); }
panDisplay.Caption := '';
exit;
end;
GetCommState(hSerialPort,cc.dcb);
cc.dcb.BaudRate:=CBR_4800;
cc.dcb.ByteSize:=8;
cc.dcb.Parity:=NOPARITY;
cc.dcb.StopBits:=ONESTOPBIT; if not SetCommState(hSerialPort, cc.dcb) then
begin
{MessageBox(0,
'不能设置串口',
'',
MB_OK);}
panDisplay.Caption := '';
CloseHandle(hSerialPort);
exit;
end;
end;procedure TfrmMIB.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ExitSystem;
end;procedure TfrmMIB.ExitSystem;
begin
CloseHandle(hSerialPort);
end;
procedure TfrmMIB.cmbCOMChange(Sender: TObject);
begin
OpenComm(cmbCOM.Text);
end;end.///////////////////////////////////////////////////////////////unit DISPLAY;interfaceuses
Classes,Windows;type
TDisplay = class(TThread)
private
{ Private declarations }
procedure Receives;
protected
procedure Execute; override;
end;var
tDisp: TDisplay;
implementationuses MIB;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure TDisplay.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ TDisplay }procedure TDisplay.Execute;
begin
{ Place thread code here }
Receives;
end;procedure TDisplay.Receives;
var
TempString : string;
inBuff : array[0..2047] of Char;
BytesRead, dwEvent,dwError : LongWORD;
cs : TCOMSTAT;
begin
ClearCommError(MIB.hSerialPort, dwError, @cs);
if cs.cbInQue>sizeof(inBuff) then
begin
PurgeComm(hSerialPort, PURGE_RXCLEAR);
exit;
end;
ReadFile(MIB.hSerialPort, inBuff, cs.cbInQue, BytesRead, nil);
TempString:=Copy(inBuff, 1, cs.cbInQue);
MIB.frmMIB.panDisplay.Caption:= TempString;
end;end.
//////////////////////////////////////////////////////////
unit MIB;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Menus;type
TfrmMIB = class(TForm)
btnENT: TButton;
edtNUM: TEdit;
btnCALL: TButton;
btnCLR: TButton;
btnMMIN: TButton;
panDisplay: TPanel;
mnuMIB: TMainMenu;
N3: TMenuItem;
nExit: TMenuItem;
N1: TMenuItem;
nUsehelp: TMenuItem;
bAbout: TMenuItem;
cmbCOM: TComboBox;
ListBox1: TListBox;
Label1: TLabel;
dlgSaveLST: TSaveDialog;
btnSaveData: TButton;
btnAddData: TButton;
procedure FormShow(Sender: TObject);
procedure nExitClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure cmbCOMChange(Sender: TObject); private
{ Private declarations } procedure OpenComm(strPort: String);
procedure ExitSystem;
public
{ Public declarations } end;var
frmMIB: TfrmMIB;
hSerialPort: THandle;implementation
{$R *.dfm}uses DISPLAY;procedure TfrmMIB.FormShow(Sender: TObject);
begin
btnENT.SetFocus;
OpenComm(cmbCOM.Text);
DISPLAY.tDisp.Create(FALSE); //不能启动/////////////////////////////////////////////
end;
procedure TfrmMIB.nExitClick(Sender: TObject);
begin
frmMIB.Close;
end;procedure TfrmMIB.OpenComm(strPort: String);
var
cc:TCOMMCONFIG;
Temp:String;begin
Temp:=cmbCOM.Text;
hSerialPort:=CreateFile(PChar(Temp),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
0,
0);
if (hSerialPort=INVALID_HANDLE_VALUE) then
begin
{MessageBox(0,
'打开串口时发生错误',
'',
MB_OK); }
panDisplay.Caption := '';
exit;
end;
GetCommState(hSerialPort,cc.dcb);
cc.dcb.BaudRate:=CBR_4800;
cc.dcb.ByteSize:=8;
cc.dcb.Parity:=NOPARITY;
cc.dcb.StopBits:=ONESTOPBIT; if not SetCommState(hSerialPort, cc.dcb) then
begin
{MessageBox(0,
'不能设置串口',
'',
MB_OK);}
panDisplay.Caption := '';
CloseHandle(hSerialPort);
exit;
end;
end;procedure TfrmMIB.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ExitSystem;
end;procedure TfrmMIB.ExitSystem;
begin
CloseHandle(hSerialPort);
end;
procedure TfrmMIB.cmbCOMChange(Sender: TObject);
begin
OpenComm(cmbCOM.Text);
end;end.///////////////////////////////////////////////////////////////unit DISPLAY;interfaceuses
Classes,Windows;type
TDisplay = class(TThread)
private
{ Private declarations }
procedure Receives;
protected
procedure Execute; override;
end;var
tDisp: TDisplay;
implementationuses MIB;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure TDisplay.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ TDisplay }procedure TDisplay.Execute;
begin
{ Place thread code here }
Receives;
end;procedure TDisplay.Receives;
var
TempString : string;
inBuff : array[0..2047] of Char;
BytesRead, dwEvent,dwError : LongWORD;
cs : TCOMSTAT;
begin
ClearCommError(MIB.hSerialPort, dwError, @cs);
if cs.cbInQue>sizeof(inBuff) then
begin
PurgeComm(hSerialPort, PURGE_RXCLEAR);
exit;
end;
ReadFile(MIB.hSerialPort, inBuff, cs.cbInQue, BytesRead, nil);
TempString:=Copy(inBuff, 1, cs.cbInQue);
MIB.frmMIB.panDisplay.Caption:= TempString;
end;end.
解决方案 »
- 请问DBExpress的StoredProcName属性时,不能出现数据库中的存储过程,是什么原因?
- Tbaimap对像与Tcanvas对像的赋值
- oracle 和 mts(com+)的读不能锁定数据的事务问题
- ****失恋了,心情不好,大家有好的聊天室吗?****
- ***********招聘程序员***********************
- 如何将SpeedButton的快捷键设置成F2或者F3
- 急急!求教delphi程序在windows操作系统下不同版本之间的运行问题。
- IdSmtp 用 smtp.netease.com 发送邮件的问题
- 在FastNet中的MNStrm和MNStrmServ必须成对出现吗?如果是,怎么样在MNStrmServ端实时取得已传输的数据流
- 问题:如果要把打印做成一个公共模块(*.DLL),独立于要打印的格式和内容,要注意什么
- 如何自定义纸张大小并且如何实现打印一行记录后不走纸
- Delphi5 里面用到了 ADOTable.....等等,问题出现了
unit2.tDisp:=unit2.TDisplay.Create(FALSE); //不能启 //就行了
begin
inherited Create(False);
FreeOnTerminate:=true;
OnTerminate:=Close;
end;
constructor TDisplay.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate:=true;
OnTerminate:=Close;
//Priority := tpNormal;
end;
可还是通不过,OnTerminate函数需要一个对象(Sender: TObject),注释掉这句还是出现同样错误,各位高手救命呀!
unit MIB;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Menus;type
TfrmMIB = class(TForm)
btnENT: TButton;
edtNUM: TEdit;
btnCALL: TButton;
btnCLR: TButton;
btnMMIN: TButton;
panDisplay: TPanel;
mnuMIB: TMainMenu;
N3: TMenuItem;
nExit: TMenuItem;
N1: TMenuItem;
nUsehelp: TMenuItem;
bAbout: TMenuItem;
cmbCOM: TComboBox;
ListBox1: TListBox;
Label1: TLabel;
dlgSaveLST: TSaveDialog;
btnSaveData: TButton;
btnAddData: TButton;
procedure FormShow(Sender: TObject);
procedure nExitClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure cmbCOMChange(Sender: TObject); private
{ Private declarations }
ThreadsRunning : integer;
Procedure ThreadDone(Sender: TObject);
procedure OpenComm(strPort: String);
procedure ExitSystem;
public
{ Public declarations } end;var
frmMIB: TfrmMIB;
hSerialPort: THandle;implementation
{$R *.dfm}uses DISPLAY;procedure TfrmMIB.FormShow(Sender: TObject);
begin
btnENT.SetFocus;
OpenComm(cmbCOM.Text);
with TDISPLAY.Create(False) do //关键改进
OnTerminate := ThreadDone; //结构很重要
ThreadsRunning := 1;
end;procedure TfrmMIB.ThreadDone(Sender: TObject);
begin
{Dec(ThreadsRunning);
if ThreadsRunning = 0 then
begin
end; }
end;procedure TfrmMIB.nExitClick(Sender: TObject);
begin
frmMIB.Close;
end;procedure TfrmMIB.OpenComm(strPort: String);
var
cc:TCOMMCONFIG;
Temp:String;begin
Temp:=cmbCOM.Text;
hSerialPort:=CreateFile(PChar(Temp),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
0,
0);
if (hSerialPort=INVALID_HANDLE_VALUE) then
begin
{MessageBox(0,
'打开串口时发生错误',
'',
MB_OK); }
panDisplay.Caption := '';
exit;
end;
GetCommState(hSerialPort,cc.dcb);
cc.dcb.BaudRate:=CBR_4800;
cc.dcb.ByteSize:=8;
cc.dcb.Parity:=NOPARITY;
cc.dcb.StopBits:=ONESTOPBIT; if not SetCommState(hSerialPort, cc.dcb) then
begin
{MessageBox(0,
'不能设置串口',
'',
MB_OK);}
panDisplay.Caption := '';
CloseHandle(hSerialPort);
exit;
end;
end;procedure TfrmMIB.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ExitSystem;
end;procedure TfrmMIB.ExitSystem;
begin
CloseHandle(hSerialPort);
end;procedure TfrmMIB.cmbCOMChange(Sender: TObject);
begin
OpenComm(cmbCOM.Text);
end;end.