WinComm/delphi/TESTMAIN.PAS
Scott Duensing dd8326d16a Add native Delphi 1.0 TKPComm serial communications component
VBX registration is non-functional in VB4 16-bit (VBRegisterModel is a
no-op, VBGetModelInfo never called). Native Delphi component avoids all
DLL/export/registration issues — compiles directly into the IDE.

TKPComm is a TComponent descendant calling the Windows 3.1 comm API
directly. Uses RegisterClass/CreateWindow for WM_COMMNOTIFY dispatch
with the component instance pointer stored in cbWndExtra. Includes a
test application (KPTEST) with send/receive UI built entirely in code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:04:54 -06:00

267 lines
6.4 KiB
ObjectPascal

unit TestMain;
{ Test application for the TKPComm serial communications component. }
{ Form and all controls are created in code (no DFM required). }
interface
uses
SysUtils, Classes, WinTypes, WinProcs, Messages,
Forms, Controls, StdCtrls, KPComm;
type
TMainForm = class(TForm)
private
FComm: TKPComm;
FLabelPort: TLabel;
FEditPort: TEdit;
FLabelSettings: TLabel;
FEditSettings: TEdit;
FBtnOpen: TButton;
FBtnClose: TButton;
FLabelStatus: TLabel;
FLabelRecv: TLabel;
FMemoRecv: TMemo;
FEditSend: TEdit;
FBtnSend: TButton;
FLabelInfo: TLabel;
procedure BtnCloseClick(Sender: TObject);
procedure BtnOpenClick(Sender: TObject);
procedure BtnSendClick(Sender: TObject);
procedure CommEvent(Sender: TObject);
procedure UpdateStatus;
public
constructor Create(AOwner: TComponent); override;
end;
var
MainForm: TMainForm;
implementation
procedure TMainForm.BtnCloseClick(Sender: TObject);
begin
FComm.PortOpen := False;
FMemoRecv.Lines.Add('--- Port closed ---');
UpdateStatus;
end;
procedure TMainForm.BtnOpenClick(Sender: TObject);
begin
try
FComm.CommPort := StrToInt(FEditPort.Text);
FComm.Settings := FEditSettings.Text;
FComm.RThreshold := 1;
FComm.PortOpen := True;
FMemoRecv.Lines.Add('--- Port opened on COM' +
FEditPort.Text + ' at ' + FEditSettings.Text + ' ---');
except
on E: Exception do
FMemoRecv.Lines.Add('Open failed: ' + E.Message);
end;
UpdateStatus;
end;
procedure TMainForm.BtnSendClick(Sender: TObject);
begin
if Length(FEditSend.Text) = 0 then
Exit;
try
FComm.Output := FEditSend.Text + #13;
FMemoRecv.Lines.Add('TX: ' + FEditSend.Text);
FEditSend.Text := '';
except
on E: Exception do
FMemoRecv.Lines.Add('Send failed: ' + E.Message);
end;
UpdateStatus;
end;
procedure TMainForm.CommEvent(Sender: TObject);
var
S: string;
begin
case FComm.CommEvent of
comEvReceive:
begin
S := FComm.Input;
if Length(S) > 0 then
FMemoRecv.Lines.Add('RX: ' + S);
end;
comEvCTS:
FMemoRecv.Lines.Add('CTS changed');
comEvDSR:
FMemoRecv.Lines.Add('DSR changed');
comEvCD:
FMemoRecv.Lines.Add('CD changed');
comEvRing:
FMemoRecv.Lines.Add('Ring');
comEvEOF:
FMemoRecv.Lines.Add('EOF received');
comEvtBreak:
FMemoRecv.Lines.Add('Break received');
comEvtFrame:
FMemoRecv.Lines.Add('Framing error');
comEvtOverrun:
FMemoRecv.Lines.Add('Overrun error');
comEvtRxOver:
FMemoRecv.Lines.Add('RX buffer overflow');
comEvtParity:
FMemoRecv.Lines.Add('Parity error');
comEvtTxFull:
FMemoRecv.Lines.Add('TX buffer full');
end;
UpdateStatus;
end;
constructor TMainForm.Create(AOwner: TComponent);
begin
inherited CreateNew(AOwner);
Caption := 'KPComm Test';
Width := 500;
Height := 380;
BorderStyle := bsSingle;
{ Serial component }
FComm := TKPComm.Create(Self);
FComm.OnComm := CommEvent;
{ Row 1: Port and Settings }
FLabelPort := TLabel.Create(Self);
FLabelPort.Parent := Self;
FLabelPort.Left := 8;
FLabelPort.Top := 12;
FLabelPort.Caption := 'Port:';
FEditPort := TEdit.Create(Self);
FEditPort.Parent := Self;
FEditPort.Left := 44;
FEditPort.Top := 8;
FEditPort.Width := 32;
FEditPort.Text := '1';
FLabelSettings := TLabel.Create(Self);
FLabelSettings.Parent := Self;
FLabelSettings.Left := 88;
FLabelSettings.Top := 12;
FLabelSettings.Caption := 'Settings:';
FEditSettings := TEdit.Create(Self);
FEditSettings.Parent := Self;
FEditSettings.Left := 148;
FEditSettings.Top := 8;
FEditSettings.Width := 140;
FEditSettings.Text := '9600,N,8,1';
{ Row 2: Open/Close buttons and status }
FBtnOpen := TButton.Create(Self);
FBtnOpen.Parent := Self;
FBtnOpen.Left := 8;
FBtnOpen.Top := 38;
FBtnOpen.Width := 65;
FBtnOpen.Height := 25;
FBtnOpen.Caption := 'Open';
FBtnOpen.OnClick := BtnOpenClick;
FBtnClose := TButton.Create(Self);
FBtnClose.Parent := Self;
FBtnClose.Left := 80;
FBtnClose.Top := 38;
FBtnClose.Width := 65;
FBtnClose.Height := 25;
FBtnClose.Caption := 'Close';
FBtnClose.Enabled := False;
FBtnClose.OnClick := BtnCloseClick;
FLabelStatus := TLabel.Create(Self);
FLabelStatus.Parent := Self;
FLabelStatus.Left := 160;
FLabelStatus.Top := 44;
FLabelStatus.Caption := 'Closed';
{ Receive area }
FLabelRecv := TLabel.Create(Self);
FLabelRecv.Parent := Self;
FLabelRecv.Left := 8;
FLabelRecv.Top := 70;
FLabelRecv.Caption := 'Received:';
FMemoRecv := TMemo.Create(Self);
FMemoRecv.Parent := Self;
FMemoRecv.Left := 8;
FMemoRecv.Top := 86;
FMemoRecv.Width := 476;
FMemoRecv.Height := 186;
FMemoRecv.ScrollBars := ssVertical;
FMemoRecv.ReadOnly := True;
{ Send row }
FEditSend := TEdit.Create(Self);
FEditSend.Parent := Self;
FEditSend.Left := 8;
FEditSend.Top := 280;
FEditSend.Width := 400;
FBtnSend := TButton.Create(Self);
FBtnSend.Parent := Self;
FBtnSend.Left := 416;
FBtnSend.Top := 280;
FBtnSend.Width := 65;
FBtnSend.Height := 25;
FBtnSend.Caption := 'Send';
FBtnSend.Enabled := False;
FBtnSend.OnClick := BtnSendClick;
{ Status info line }
FLabelInfo := TLabel.Create(Self);
FLabelInfo.Parent := Self;
FLabelInfo.Left := 8;
FLabelInfo.Top := 316;
FLabelInfo.Width := 476;
FLabelInfo.Caption := 'RX: 0 TX: 0 Event: 0';
end;
procedure TMainForm.UpdateStatus;
var
S: string;
begin
if FComm.PortOpen then
FLabelStatus.Caption := 'Open'
else
FLabelStatus.Caption := 'Closed';
FBtnOpen.Enabled := not FComm.PortOpen;
FBtnClose.Enabled := FComm.PortOpen;
FBtnSend.Enabled := FComm.PortOpen;
FEditSend.Enabled := FComm.PortOpen;
S := 'RX: ' + IntToStr(FComm.InBufferCount) +
' TX: ' + IntToStr(FComm.OutBufferCount);
if FComm.PortOpen then
begin
if FComm.CTSHolding then
S := S + ' CTS: On'
else
S := S + ' CTS: Off';
if FComm.DSRHolding then
S := S + ' DSR: On'
else
S := S + ' DSR: Off';
if FComm.CDHolding then
S := S + ' CD: On'
else
S := S + ' CD: Off';
end;
S := S + ' Event: ' + IntToStr(FComm.CommEvent);
FLabelInfo.Caption := S;
end;
end.