小弟用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.

解决方案 »

  1.   

    改成
    unit2.tDisp:=unit2.TDisplay.Create(FALSE); //不能启  //就行了
      

  2.   

    我试了一下还是不行,出错信息为Access violation at address 004191F8 in module 'MBT.exe'.Write of address 0000000E.请再帮我找找原因。谢谢
      

  3.   

    没有sleep是不是线程占有cpu时间太多了
      

  4.   

    constructor TDisplay.Create;
    begin
        inherited Create(False);
        FreeOnTerminate:=true;
        OnTerminate:=Close;
    end;
      

  5.   

    我现在代码已改为
    constructor TDisplay.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
      FreeOnTerminate:=true;
      OnTerminate:=Close;
      //Priority := tpNormal;
    end;
    可还是通不过,OnTerminate函数需要一个对象(Sender: TObject),注释掉这句还是出现同样错误,各位高手救命呀!
      

  6.   

    问题已解决,放分
    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.