|
|
|
|
Checking for Available Ports and Modemswith Async Professional
One common request we receive at TurboPower Software is how properly to determine the presence and availability of Serial Ports and Modems at run-time. When a TApdComPort component attempts to open a port that is not available (either it doesn’t exist, is disabled, or perhaps has an input only device attached, such as a mouse), it throws a custom APRO exception “EBadID”; this is easy enough to trap for to detect that a good port was found. If a good port is found it is then possible to send the common modem attention command “AT” over the port, and if the common modem response “OK” is received back then there is clearly a modem attached and active. Here’s a simple project showing how one might set all this up: Delphi: unit detportu1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OoMisc, AdPort, AdModem, AdExcept, TypInfo;
const MIN_PORT_NUM = 1; MAX_PORT_NUM = 8;
type TForm1 = class(TForm) ApdComPort1: TApdComPort; Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1; OKTrig: Word; ModemFound: Boolean;
implementation
{$R *.DFM}
function CheckForPort(Port: TApdCustomComPort; PortNo: Integer): boolean; begin Result := True; try Port.Open := False; DelayTicks(9,True); Port.ComNumber := PortNo; Port.Open := True; DelayTicks(9,True); except on E: EBadId do Result := False; end; end;
procedure ModemTriggerHandler(Msg, wParam : Cardinal; lParam : Longint); begin if (Msg = APW_TRIGGERDATA) and (wParam = OKTrig) then begin ModemFound := True; OKTrig := 0; end; end;
function CheckForModem(Port: TApdCustomComPort; PortNo: Integer): boolean; begin ModemFound := False; try Port.Open := False; DelayTicks(9,True); Port.ComNumber := PortNo; Port.Open := True; DelayTicks(9,True); Port.Dispatcher.RegisterProcTriggerHandler(ModemTriggerHandler); OKTrig := Port.AddDataTrigger('OK', True); Port.Output := 'AT'#13#10; DelayTicks(36,True); finally Result := ModemFound; if OKTrig = 0 then Port.RemoveTrigger(OKTrig); Port.Dispatcher.DeregisterProcTriggerHandler(ModemTriggerHandler); end; end;
procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin i := MIN_PORT_NUM; while i <= MAX_PORT_NUM do begin if CheckForPort(ApdComPort1, i) then begin Memo1.Lines.Add('Opening COM' + IntToStr(i) + ':' + ' Successful!');
if CheckForModem(ApdComPort1, i) then Memo1.Lines.Add('Modem Found on COM' + IntToStr(i) + ':' ); end else Memo1.Lines.Add('Opening COM' + IntToStr(i) + ':' + ' Port Unavailable.');
Inc(i); end; Memo1.Lines.Add('** Done Scanning **'); end;
end.
C++Builder:
Header:
//--------------------------------------------------------------------------- #include <vcl\Classes.hpp> #include <vcl\Controls.hpp> #include <vcl\StdCtrls.hpp> #include <vcl\Forms.hpp> #include "AdPort.hpp" #include "OoMisc.hpp" //--------------------------------------------------------------------------- #define MIN_PORT_NUM 1 #define MAX_PORT_NUM 8 //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; TMemo *Memo1; TApdComPort *ApdComPort1; void __fastcall Button1Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner);
Boolean __fastcall CheckForPort(TApdCustomComPort* Port, int PortNo); Boolean __fastcall CheckForModem(TApdCustomComPort* Port, int PortNo);
}; //--------------------------------------------------------------------------- extern TForm1 *Form1;
Word OKTrig; Boolean ModemFound;
//--------------------------------------------------------------------------- #endif
Unit:
//--------------------------------------------------------------------------- #include <vcl\vcl.h> #pragma hdrstop
#include "detprtub1.h" //--------------------------------------------------------------------------- #pragma link "AdPort" #pragma link "OoMisc" #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //---------------------------------------------------------------------------
Boolean __fastcall TForm1::CheckForPort(TApdCustomComPort* Port, int PortNo) { try { Port->Open = FALSE; DelayTicks(9,True); Port->ComNumber = (Word)PortNo; Port->Open = True; DelayTicks(9,True); } catch (EBadId*) { return False; } return True; } //--------------------------------------------------------------------------- void __fastcall ModemTriggerHandler(Cardinal Msg, Cardinal wParam, int lParam) { if ((Msg == apw_TriggerData) && ((Word)wParam == OKTrig)) { ModemFound = True; OKTrig = 0; } } //--------------------------------------------------------------------------- Boolean __fastcall TForm1::CheckForModem(TApdCustomComPort* Port, int PortNo) { ModemFound = False; try { Port->Open = False; DelayTicks(9,True); Port->ComNumber = (Word)PortNo; Port->Open = True; DelayTicks(9,True); Port->Dispatcher->RegisterProcTriggerHandler(*ModemTriggerHandler); OKTrig = Port->AddDataTrigger("OK", True); Port->Output = "AT\x0D"; DelayTicks(45,True); } catch (...) { // finally
if OKTrig = 0 { Port->RemoveTrigger(OKTrig); } Port->Dispatcher->RegisterProcTriggerHandler(ModemTriggerHandler); return ModemFound; } if OKTrig = 0 { Port->RemoveTrigger(OKTrig); } Port->Dispatcher->RegisterProcTriggerHandler(ModemTriggerHandler); return ModemFound; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { for (int i = MIN_PORT_NUM; i < MAX_PORT_NUM; i++) { if (CheckForPort(ApdComPort1, i)) { Memo1->Lines->Add("Opening COM" + IntToStr(i) + ":" + " Successful!");
if (CheckForModem(ApdComPort1, i)) Memo1->Lines->Add("Modem Found on COM" + IntToStr(i) + ":" ); } else Memo1->Lines->Add("Opening COM" + IntToStr(i) + ":" + " Unavailable."); } Memo1->Lines->Add("** Done Scanning **"); }
So, what’s going on here? Basically all the project does is iterate through a set of Com Port numbers (set by the MIN_PORT_NUM and MAX_PORT_NUM constants), and display the results from the CheckForPort and CheckForModem routines. Really all the CheckForPort routine does is attempt to open the specified port and returns whether or not it could, trapping for exceptions as described above in the introduction. CheckForModem is a bit more complex; it makes use of the Trigger registration facilities of TApdComPort so that it gets itself notified when the modem responds with the traditional “OK” prompt, and simply opens the requested port, attempts sending “AT” plus a Carriage Return/Line Feed combination, and waits a bit for the Modem to respond. |
This site is not affiliated, endorsed, or otherwise associated with the
entity formerly known as
TurboPower Software. The owners and maintainers of Aprozilla.com were merely
meager employees of the aforementioned organization, providing this site out of
the pure goodness of their collective hearts.
|