// =======================================
// USB Device I/O Demo Project for nrComm Lib
// Copyright(C) 2011 Roman Novgorodov,
// http://www.DeepSoftware.com
//---------------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, nrcommbox, nrclasses, nrusb, ComCtrls, nrusbpipe,
  XPMan, nrusbdriver, nrlogfile;

type
  TForm1 = class(TForm)
    nrUSB1: TnrUSB;
    nrDeviceBox1: TnrDeviceBox;
    Label1: TLabel;
    nrUSBPipePair1: TnrUSBPipePair;
    Label2: TLabel;
    ePipeIn: TComboBox;
    ePipeOut: TComboBox;
    Label3: TLabel;                                                  
    Label4: TLabel;
    CheckBox1: TCheckBox;
    Label5: TLabel;
    Memo1: TMemo;
    Memo2: TMemo;
    XPManifest1: TXPManifest;
    bInstall: TButton;
    nrUsbDriver1: TnrUsbDriver;
    nrLogFile1: TnrLogFile;
    procedure nrDeviceBox1Change(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure nrUSBPipePair1AfterReceive(Com: TObject; Buffer: Pointer;
      Received: Cardinal);
    procedure ePipeInChange(Sender: TObject);
    procedure bInstallClick(Sender: TObject);
  private    { Private declarations }
    procedure UpdateControls;
  public   { Public declarations }
    procedure WMDeviceChange(var Msg:TMessage); message WM_DEVICECHANGE;
  end;

var
  Form1: TForm1;

implementation
uses nrusbman;

{$R *.dfm}

procedure TForm1.ePipeInChange(Sender: TObject);
begin
  UpdateControls;
end;

procedure TForm1.nrDeviceBox1Change(Sender: TObject);
var i:integer;
    Dev:TnrUsbDevice;
begin
  UpdateControls;
  Dev := nrUSB1.UsbDevice;
  if Dev = nil then exit;
  ePipeIn.Clear;
  ePipeOut.Clear;

  // fill Pipe combobox controls ....
  for i := 0 to Dev.PipeCount - 1 do begin
    if Dev.Pipes[i].DirectionOut
      then ePipeOut.Items.AddObject(Dev.Pipes[i].Description, Dev.Pipes[i]);
    if Dev.Pipes[i].DirectionIn
      then ePipeIn.Items.AddObject(Dev.Pipes[i].Description, Dev.Pipes[i]);
  end;

end;

procedure TForm1.WMDeviceChange(var Msg: TMessage);
var i:integer;
begin
  Screen.Cursor := crHourGlass;
  i := nrUsb1.DeviceIndex;
  nrUsb1.WMDeviceChange(Msg);
  nrUsb1.DeviceIndex := i;
  nrDeviceBox1Change(Self);
  Screen.Cursor := crDefault;
  UpdateControls;
end;

procedure TForm1.bInstallClick(Sender: TObject);
begin
  nrUsbDriver1.DriverDate := Now;
  nrUsbDriver1.DriverCaption := 'UsbIODemo Test driver for ' + nrUsb1.UsbDevice.NameFriendly;
  nrUsbDriver1.Install;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  try
    if CheckBox1.Checked then begin
      nrUSB1.Active := True;
      if nrUSB1.Active then begin
        if ePipeIn.ItemIndex >= 0 then begin
          nrUSBPipePair1.PipeIn := TnrUsbPipe(ePipeIn.Items.Objects[ePipeIn.ItemIndex]).Index;
          if TnrUsbPipe(ePipeIn.Items.Objects[ePipeIn.ItemIndex]).MaxPacketSize > 0
            then nrUSBPipePair1.ReadBufferSize := TnrUsbPipe(ePipeIn.Items.Objects[ePipeIn.ItemIndex]).MaxPacketSize;
        end;

        if ePipeOut.ItemIndex >= 0 then
          nrUSBPipePair1.PipeOut := TnrUsbPipe(ePipeOut.Items.Objects[ePipeOut.ItemIndex]).Index;
      end;
      nrUSBPipePair1.Active := True;
    end else begin
      nrUSBPipePair1.Active := False;
      nrUSB1.Active := False;
    end;
    UpdateControls;
  except
    nrUSB1.Active := False;
    nrUSBPipePair1.Active := False;
    CheckBox1.Checked := nrUSB1.Active and nrUSBPipePair1.Active;
    raise;
  end;

end;

procedure TForm1.nrUSBPipePair1AfterReceive(Com: TObject; Buffer: Pointer;
  Received: Cardinal);
var s:string;
    i : integer;
begin
  //OutputDebugString(PChar('Rec:' + IntToStr(Received) + ' bytes'));
  s := '';
  for i := 0 to Received - 1 do
    s := s + IntToHex(Byte(PCHar(Buffer)[i]),2) + ' ';
  Memo2.Lines.Add(s);
end;

procedure TForm1.UpdateControls;
begin
  CheckBox1.Enabled := (ePipeIn.ItemIndex >= 0) or (ePipeOut.ItemIndex >= 0);
  ePipeIn.Enabled := (nrUSB1.DeviceIndex >= 0) and not nrUSBPipePair1.Active;
  ePipeOut.Enabled :=   ePipeIn.Enabled;
  bInstall.Enabled := ePipeIn.Enabled;// not nrUSBPipePair1.Active and ;
  nrDeviceBox1.Enabled := not nrUSBPipePair1.Active;
end;

end.
