【问题标题】:Tcomport in console application with Delphi 10.3带有 Delphi 10.3 的控制台应用程序中的 Tcomport
【发布时间】:2018-12-30 15:57:09
【问题描述】:

我在一个简单的 Delphi 10.3 控制台应用程序中使用 TComPort (4.11f),见下文,但我没有得到任何数据。

在 VCL 应用程序中使用相同的代码可以正常工作。有什么想法吗?

我的猜测是我没有正确连接 ComDataPacket1ComPort1 对象。但是,我找不到其他方法。

program commapp;

{$APPTYPE CONSOLE}

uses
  Vcl.Forms, CPort, CPortCtl, system.sysutils, classes, Windows;

{$R *.res}

var
  ComPort1: TComPort;
  ComDataPacket1: TComDataPacket;
  Sender: TObject;
  Str: string;

type
  TEventHandlers = class
    class procedure ComDataPacket1Packet(Sender: TObject; const Str: string);
  end;

class procedure TEventHandlers.ComDataPacket1Packet(Sender: TObject; const Str: string);
begin
  WriteLn('Inside the proc with ' + str);
end;

begin // Main program                 ///
  ComPort1 := TComPort.Create(nil);  // create the    comm
  ComDataPacket1 := TComDataPacket.Create(nil);
  ComPort1.BaudRate := br115200;                 // set parameters
  ComPort1.Port     := 'COM3';
  ComPort1.Parity.Bits := prNone;

  ComDataPacket1.Size := 33;
  ComDataPacket1.ComPort  := ComPort1;
  ComDataPacket1.OnPacket := TEventHandlers.ComDataPacket1Packet;
  ComDataPacket1.StartString := '';
  ComDataPacket1.StopString := '';

  if ParamCount = 0 then // no paramters passed enter menu
  begin
    ComPort1.ShowSetupDialog; // Open the port settings.
    ComPort1.Open;
    ComPort1.WriteStr('b') ;  // Send the command to start sending data
    WriteLn('After sending an b I get  :  ' + str); 
    ReadLn;
  end;

  // release the components
  ComDataPacket1.Free;
  ComPort1.Free;
end.

【问题讨论】:

  • 你在 VCL 应用程序中也使用 class 过程作为事件处理程序吗?带有空标记的数据包的目的是什么?
  • 不,这是一个区别。如果我不将 proc 包装在一个类中,我会根据下面的链接得到一个错误。所以我将它包装在一个类中以使编译器满意。 stackoverflow.com/questions/11314641/… 空的开始和结束字符串在我离开或取出时没有任何区别,它们在两个版本中。
  • 但是你可以使用没有class的常用方法(但是创建TEventHandlers实例)。
  • 是的,但是取出类并创建 TEventHandlers 的实例并将其附加到 Comport 并没有任何区别。
  • ReadLn 不足以等待在控制台应用程序中处理事件。就像@RemyLebeau 说的那样,您必须为要处理的事件实现一个消息循环。

标签: delphi console-application tcomport


【解决方案1】:

在等待OnPacket 事件触发时尝试运行消息循环,例如:

program commapp;

{$APPTYPE CONSOLE}

uses
  Vcl.Forms, CPort, CPortCtl, System.SysUtils,
  System.Classes, Winapi.Windows, System.SyncObjs;

{$R *.res}

var
  ComPort1: TComPort;
  ComDataPacket1: TComDataPacket;
  DataEvent: TEvent;
  hEvent: THandle;
  DataStr: string;

type
  TEventHandlers = class
    class procedure ComDataPacket1Packet(Sender: TObject; const Str: string);
  end;

class procedure TEventHandlers.ComDataPacket1Packet(Sender: TObject; const Str: string);
begin
  WriteLn('Inside the proc with ' + Str);
  DataStr := Str;
  DataEvent.SetEvent;
end;

begin // Main program
  ComPort1 := TComPort.Create(nil); // create the comm
  ComDataPacket1 := TComDataPacket.Create(nil);
  DataEvent := TEvent.Create;

  ComPort1.BaudRate := br115200; // set parameters
  ComPort1.Port := 'COM3';
  ComPort1.Parity.Bits := prNone;

  ComDataPacket1.Size := 33;
  ComDataPacket1.ComPort := ComPort1;
  ComDataPacket1.OnPacket := TEventHandlers.ComDataPacket1Packet;
  ComDataPacket1.StartString := '';
  ComDataPacket1.StopString := '';

  if ParamCount = 0 then // no paramters passed enter menu
  begin
    ComPort1.ShowSetupDialog; // Open the port settings.
  end;

  ComPort1.Open;
  ComPort1.WriteStr('b') ; // Send the command to start sending data

  hEvent := DataEvent.Handle;
  repeat
    case MsgWaitForMultipleObjects(1, hEvent, False, INFINITE, QS_ALLINPUT) of
      WAIT_OBJECT_0: Break;
      WAIT_OBJECT_0 + 1: Application.HandleMessage; // or Application.ProcessMessages()
      WAIT_FAILED: RaiseLastOSError;
    end;
  until False;

  WriteLn('After sending an b I get : ' + DataStr);
  ReadLn;

  // release the components
  DataEvent.Free;
  ComDataPacket1.Free;
  ComPort1.Free;
end.

【讨论】:

  • 感谢示例代码。运行它我在 MsgWaitForMultipleObjects(1, DataEvent.Handle, False, INFINITE, QS_ALLINPUT) 上收到一条错误消息,指出“常量对象不能作为 var 参数传递”,我相信是指 DataEvent.Handle。我查看了这个并尝试将指针传递给它无济于事,并尝试将该参数设置为常规 Thandle。后者有效,但不再附加到我认为没有数据的事件。
  • @user3338048 对此感到抱歉。我调整了答案。
  • 感谢您的编辑,完美运行。我已经接受了答案。
猜你喜欢
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
相关资源
最近更新 更多