begin process at 2010 02 10 01:24:53
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Périphériques

 > COMPOSANT TLPTPORT AVEC FONCTION OUT & INP + GESTION DE LA MÉMOIRE PHYSIQUE

COMPOSANT TLPTPORT AVEC FONCTION OUT & INP + GESTION DE LA MÉMOIRE PHYSIQUE


 Information sur la source

Note :
8,33 / 10 - par 3 personnes
8,33 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Périphériques Classé sous :lpt, io, port Niveau :Initié Date de création :25/04/2003 Date de mise à jour :11/03/2006 22:11:43 Vu / téléchargé :15 718 / 1 145

Auteur : shining

Ecrire un message privé
Site perso
Commentaire sur cette source (12)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
mise à jour importante désormais c'est un composant permettant le dialogue avec le port parallèle LPT, cette mise à jour inclus notamment la prise en charge des OS Windows 9x/NT/2000 and XP et ce grâce au driver WinIO de chez http://www.internals.com

on m'a demander récemment comment faire pour avoir l'adresse du Port LPT, effectivement ce n'est pas aussi simple car d'habitude il faut aller voir le BIOS...
maintenant c'est une histoire ancienne le composant va chercher les Ports en lisant la mémoire physique, en effet les valeurs des Ports sont stockés à l'adresse [$0040:$0008] seulement voilà là il sagit d'une adresse logique, j'ai donc dû rajouter une fonction qui calcule l'adresse Physique à partir de l'adresse Logique "MakeMemLoc", bon le nom n'est peut être pas assez explicite :)



maintenant on peut aussi énuméré les Ports LPT

Source

  • unit LPTPort;
  • interface
  • Uses
  • Windows , Classes, SysUtils, Dialogs;
  • (***********************************************************************************************)
  • (* Author : Shining-Freeman *)
  • (* Date : 25/04/2003 *)
  • (* Release : 10/03/2006 *)
  • (* Purpose : contrôler le port parallèle *)
  • (***********************************************************************************************)
  • {
  • Historiques :
  • 10/03/2006 : Ajout de
  • SelectPort(Addr : WORD); équivaut à LPTport := Addr
  • SelectPortByIndex(PortIndex : Integer); choisit le port en fonction du combobox
  • GetPhysDWORD(Addr : DWORD ; var Return : DWORD):Boolean; Lecture de la Mémoire Physique en DWORD=LongWord
  • SetPhysDWORD(Addr : DWORD ; Value : DWORD):Boolean; écriture de la Mémoire Physique
  • EnumPorts(Strings : TStrings);overload; énumération des Ports disponibles dans un Combobox;
  • EnumPorts;overload; // énumération des Ports dans la List(TCollection)
  • MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD; transforme une adresse logique en adresse physique [xx:xx]
  • }
  • Const
  • Version = 'Bêta 1.3';
  • Type
  • TPinKind =
  • (
  • pkD0,
  • pkD1,
  • pkD2,
  • pkD3,
  • pkD4,
  • pkD5,
  • pkD6,
  • pkD7
  • );
  • TPinKinds = Set of TPinKind;
  • TPinInfo = record
  • Name : String;
  • Kind : TPinKind;
  • Offset : Byte;
  • end;
  • Const
  • { Table d'adressage des PIN's D0..D7
  • Nota : sur le port parallele D0 est situé sur le pin 1
  • }
  • TPinLookUp : array[0..7] of TPinInfo=(
  • (Name : 'D0' ; Kind : pkD0 ; Offset : $1),
  • (Name : 'D1' ; Kind : pkD1 ; Offset : $2),
  • (Name : 'D2' ; Kind : pkD2 ; Offset : $4),
  • (Name : 'D3' ; Kind : pkD3 ; Offset : $8),
  • (Name : 'D4' ; Kind : pkD4 ; Offset : $10),
  • (Name : 'D5' ; Kind : pkD5 ; Offset : $20),
  • (Name : 'D6' ; Kind : pkD6 ; Offset : $40),
  • (Name : 'D7' ; Kind : pkD7 ; Offset : $80)
  • );
  • Type
  • TOnPinChange = procedure (Sender : TObject ; Info : TPinInfo ; State : Boolean) of Object;
  • TLPTList = class;
  • TLPTListItems = class;
  • TLPTList = class(TCollection)
  • private
  • { Déclarations privées }
  • FItemIndex : Integer;
  • function GetItem (Index : Integer): TLPTListItems;
  • procedure SetItem (Index : Integer ; Value : TLPTListItems);
  • public
  • { Déclarations publiques }
  • ItemFind : TLPTListItems;
  • Constructor Create;
  • Destructor Destroy;override;
  • function Add: TLPTListItems;
  • function ItemExist (ItemName : String): Boolean;
  • function ItemOf (ItemName : String): TLPTListItems;
  • property Items[Index : Integer] : TLPTListItems read GetItem write SetItem; default;
  • property ItemIndex : integer read FItemIndex write FItemIndex;
  • published
  • end;
  • TLPTListItems = class(TCollectionItem)
  • private
  • { Déclarations privées }
  • FName : String;
  • FPort : WORD;
  • protected
  • { Déclarations protégées }
  • Parent : TLPTList;
  • public
  • { Déclarations publiques }
  • Constructor Create (Collection : TCollection);override;
  • Destructor Destroy;override;
  • procedure Assign (Source : TPersistent);override;
  • published
  • property Name : String read FName write FName;
  • property Port : WORD read FPort write FPort;
  • end;
  • TLPTPort = class(TComponent)
  • private
  • FInitialized : Boolean;
  • FDLLHandle : THandle;
  • FPort : Word;
  • { calcule des sommes pour les pins D0..D7}
  • FPinHash : Integer;
  • FLS : array[0..7] of Boolean;//Led State
  • FOnPinChange : TOnPinChange;
  • FInpOffset : Integer;
  • FUpdate : Boolean;
  • FPorts : TLPTList;
  • procedure NotifyPinChange(Name : String ; State : Boolean);
  • procedure LoadSysDrivers;
  • procedure FreeSysDrivers;
  • function GetBytePort (Addr : Word): Byte;
  • function GetDWordPort (Addr : Word): DWord;
  • function GetWordPort (Addr : Word): Word;
  • procedure SetBytePort (Addr : Word; const Value: Byte);
  • procedure SetDWordPort (Addr : Word; const Value: DWord);
  • procedure SetWordPort (Addr : Word; const Value: Word);
  • procedure SetD0(const Value: Boolean);
  • procedure SetD1(const Value: Boolean);
  • procedure SetD2(const Value: Boolean);
  • procedure SetD3(const Value: Boolean);
  • procedure SetD4(const Value: Boolean);
  • procedure SetD5(const Value: Boolean);
  • procedure SetD6(const Value: Boolean);
  • procedure SetD7(const Value: Boolean);
  • function GetD0: Boolean;
  • function GetD1: Boolean;
  • function GetD2: Boolean;
  • function GetD3: Boolean;
  • function GetD4: Boolean;
  • function GetD5: Boolean;
  • function GetD6: Boolean;
  • function GetD7: Boolean;
  • procedure SetPorts(const Value : TLPTList);
  • protected
  • procedure InitializeDrivers;
  • procedure FinalizeDrivers;
  • public
  • Constructor Create(AOwner : TComponent);override;
  • Destructor Destroy;override;
  • procedure BeginUpdate;
  • procedure EndUpdate;
  • function Open:Boolean;
  • function Close:Boolean;
  • procedure ClearPins;
  • procedure SetPin (Name : String; State : Boolean = true);
  • procedure SetPins (Names : array of String);
  • procedure SelectPort(Addr : WORD);
  • procedure SelectPortByIndex(PortIndex : Integer);
  • function GetPhysDWORD(Addr : DWORD ; var Return : DWORD):Boolean;
  • function SetPhysDWORD(Addr : DWORD ; Value : DWORD):Boolean;
  • procedure EnumPorts(Strings : TStrings);overload;
  • procedure EnumPorts;overload;
  • { fonction de sortie
  • Out utiliser LPTPort pour l'accès
  • OutP permet de spécifié un port
  • }
  • function Out (Value : Byte):Boolean;overload;
  • function Out (Value : Word):Boolean;overload;
  • function Out (Value : DWord):Boolean;overload;
  • function Inp : Byte;
  • function InpW : Word;
  • function InpDW : DWord;
  • function OutP (Addr : Word; Value : Byte):Boolean;overload;
  • function OutP (Addr : Word; Value : Word):Boolean;overload;
  • function OutP (Addr : Word; Value : DWord):Boolean;overload;
  • function InpP (Addr : Word) : Byte;
  • function InpWP (Addr : Word) : Word;
  • function InpDWP(Addr : Word) : DWord;
  • property Port [Addr : Word] : Byte read GetBytePort write SetBytePort;
  • property PortW [Addr : Word] : Word read GetWordPort write SetWordPort;
  • property PortDW [Addr : Word] : DWord read GetDWordPort write SetDWordPort;
  • property D0 : Boolean read GetD0 write SetD0;
  • property D1 : Boolean read GetD1 write SetD1;
  • property D2 : Boolean read GetD2 write SetD2;
  • property D3 : Boolean read GetD3 write SetD3;
  • property D4 : Boolean read GetD4 write SetD4;
  • property D5 : Boolean read GetD5 write SetD5;
  • property D6 : Boolean read GetD6 write SetD6;
  • property D7 : Boolean read GetD7 write SetD7;
  • property Initialized : Boolean read FInitialized;
  • property Ports : TLPTList read FPorts write SetPorts;
  • published
  • property LPTPort : Word read FPort write FPort;
  • {
  • Inp normalement Inp = Base + 1 pour lire l'état
  • donc inp vaut 1 par défaut, lors de l'appel à la fonction Inp, celle-ci renvoie inp(Port + LptInp);
  • }
  • property InpOffset : Integer read FInpOffset write FInpOffset default 1;
  • property OnPinChange : TOnPinChange read FOnPinChange write FOnPinChange;
  • end;
  • {$R LPTPort.dcr}
  • function PinNameToPinInfo(Name : String; var Info : TPinInfo):Boolean;
  • function PinValToPinKinds(Value : Byte):TPinKinds;
  • function GetDir:String;// revient au même que ExtractFilePath mais sans utiliser Application.ExeName(dans Forms)
  • function DecToBin(Value : Integer ; nBits : Integer = 8): String;
  • function HexToBin(Value : String ; nBits : Integer = 8):String;
  • function IsNumeric(Value : String):Boolean;
  • {
  • Make Memory Location
  • permet d'avoir l'équivalent de la fonction TurboPascal MemW[xx:xx]
  • Seulement cette fonction ne fait que calculer l'adresse physique à partir de l'adresse logique, et ne fournis aucun accès à celle-ci
  • Exemple
  • l'adresse logique [0040:0008] contient l'adresse du port de LPT1
  • et donc son adresse physique est $408;
  • autre exemple
  • [$2135:$4A] correspond à l'adresse Physique $2139A
  • }
  • function MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD;
  • procedure Register;
  • implementation
  • procedure Register;
  • begin
  • RegisterComponents('SFC I/O' , [TLPTPort]);
  • end;
  • Type
  • TDriverInfo = record
  • Name : String;
  • ResName : String;
  • end;
  • Const
  • TDrivers : array [0..2] of TDriverInfo = (
  • (Name : 'WinIO.dll' ; ResName : 'WIDL'), // noyau Sys <> OS
  • (Name : 'WinIO.sys' ; ResName : 'WISY'), // pour Win2000,XP,NT
  • (Name : 'WinIO.vxd' ; ResName : 'WIVX') // pour Win95,98
  • );
  • {
  • Déclaration de la DLL WinIO.dll
  • }
  • var
  • InitializeWinIo : function : Boolean;stdcall;
  • ShutdownWinIo : function : Boolean;stdcall;
  • MapPhysToLin : function (var pbPhysAddr: Byte; dwPhysSize : Integer; var pPhysicalMemoryHandle : THandle):PByte;
  • UnmapPhysicalMemory : function (PhysicalMemoryHandle : THandle; var pbLinAddr: Byte): Boolean;
  • GetPhysLong : function (pbPhysAddr : DWORD; var pdwPhysVal : DWORD): Boolean;stdcall;
  • SetPhysLong : function (pbPhysAddr : DWORD; dwPhysVal : DWORD): Boolean;stdcall;
  • GetPortVal : function (wPortAddr : Word; var pdwPortVal : Integer; bSize: Byte): Boolean;stdcall;
  • SetPortVal : function (wPortAddr : Word; dwPortVal: Integer; bSize: Byte): Boolean;stdcall;
  • InstallWinIoDriver : function (pszWinIoDriverPath: PChar; IsDemandLoaded : Boolean = False): Boolean;stdcall;
  • RemoveWinIoDriver : function : Boolean;stdcall;
  • StartWinIoDriver : function : Boolean;stdcall;
  • StopWinIoDriver : function : Boolean;stdcall;
  • function PinNameToPinInfo(Name : String; var Info : TPinInfo):Boolean;
  • var
  • I : Integer;
  • begin
  • result := False;
  • for i := Low(TPinLookUp) To High(TPinLookUp) do
  • begin
  • if SameText(Name , TPinLookUp[i].Name) then
  • begin
  • Info := TPinLookUp[i];
  • result := True;
  • Break;
  • end;
  • end;
  • end;
  • function PinValToPinKinds(Value : Byte):TPinKinds;
  • var
  • i : Integer;
  • Pin : TPinInfo;
  • begin
  • result := [];
  • for i := Low(TPinLookUp) to High(TPinLookUp) do
  • begin
  • Pin := TPinLookup[i];
  • if (Value and Pin.Offset) = Pin.Offset then
  • result := result + [Pin.Kind];
  • end;
  • end;
  • function GetDir:String;
  • begin
  • result := GetCurrentDir + '\';
  • end;
  • function DecToBin(Value : Integer ; nBits : Integer = 8): String;
  • var
  • i : Integer;
  • C : Char;
  • begin
  • Result := '';
  • for i := nBits-1 downto 0 do
  • begin
  • C := '0';
  • if (Value and (1 shl i)<>0) then C := '1';
  • result := result + C;
  • end;
  • end;
  • function HexToBin(Value : String ; nBits : Integer = 8):String;
  • begin
  • result := DecToBin(StrToInt('$' + Value), nBits);
  • end;
  • function IsNumeric(Value : String):Boolean;
  • var
  • P : PChar;
  • begin
  • result := False;
  • P := PChar(Value);
  • while (P^<>#0) do
  • begin
  • if P^ in ['0'..'9', 'A'..'F', 'a'..'f'] then
  • result := true else
  • begin
  • result := false;
  • break;
  • end;
  • inc(P);
  • end;
  • end;
  • function MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD;
  • begin
  • Offset := (Offset shl 4) and $FFFFFFFF;
  • Segment := Segment and $FFFFFFFF;
  • result := Offset + Segment;
  • end;
  • { TLPTPort }
  • function TLPTPort.Close: Boolean;
  • begin
  • result := ShutDownWinIO;
  • end;
  • constructor TLPTPort.Create(AOwner: TComponent);
  • begin
  • inherited Create(AOwner);
  • FInitialized := False;
  • FDLLHandle := 0;
  • FPort := $378; // Base
  • FInpOffset := 1; // Base + 1 = Status register
  • FUpdate := False;
  • FPorts := TLPTList.Create;
  • LoadSysDrivers;
  • InitializeDrivers;
  • end;
  • destructor TLPTPort.Destroy;
  • begin
  • FinalizeDrivers;
  • FreeSysDrivers;
  • FPorts.Free;
  • inherited Destroy;
  • end;
  • function TLPTPort.GetBytePort(Addr: Word): Byte;
  • begin
  • result := InpP(Addr);
  • end;
  • function TLPTPort.GetDWordPort(Addr: Word): DWord;
  • begin
  • result := InpDWP(Addr);
  • end;
  • function TLPTPort.GetWordPort(Addr: Word): Word;
  • begin
  • result := InpWP(Addr);
  • end;
  • function TLPTPort.Inp : Byte;
  • var
  • Ret : Integer;
  • begin
  • result := 0;
  • if GetPortVal(FPort + FInpOffset , Ret , 1) then
  • result := (Ret and $FF);
  • end;
  • function TLPTPort.InpW : Word;
  • var
  • Ret : Integer;
  • begin
  • result := 0;
  • if GetPortVal(FPort + FInpOffset , Ret , 2) then
  • result := (Ret and $FFFF);
  • end;
  • procedure TLPTPort.InitializeDrivers;
  • begin
  • FDLLHandle := LoadLibrary(PChar(TDrivers[0].Name));
  • @InitializeWinIo := GetProcAddress(FDLLHandle,'InitializeWinIo');
  • @ShutdownWinIo := GetProcAddress(FDLLHandle,'ShutdownWinIo');
  • @MapPhysToLin := GetProcAddress(FDLLHandle,'MapPhysToLin');
  • @UnmapPhysicalMemory := GetProcAddress(FDLLHandle,'UnmapPhysicalMemory');
  • @GetPhysLong := GetProcAddress(FDLLHandle,'GetPhysLong');
  • @SetPhysLong := GetProcAddress(FDLLHandle,'SetPhysLong');
  • @GetPortVal := GetProcAddress(FDLLHandle,'GetPortVal');
  • @SetPortVal := GetProcAddress(FDLLHandle,'SetPortVal');
  • @InstallWinIoDriver := GetProcAddress(FDLLHandle,'InstallWinIoDriver');
  • @RemoveWinIoDriver := GetProcAddress(FDLLHandle,'RemoveWinIoDriver');
  • @StartWinIoDriver := GetProcAddress(FDLLHandle,'StartWinIoDriver');
  • @StopWinIoDriver := GetProcAddress(FDLLHandle,'StopWinIoDriver');
  • end;
  • function TLPTPort.InpDW: DWord;
  • var
  • Ret : Integer;
  • begin
  • result := 0;
  • if GetPortVal(FPort + FInpOffset , Ret , 4) then
  • result := (Ret and $FFFFFFFF);
  • end;
  • function TLPTPort.Open: Boolean;
  • begin
  • FInitialized := InitializeWinIo;
  • result := FInitialized;
  • end;
  • function TLPTPort.Out(Value: Byte): Boolean;
  • begin
  • result := SetPortVal(FPort , Value, 1);
  • end;
  • function TLPTPort.Out(Value: Word): Boolean;
  • begin
  • result := SetPortVal(FPort , Value, 2);
  • end;
  • function TLPTPort.Out(Value: DWord): Boolean;
  • begin
  • result := SetPortVal(FPort , Value, 4);
  • end;
  • procedure TLPTPort.SetBytePort(Addr: Word; const Value: Byte);
  • begin
  • OutP(Addr, Value);
  • end;
  • procedure TLPTPort.SetDWordPort(Addr: Word; const Value: DWord);
  • begin
  • OutP(Addr, Value);
  • end;
  • procedure TLPTPort.SetWordPort(Addr: Word; const Value: Word);
  • begin
  • OutP(Addr, Value);
  • end;
  • procedure TLPTPort.FreeSysDrivers;
  • var
  • i : integer;
  • begin
  • for i := Low(TDrivers) to High(TDrivers) do
  • DeleteFile(GetDir + TDrivers[i].Name);
  • end;
  • procedure TLPTPort.LoadSysDrivers;
  • var
  • I : Integer;
  • Res : TResourceStream;
  • FileName : String;
  • begin
  • { Extraction du Driver depuis le ressource LPTPort.dcr }
  • res := nil;
  • for i := Low(TDrivers) to High(TDrivers) do
  • begin
  • FileName := GetDir + TDrivers[i].Name;
  • if FileExists(FileName)=False then
  • begin
  • try
  • Res := TResourceStream.Create(hInstance , TDrivers[i].ResName , 'WINIO');
  • Res.SaveToFile (FileName);
  • { fichier caché }
  • SetFileAttributes(PChar(FileName), FILE_ATTRIBUTE_SYSTEM + FILE_ATTRIBUTE_HIDDEN);
  • finally
  • Res.Free;
  • end;
  • end;//File doesn't exists
  • end;//i++
  • end;
  • procedure TLPTPort.FinalizeDrivers;
  • begin
  • FreeLibrary(FDLLHandle);
  • end;
  • procedure TLPTPort.SetPin(Name: String; State: Boolean = true);
  • var
  • Info : TPinInfo;
  • begin
  • if PinNameToPinInfo(Name, Info) then
  • begin
  • Case Info.Kind of
  • pkD0 : D0 := State;
  • pkD1 : D1 := State;
  • pkD2 : D2 := State;
  • pkD3 : D3 := State;
  • pkD4 : D4 := State;
  • pkD5 : D5 := State;
  • pkD6 : D6 := State;
  • pkD7 : D7 := State;
  • end;
  • end;
  • end;
  • procedure TLPTPort.SetD0(const Value: Boolean);
  • begin
  • if FLS[0] <> Value then
  • begin
  • FLS[0] := Value;
  • NotifyPinChange('D0' , Value);
  • end;
  • end;
  • procedure TLPTPort.NotifyPinChange(Name: String; State: Boolean);
  • var
  • Info : TPinInfo;
  • begin
  • if PinNameToPinInfo(Name , Info) then
  • begin
  • if Assigned(FOnPinChange) then FOnPinChange(Self , Info , State);
  • case State of
  • True :
  • begin
  • Inc(FPinHash , Info.Offset);
  • end;
  • False :
  • begin
  • Dec(FPinHash , Info.Offset);
  • end;
  • end;
  • if FUpdate = False then
  • Out(FPinHash);
  • end;//Pin Found
  • end;
  • procedure TLPTPort.SetD1(const Value: Boolean);
  • begin
  • if FLS[1] <> Value then
  • begin
  • FLS[1] := Value;
  • NotifyPinChange('D1' , Value);
  • end;
  • end;
  • procedure TLPTPort.SetD2(const Value: Boolean);
  • begin
  • if FLS[2] <> Value then
  • begin
  • FLS[2] := Value;
  • NotifyPinChange('D2' , Value);
  • end;
  • end;
  • procedure TLPTPort.SetD3(const Value: Boolean);
  • begin
  • if FLs[3] <> Value then
  • begin
  • FLS[3] := Value;
  • NotifyPinChange('D3' , Value);
  • end;
  • end;
  • procedure TLPTPort.SetD4(const Value: Boolean);
  • begin
  • if FLS[4] <> Value then
  • begin
  • FLS[4] := Value;
  • NotifyPinChange('D4' , Value);
  • end;
  • end;
  • procedure TLPTPort.SetD5(const Value: Boolean);
  • begin
  • if FLS[5] <> Value then
  • begin
  • FLS[5] := Value;
  • NotifyPinChange('D5' , Value);
  • end;
  • end;
  • procedure TLPTPort.SetD6(const Value: Boolean);
  • begin
  • if FLS[6] <> Value then
  • begin
  • FLS[6] := Value;
  • NotifyPinChange('D6' , Value);
  • end;
  • end;
  • procedure TLPTPort.SetD7(const Value: Boolean);
  • begin
  • if FLS[7] <> Value then
  • begin
  • FLS[7] := Value;
  • NotifyPinChange('D7' , Value);
  • end;
  • end;
  • function TLPTPort.GetD0: Boolean;
  • begin
  • result := (Inp and $1) = $1;
  • end;
  • function TLPTPort.GetD1: Boolean;
  • begin
  • result := (Inp and $2) = $2;
  • end;
  • function TLPTPort.GetD2: Boolean;
  • begin
  • result := (Inp and $4) = $4;
  • end;
  • function TLPTPort.GetD3: Boolean;
  • begin
  • result := (Inp and $8) = $8;
  • end;
  • function TLPTPort.GetD4: Boolean;
  • begin
  • result := (Inp and $10) = $10;
  • end;
  • function TLPTPort.GetD5: Boolean;
  • begin
  • result := (Inp and $20) = $20;
  • end;
  • function TLPTPort.GetD6: Boolean;
  • begin
  • result := (Inp and $40) = $40;
  • end;
  • function TLPTPort.GetD7: Boolean;
  • begin
  • result := (Inp and $80) = $80;
  • end;
  • function TLPTPort.OutP(Addr: Word; Value: Byte): Boolean;
  • begin
  • result := SetPortVal(Addr , Value, 1);
  • end;
  • function TLPTPort.OutP(Addr, Value: Word): Boolean;
  • begin
  • result := SetPortVal(Addr , Value, 2);
  • end;
  • function TLPTPort.OutP(Addr: Word; Value: DWord): Boolean;
  • begin
  • result := SetPortVal(Addr , Value, 4);
  • end;
  • function TLPTPort.InpDWP(Addr: Word): DWord;
  • var
  • Ret : Integer;
  • begin
  • result := 0;
  • if GetPortVal(Addr + FInpOffset , Ret , 4) then
  • result := (Ret and $FFFFFFFF);
  • end;
  • function TLPTPort.InpP(Addr: Word): Byte;
  • var
  • Ret : Integer;
  • begin
  • result := 0;
  • if GetPortVal(Addr + FInpOffset , Ret , 1) then
  • result := (Ret and $FF);
  • end;
  • function TLPTPort.InpWP(Addr : Word): Word;
  • var
  • Ret : Integer;
  • begin
  • result := 0;
  • if GetPortVal(Addr + FInpOffset , Ret , 2) then
  • result := (Ret and $FFFF);
  • end;
  • procedure TLPTPort.BeginUpdate;
  • begin
  • FUpdate := True;
  • end;
  • procedure TLPTPort.EndUpdate;
  • begin
  • if FUpdate then
  • begin
  • FUpdate := False;
  • Out(FPinHash);
  • end;
  • end;
  • procedure TLPTPort.SetPins(Names: array of String);
  • var
  • i : Integer;
  • Info : TPinInfo;
  • State : Boolean;
  • begin
  • BeginUpdate;
  • ClearPins;
  • for i := Low(Names) to High(Names) do
  • begin
  • PinNameToPinInfo(Names[i] , Info);
  • State := True;
  • Case Info.Kind of
  • pkD0 : D0 := State;
  • pkD1 : D1 := State;
  • pkD2 : D2 := State;
  • pkD3 : D3 := State;
  • pkD4 : D4 := State;
  • pkD5 : D5 := State;
  • pkD6 : D6 := State;
  • pkD7 : D7 := State;
  • end;//Case
  • end;//i++
  • EndUpdate;
  • end;
  • procedure TLPTPort.ClearPins;
  • begin
  • D0 := False;
  • D1 := False;
  • D2 := False;
  • D3 := False;
  • D4 := False;
  • D5 := False;
  • D6 := False;
  • D7 := False;
  • end;
  • function TLPTPort.GetPhysDWORD(Addr : DWORD; var Return : DWORD): Boolean;
  • begin
  • Addr := Addr and $FFFFFFFF;
  • result := GetPhysLong( Addr , Return );
  • if result then Return := (Return and $FFFFFFFF);
  • end;
  • function TLPTPort.SetPhysDWORD(Addr, Value: DWORD): Boolean;
  • begin
  • Addr := (Addr and $FFFFFFFF);
  • Value := (Value and $FFFFFFFF);
  • result := SetPhysLong(Addr , Value);
  • end;
  • procedure TLPTPort.EnumPorts;
  • var
  • I : Integer;
  • SearchBase : DWORD;
  • PortFind : DWORD;
  • begin
  • SearchBase := $408; // [$40:$008]
  • Ports.Clear;
  • for i := 1 to 3 do // LPT1 ... LPT3
  • begin
  • if GetPhysDWORD(SearchBase , PortFind) then
  • begin
  • PortFind := (PortFind and $FFFF);
  • if (PortFind > 0) then
  • begin
  • with Ports.Add do
  • begin
  • Name := Format('LPT%u' , [i]);
  • Port := PortFind;
  • end;//with Ports.Add
  • end;
  • end;//if GetPhysique
  • inc(SearchBase , 2);
  • end;// i ++
  • end;
  • { implementation of TLPTList }
  • function TLPTList.GetItem (Index : Integer): TLPTListItems;
  • begin
  • result := TLPTListItems(inherited GetItem(Index));
  • end;
  • procedure TLPTList.SetItem (Index : Integer ; Value : TLPTListItems);
  • begin
  • inherited SetItem(Index, Value);
  • end;
  • Constructor TLPTList.Create;
  • begin
  • inherited Create(TLPTListItems);
  • end;
  • Destructor TLPTList.Destroy;
  • begin
  • inherited Destroy;
  • end;
  • function TLPTList.Add: TLPTListItems;
  • begin
  • result := TLPTListItems(inherited Add);
  • end;
  • function TLPTList.ItemExist (ItemName : String): Boolean;
  • var
  • I : Integer;
  • begin
  • result := False;
  • ItemIndex := -1;
  • for i :=0 to Count -1 do
  • begin
  • if SameText(ItemName, Items[i].Name) Then
  • begin
  • ItemIndex := I;
  • ItemFind := Items[i];
  • result := True;
  • Break;
  • end;//Trouver
  • end;//Fin de la boucle I
  • end;
  • function TLPTList.ItemOf (ItemName : String): TLPTListItems;
  • begin
  • result := nil;
  • if ItemExist(ItemName) Then
  • result := Items[ItemIndex];
  • end;
  • { implementation of TLPTListItems }
  • Constructor TLPTListItems.Create (Collection : TCollection);
  • begin
  • inherited Create(Collection);
  • Parent := TLPTList(Collection);
  • FPort := 0;
  • end;
  • Destructor TLPTListItems.Destroy;
  • begin
  • inherited Destroy;
  • end;
  • procedure TLPTListItems.Assign (Source : TPersistent);
  • begin
  • if Source is TLPTListItems Then
  • begin
  • FName := TLPTListItems(Source).FName;
  • FPort := TLPTListItems(Source).FPort;
  • end else
  • inherited;
  • end;
  • procedure TLPTPort.SetPorts(const Value: TLPTList);
  • begin
  • FPorts.Assign(Value);
  • end;
  • procedure TLPTPort.EnumPorts(Strings: TStrings);
  • var
  • i : Integer;
  • begin
  • Strings.Clear;
  • EnumPorts;
  • for i := 0 to Ports.Count -1 do
  • Strings.Add(Ports[i].Name);
  • end;
  • procedure TLPTPort.SelectPort(Addr: WORD);
  • begin
  • LPTPort := Addr;
  • end;
  • procedure TLPTPort.SelectPortByIndex(PortIndex: Integer);
  • begin
  • LPTPort := Ports[PortIndex].Port;
  • end;
  • end.
unit LPTPort;

interface
Uses
Windows , Classes, SysUtils, Dialogs;

(***********************************************************************************************)
(*  Author  : Shining-Freeman                                                                  *)
(*  Date    : 25/04/2003                                                                       *)
(*  Release : 10/03/2006                                                                       *)
(*  Purpose : contrôler le port parallèle                                                      *)
(***********************************************************************************************)

{
 Historiques :


 10/03/2006 : Ajout de
            SelectPort(Addr   : WORD); équivaut à LPTport := Addr
            SelectPortByIndex(PortIndex : Integer); choisit le port en fonction du combobox
            GetPhysDWORD(Addr : DWORD ; var Return : DWORD):Boolean; Lecture de la Mémoire Physique en DWORD=LongWord
            SetPhysDWORD(Addr : DWORD ; Value : DWORD):Boolean; écriture de la Mémoire Physique
            EnumPorts(Strings : TStrings);overload; énumération des Ports disponibles dans un Combobox;
            EnumPorts;overload; // énumération des Ports dans la List(TCollection)
            MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD; transforme une adresse logique en adresse physique [xx:xx]
}


  Const
  Version = 'Bêta 1.3';

  Type

  TPinKind =
  (
  pkD0,
  pkD1,
  pkD2,
  pkD3,
  pkD4,
  pkD5,
  pkD6,
  pkD7
  );
  TPinKinds = Set of TPinKind;

  TPinInfo = record
  Name   : String;
  Kind   : TPinKind;
  Offset : Byte;
  end;

  Const
  { Table d'adressage des PIN's D0..D7
   Nota : sur le port parallele D0 est situé sur le pin 1
  }
  TPinLookUp : array[0..7] of TPinInfo=(
  (Name : 'D0' ; Kind : pkD0 ; Offset : $1),
  (Name : 'D1' ; Kind : pkD1 ; Offset : $2),
  (Name : 'D2' ; Kind : pkD2 ; Offset : $4),
  (Name : 'D3' ; Kind : pkD3 ; Offset : $8),
  (Name : 'D4' ; Kind : pkD4 ; Offset : $10),
  (Name : 'D5' ; Kind : pkD5 ; Offset : $20),
  (Name : 'D6' ; Kind : pkD6 ; Offset : $40),
  (Name : 'D7' ; Kind : pkD7 ; Offset : $80)
  );

  Type

  TOnPinChange = procedure (Sender : TObject ; Info : TPinInfo ; State : Boolean) of Object;


  TLPTList      = class;
  TLPTListItems = class;

  TLPTList = class(TCollection)
  private
    { Déclarations privées }
    FItemIndex : Integer;
    function GetItem (Index : Integer): TLPTListItems;
    procedure SetItem (Index : Integer ; Value : TLPTListItems);
  public
    { Déclarations publiques }
    ItemFind : TLPTListItems;
    Constructor Create;
    Destructor Destroy;override;
    function Add: TLPTListItems;
    function ItemExist (ItemName : String): Boolean;
    function ItemOf (ItemName : String): TLPTListItems;
    property Items[Index : Integer] : TLPTListItems read GetItem write SetItem; default;
    property ItemIndex : integer read FItemIndex write FItemIndex;
  published
  end;

  
  TLPTListItems = class(TCollectionItem)
  private
    { Déclarations privées }
    FName : String;
    FPort : WORD;
  protected
    { Déclarations protégées }
    Parent : TLPTList;
  public
    { Déclarations publiques }
    Constructor Create (Collection : TCollection);override;
    Destructor  Destroy;override;
    procedure   Assign (Source : TPersistent);override;
  published
    property    Name : String  read FName write FName;
    property    Port : WORD    read FPort write FPort;
  end;

  TLPTPort = class(TComponent)
  private
    FInitialized : Boolean;
    FDLLHandle   : THandle;
    FPort        : Word;
    { calcule des sommes pour les pins D0..D7}
    FPinHash     : Integer;
    FLS          : array[0..7] of Boolean;//Led State
    FOnPinChange : TOnPinChange;
    FInpOffset   : Integer;
    FUpdate      : Boolean;
    FPorts       : TLPTList;
    procedure   NotifyPinChange(Name : String ; State : Boolean);
    procedure   LoadSysDrivers;
    procedure   FreeSysDrivers;
    function    GetBytePort  (Addr : Word): Byte;
    function    GetDWordPort (Addr : Word): DWord;
    function    GetWordPort  (Addr : Word): Word;
    procedure   SetBytePort  (Addr : Word; const Value: Byte);
    procedure   SetDWordPort (Addr : Word; const Value: DWord);
    procedure   SetWordPort  (Addr : Word; const Value: Word);
    procedure   SetD0(const Value: Boolean);
    procedure   SetD1(const Value: Boolean);
    procedure   SetD2(const Value: Boolean);
    procedure   SetD3(const Value: Boolean);
    procedure   SetD4(const Value: Boolean);
    procedure   SetD5(const Value: Boolean);
    procedure   SetD6(const Value: Boolean);
    procedure   SetD7(const Value: Boolean);
    function    GetD0: Boolean;
    function    GetD1: Boolean;
    function    GetD2: Boolean;
    function    GetD3: Boolean;
    function    GetD4: Boolean;
    function    GetD5: Boolean;
    function    GetD6: Boolean;
    function    GetD7: Boolean;
    procedure   SetPorts(const Value : TLPTList);
  protected
    procedure   InitializeDrivers;
    procedure   FinalizeDrivers;
  public
    Constructor Create(AOwner : TComponent);override;
    Destructor  Destroy;override;
    procedure   BeginUpdate;
    procedure   EndUpdate;

    function    Open:Boolean;
    function    Close:Boolean;
    procedure   ClearPins;

    procedure   SetPin  (Name  : String; State : Boolean = true);
    procedure   SetPins (Names : array of String);

    procedure   SelectPort(Addr   : WORD);
    procedure   SelectPortByIndex(PortIndex : Integer);
    function    GetPhysDWORD(Addr : DWORD ; var Return : DWORD):Boolean;
    function    SetPhysDWORD(Addr : DWORD ; Value : DWORD):Boolean;

    procedure   EnumPorts(Strings : TStrings);overload;
    procedure   EnumPorts;overload;

    { fonction de sortie
      Out utiliser LPTPort pour l'accès
      OutP permet de spécifié un port
    }
    function    Out (Value : Byte):Boolean;overload;
    function    Out (Value : Word):Boolean;overload;
    function    Out (Value : DWord):Boolean;overload;

    function    Inp   : Byte;
    function    InpW  : Word;
    function    InpDW : DWord;

    function    OutP (Addr : Word; Value : Byte):Boolean;overload;
    function    OutP (Addr : Word; Value : Word):Boolean;overload;
    function    OutP (Addr : Word; Value : DWord):Boolean;overload;

    function    InpP  (Addr : Word) : Byte;
    function    InpWP (Addr : Word) : Word;
    function    InpDWP(Addr : Word) : DWord;

    property    Port   [Addr : Word] : Byte  read GetBytePort  write SetBytePort;
    property    PortW  [Addr : Word] : Word  read GetWordPort  write SetWordPort;
    property    PortDW [Addr : Word] : DWord read GetDWordPort write SetDWordPort;

    property    D0 : Boolean read GetD0 write SetD0;
    property    D1 : Boolean read GetD1 write SetD1;
    property    D2 : Boolean read GetD2 write SetD2;
    property    D3 : Boolean read GetD3 write SetD3;
    property    D4 : Boolean read GetD4 write SetD4;
    property    D5 : Boolean read GetD5 write SetD5;
    property    D6 : Boolean read GetD6 write SetD6;
    property    D7 : Boolean read GetD7 write SetD7;

    property    Initialized : Boolean   read FInitialized;
    property    Ports       : TLPTList  read FPorts write SetPorts;
  published
    property    LPTPort     : Word         read FPort        write FPort;

    {
     Inp normalement Inp = Base + 1 pour lire l'état
     donc inp vaut 1 par défaut, lors de l'appel à la fonction Inp, celle-ci renvoie inp(Port + LptInp);
    }
    property    InpOffset   : Integer      read FInpOffset   write FInpOffset default 1;

    property    OnPinChange : TOnPinChange read FOnPinChange write FOnPinChange;
  end;

{$R LPTPort.dcr}

function PinNameToPinInfo(Name  : String; var Info : TPinInfo):Boolean;
function PinValToPinKinds(Value : Byte):TPinKinds;
function GetDir:String;// revient au même que ExtractFilePath mais sans utiliser Application.ExeName(dans Forms)
function DecToBin(Value : Integer ; nBits : Integer = 8): String;
function HexToBin(Value : String  ; nBits : Integer = 8):String;
function IsNumeric(Value : String):Boolean;

{
 Make Memory Location
 permet d'avoir l'équivalent de la fonction TurboPascal MemW[xx:xx]
 Seulement cette fonction ne fait que calculer l'adresse physique à partir de l'adresse logique, et ne fournis aucun accès à celle-ci
 Exemple
 l'adresse logique [0040:0008] contient l'adresse du port de LPT1
 et donc son adresse physique est $408;

 autre exemple
 [$2135:$4A] correspond à l'adresse Physique $2139A
}

function MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD;


procedure Register;

implementation

procedure Register;
begin
    RegisterComponents('SFC I/O' , [TLPTPort]);
end;

   Type
   TDriverInfo = record
   Name    : String;
   ResName : String;
   end;

   Const
   TDrivers : array [0..2] of TDriverInfo = (
   (Name : 'WinIO.dll' ; ResName : 'WIDL'), // noyau  Sys <> OS
   (Name : 'WinIO.sys' ; ResName : 'WISY'), //  pour Win2000,XP,NT
   (Name : 'WinIO.vxd' ; ResName : 'WIVX')  //  pour Win95,98
   );

  {
   Déclaration de la DLL WinIO.dll
  }
   var
   InitializeWinIo     : function : Boolean;stdcall;
   ShutdownWinIo       : function : Boolean;stdcall;
   MapPhysToLin        : function (var pbPhysAddr: Byte; dwPhysSize : Integer; var pPhysicalMemoryHandle : THandle):PByte;
   UnmapPhysicalMemory : function (PhysicalMemoryHandle : THandle; var pbLinAddr: Byte): Boolean;
   GetPhysLong         : function (pbPhysAddr : DWORD;  var pdwPhysVal  : DWORD): Boolean;stdcall;
   SetPhysLong         : function (pbPhysAddr : DWORD; dwPhysVal  : DWORD): Boolean;stdcall;
   GetPortVal          : function (wPortAddr : Word; var pdwPortVal : Integer; bSize: Byte): Boolean;stdcall;
   SetPortVal          : function (wPortAddr : Word; dwPortVal: Integer; bSize: Byte): Boolean;stdcall;
   InstallWinIoDriver  : function (pszWinIoDriverPath: PChar; IsDemandLoaded : Boolean = False): Boolean;stdcall;
   RemoveWinIoDriver   : function  : Boolean;stdcall;
   StartWinIoDriver    : function  : Boolean;stdcall;
   StopWinIoDriver     : function  : Boolean;stdcall;

function  PinNameToPinInfo(Name : String; var Info : TPinInfo):Boolean;
var
I : Integer;
begin
    result := False;
    for i := Low(TPinLookUp) To High(TPinLookUp) do
    begin
        if SameText(Name , TPinLookUp[i].Name) then
        begin
            Info := TPinLookUp[i];
            result := True;
            Break;
        end;
    end;
end;

function PinValToPinKinds(Value : Byte):TPinKinds;
var
i   : Integer;
Pin : TPinInfo;
begin
    result := [];
    for i := Low(TPinLookUp) to High(TPinLookUp) do
    begin
        Pin := TPinLookup[i];
        if (Value and Pin.Offset) = Pin.Offset then
        result := result + [Pin.Kind];
    end;
end;

function GetDir:String;
begin
    result := GetCurrentDir + '\';
end;

function DecToBin(Value : Integer ; nBits : Integer = 8): String;
var
  i : Integer;
  C : Char;
begin
    Result := '';
    for i := nBits-1 downto 0 do
    begin
        C := '0';
        if  (Value and (1 shl i)<>0)  then C := '1';
        result := result + C;
    end;
end;

function HexToBin(Value : String ; nBits : Integer = 8):String;
begin
    result := DecToBin(StrToInt('$' + Value), nBits);
end;

function IsNumeric(Value : String):Boolean;
var
P : PChar;
begin
    result := False;
    P := PChar(Value);
    while (P^<>#0) do
    begin
        if P^ in ['0'..'9', 'A'..'F', 'a'..'f'] then
        result := true else
        begin
            result := false;
            break;
        end;
        inc(P);
    end;
end;

function MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD;
begin
    Offset  := (Offset shl 4) and $FFFFFFFF;
    Segment := Segment  and $FFFFFFFF;
    result  := Offset + Segment;
end;
{ TLPTPort }

function TLPTPort.Close: Boolean;
begin
    result := ShutDownWinIO;
end;

constructor TLPTPort.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);
    FInitialized := False;
    FDLLHandle   := 0;
    FPort        := $378; // Base
    FInpOffset   := 1;    // Base + 1 = Status register
    FUpdate      := False;
    FPorts       := TLPTList.Create; 
    LoadSysDrivers;
    InitializeDrivers;
end;

destructor TLPTPort.Destroy;
begin
    FinalizeDrivers;
    FreeSysDrivers;
    FPorts.Free; 
    inherited Destroy;
end;

function TLPTPort.GetBytePort(Addr: Word): Byte;
begin
    result := InpP(Addr);
end;

function TLPTPort.GetDWordPort(Addr: Word): DWord;
begin
    result := InpDWP(Addr);
end;

function TLPTPort.GetWordPort(Addr: Word): Word;
begin
    result := InpWP(Addr);
end;

function TLPTPort.Inp : Byte;
var
Ret : Integer;
begin
    result := 0;
    if GetPortVal(FPort  + FInpOffset , Ret , 1) then
    result := (Ret and $FF);
end;

function TLPTPort.InpW : Word;
var
Ret : Integer;
begin
    result := 0;
    if GetPortVal(FPort + FInpOffset , Ret , 2) then
    result := (Ret and $FFFF);
end;

procedure TLPTPort.InitializeDrivers;
begin
    FDLLHandle           := LoadLibrary(PChar(TDrivers[0].Name));
    @InitializeWinIo     := GetProcAddress(FDLLHandle,'InitializeWinIo');
    @ShutdownWinIo       := GetProcAddress(FDLLHandle,'ShutdownWinIo');
    @MapPhysToLin        := GetProcAddress(FDLLHandle,'MapPhysToLin');
    @UnmapPhysicalMemory := GetProcAddress(FDLLHandle,'UnmapPhysicalMemory');
    @GetPhysLong         := GetProcAddress(FDLLHandle,'GetPhysLong');
    @SetPhysLong         := GetProcAddress(FDLLHandle,'SetPhysLong');
    @GetPortVal          := GetProcAddress(FDLLHandle,'GetPortVal');
    @SetPortVal          := GetProcAddress(FDLLHandle,'SetPortVal');
    @InstallWinIoDriver  := GetProcAddress(FDLLHandle,'InstallWinIoDriver');
    @RemoveWinIoDriver   := GetProcAddress(FDLLHandle,'RemoveWinIoDriver');
    @StartWinIoDriver    := GetProcAddress(FDLLHandle,'StartWinIoDriver');
    @StopWinIoDriver     := GetProcAddress(FDLLHandle,'StopWinIoDriver');
end;

function TLPTPort.InpDW: DWord;
var
Ret : Integer;
begin
    result := 0;
    if  GetPortVal(FPort + FInpOffset , Ret , 4) then
    result := (Ret and $FFFFFFFF);
end;

function TLPTPort.Open: Boolean;
begin
    FInitialized := InitializeWinIo;
    result       := FInitialized;
end;

function TLPTPort.Out(Value: Byte): Boolean;
begin
    result := SetPortVal(FPort , Value, 1);
end;

function TLPTPort.Out(Value: Word): Boolean;
begin
    result := SetPortVal(FPort , Value, 2);
end;

function TLPTPort.Out(Value: DWord): Boolean;
begin
    result := SetPortVal(FPort , Value, 4);
end;

procedure TLPTPort.SetBytePort(Addr: Word; const Value: Byte);
begin
    OutP(Addr, Value);
end;

procedure TLPTPort.SetDWordPort(Addr: Word; const Value: DWord);
begin
    OutP(Addr, Value);
end;

procedure TLPTPort.SetWordPort(Addr: Word; const Value: Word);
begin
    OutP(Addr, Value);
end;

procedure TLPTPort.FreeSysDrivers;
var
i : integer;
begin
    for i := Low(TDrivers) to High(TDrivers) do
    DeleteFile(GetDir + TDrivers[i].Name);
end;

procedure TLPTPort.LoadSysDrivers;
var
I   : Integer;
Res : TResourceStream;
FileName : String;
begin
    { Extraction du Driver depuis le ressource LPTPort.dcr }
    res := nil;
    for i := Low(TDrivers) to High(TDrivers) do
    begin
        FileName := GetDir + TDrivers[i].Name;
        if FileExists(FileName)=False then
        begin
            try
            Res := TResourceStream.Create(hInstance , TDrivers[i].ResName , 'WINIO');
            Res.SaveToFile (FileName);
            { fichier caché }
            SetFileAttributes(PChar(FileName), FILE_ATTRIBUTE_SYSTEM + FILE_ATTRIBUTE_HIDDEN);
            finally
            Res.Free;
            end;
        end;//File doesn't exists
    end;//i++
end;

procedure TLPTPort.FinalizeDrivers;
begin
    FreeLibrary(FDLLHandle);
end;

procedure TLPTPort.SetPin(Name: String; State: Boolean = true);
var
Info : TPinInfo;
begin
    if PinNameToPinInfo(Name, Info) then
    begin
        Case Info.Kind of
        pkD0 : D0 := State;
        pkD1 : D1 := State;
        pkD2 : D2 := State;
        pkD3 : D3 := State;
        pkD4 : D4 := State;
        pkD5 : D5 := State;
        pkD6 : D6 := State;
        pkD7 : D7 := State;
        end;
    end;
end;

procedure TLPTPort.SetD0(const Value: Boolean);
begin
    if FLS[0] <> Value then
    begin
        FLS[0] := Value;
        NotifyPinChange('D0' , Value);
    end;
end;

procedure TLPTPort.NotifyPinChange(Name: String; State: Boolean);
var
Info : TPinInfo;
begin
    if PinNameToPinInfo(Name , Info) then
    begin
        if Assigned(FOnPinChange) then FOnPinChange(Self , Info , State);

        case State of
        True  :
        begin
            Inc(FPinHash , Info.Offset);
        end;

        False :
        begin
            Dec(FPinHash , Info.Offset);
        end;

        end;
        if FUpdate = False then
        Out(FPinHash);
    end;//Pin Found
end;

procedure TLPTPort.SetD1(const Value: Boolean);
begin
    if FLS[1] <> Value then
    begin
        FLS[1] := Value;
        NotifyPinChange('D1' , Value);
    end;
end;

procedure TLPTPort.SetD2(const Value: Boolean);
begin
    if FLS[2] <> Value then
    begin
        FLS[2] := Value;
        NotifyPinChange('D2' , Value);
    end;
end;

procedure TLPTPort.SetD3(const Value: Boolean);
begin
    if FLs[3] <> Value then
    begin
        FLS[3] := Value;
        NotifyPinChange('D3' , Value);
    end;
end;

procedure TLPTPort.SetD4(const Value: Boolean);
begin
    if FLS[4] <> Value then
    begin
        FLS[4] := Value;
        NotifyPinChange('D4' , Value);
    end;
end;

procedure TLPTPort.SetD5(const Value: Boolean);
begin
    if FLS[5] <> Value then
    begin
        FLS[5] := Value;
        NotifyPinChange('D5' , Value);
    end;
end;

procedure TLPTPort.SetD6(const Value: Boolean);
begin
    if FLS[6] <> Value then
    begin
        FLS[6] := Value;
        NotifyPinChange('D6' , Value);
    end;
end;

procedure TLPTPort.SetD7(const Value: Boolean);
begin
    if FLS[7] <> Value then
    begin
        FLS[7] := Value;
        NotifyPinChange('D7' , Value);
    end;
end;

function TLPTPort.GetD0: Boolean;
begin
    result := (Inp and $1) = $1; 
end;

function TLPTPort.GetD1: Boolean;
begin
    result := (Inp and $2) = $2;
end;

function TLPTPort.GetD2: Boolean;
begin
    result := (Inp and $4) = $4;
end;

function TLPTPort.GetD3: Boolean;
begin
    result := (Inp and $8) = $8;
end;

function TLPTPort.GetD4: Boolean;
begin
    result := (Inp and $10) = $10;
end;

function TLPTPort.GetD5: Boolean;
begin
    result := (Inp and $20) = $20;
end;

function TLPTPort.GetD6: Boolean;
begin
    result := (Inp and $40) = $40;
end;

function TLPTPort.GetD7: Boolean;
begin
    result := (Inp and $80) = $80;
end;


function TLPTPort.OutP(Addr: Word; Value: Byte): Boolean;
begin
    result := SetPortVal(Addr , Value, 1);
end;

function TLPTPort.OutP(Addr, Value: Word): Boolean;
begin
    result := SetPortVal(Addr , Value, 2);
end;

function TLPTPort.OutP(Addr: Word; Value: DWord): Boolean;
begin
    result := SetPortVal(Addr , Value, 4);
end;

function TLPTPort.InpDWP(Addr: Word): DWord;
var
Ret : Integer;
begin
    result := 0;
    if  GetPortVal(Addr + FInpOffset , Ret , 4) then
    result := (Ret and $FFFFFFFF);
end;

function TLPTPort.InpP(Addr: Word): Byte;
var
Ret : Integer;
begin
    result := 0;
    if GetPortVal(Addr + FInpOffset , Ret , 1) then
    result := (Ret and $FF);
end;

function TLPTPort.InpWP(Addr : Word): Word;
var
Ret : Integer;
begin
    result := 0;
    if GetPortVal(Addr + FInpOffset , Ret , 2) then
    result := (Ret and $FFFF);
end;

procedure TLPTPort.BeginUpdate;
begin
    FUpdate := True;
    
end;

procedure TLPTPort.EndUpdate;
begin
    if FUpdate then
    begin
        FUpdate := False;
        Out(FPinHash);
    end;
end;

procedure TLPTPort.SetPins(Names: array of String);
var
i     : Integer;
Info  : TPinInfo;
State : Boolean;
begin
    BeginUpdate;
    ClearPins;
    for i := Low(Names) to High(Names) do
    begin
        PinNameToPinInfo(Names[i] , Info);
        State := True;
        Case Info.Kind of
        pkD0 : D0 := State;
        pkD1 : D1 := State;
        pkD2 : D2 := State;
        pkD3 : D3 := State;
        pkD4 : D4 := State;
        pkD5 : D5 := State;
        pkD6 : D6 := State;
        pkD7 : D7 := State;
        end;//Case
    end;//i++
    EndUpdate;
end;

procedure TLPTPort.ClearPins;
begin
    D0 := False;
    D1 := False;
    D2 := False;
    D3 := False;
    D4 := False;
    D5 := False;
    D6 := False;
    D7 := False;
end;

function TLPTPort.GetPhysDWORD(Addr : DWORD; var Return : DWORD): Boolean;
begin
    Addr := Addr and $FFFFFFFF;
    result := GetPhysLong( Addr , Return );
    if result then Return := (Return and $FFFFFFFF);
end;

function TLPTPort.SetPhysDWORD(Addr, Value: DWORD): Boolean;
begin
    Addr   := (Addr  and $FFFFFFFF);
    Value  := (Value and $FFFFFFFF);
    result := SetPhysLong(Addr , Value);
end;

procedure TLPTPort.EnumPorts;
var
I          : Integer;
SearchBase : DWORD;
PortFind   : DWORD;
begin
    SearchBase := $408; // [$40:$008]
    Ports.Clear;
    for i := 1 to 3 do // LPT1 ... LPT3
    begin
        if GetPhysDWORD(SearchBase , PortFind) then
        begin
            PortFind := (PortFind and $FFFF);
            if (PortFind > 0) then
            begin
                with Ports.Add do
                begin
                    Name := Format('LPT%u' , [i]);
                    Port := PortFind;
                end;//with Ports.Add
            end;
        end;//if GetPhysique
        inc(SearchBase , 2);
    end;// i ++
end;

{ implementation of TLPTList }

function TLPTList.GetItem (Index : Integer): TLPTListItems;
begin
    result := TLPTListItems(inherited GetItem(Index));
end;

procedure TLPTList.SetItem (Index : Integer ; Value : TLPTListItems);
begin
    inherited SetItem(Index, Value);
end;

Constructor TLPTList.Create;
begin
    inherited Create(TLPTListItems);
end;

Destructor TLPTList.Destroy;
begin
    inherited Destroy;
end;

function TLPTList.Add: TLPTListItems;
begin
    result := TLPTListItems(inherited Add);
end;

function TLPTList.ItemExist (ItemName : String): Boolean;
var
I : Integer;
begin
    result := False;
    ItemIndex := -1;
    for i :=0 to Count -1 do
    begin
        if SameText(ItemName, Items[i].Name)  Then
         begin
             ItemIndex  := I;
             ItemFind   := Items[i];
             result     := True;
             Break;
         end;//Trouver
    end;//Fin de la boucle I
end;

function TLPTList.ItemOf (ItemName : String): TLPTListItems;
begin
    result := nil;
    if ItemExist(ItemName) Then
    result := Items[ItemIndex];
end;
  
  
{ implementation of TLPTListItems }

Constructor TLPTListItems.Create (Collection : TCollection);
begin
    inherited Create(Collection);
    Parent          := TLPTList(Collection);
    FPort           := 0;
end;

Destructor TLPTListItems.Destroy;
begin
    inherited Destroy;
end;

procedure TLPTListItems.Assign (Source : TPersistent);
begin
    if Source is TLPTListItems Then
    begin
        FName    := TLPTListItems(Source).FName;
        FPort    := TLPTListItems(Source).FPort;
    end else
    inherited;
end;

procedure TLPTPort.SetPorts(const Value: TLPTList);
begin
    FPorts.Assign(Value); 
end;

procedure TLPTPort.EnumPorts(Strings: TStrings);
var
i : Integer;
begin
    Strings.Clear;
    EnumPorts;    
    for i := 0 to Ports.Count -1 do
    Strings.Add(Ports[i].Name);
end;

procedure TLPTPort.SelectPort(Addr: WORD);
begin
    LPTPort := Addr; 
end;

procedure TLPTPort.SelectPortByIndex(PortIndex: Integer);
begin
    LPTPort := Ports[PortIndex].Port;
end;

end.

 Conclusion


l'utilisation du composant est très simple, d'ailleur vous n'êtes pas obliger d'installer le composant, vous pouvez le créé dynamiquement.

ce composant à été tester sur Windows 98 & XP Pro avec succès.

important !!!
si dans une de vos application vous devez lire la broche "busy", n'oubliez pas de mettre InpOffset = 1 si toute fois vous avez changer sa valeur

ensuite c'est simple la valeur du poids de busy est 128 une simple routine logique permet d'en lire l'état
exemple
InpOffset := 1;
if (Lpt.Inp and 128)=128 then ....
je rappel que Busy est activer à l'état 0

pas de bug pour le moment...

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

05 mars 2006 19:34:52 :
Prise en charge de la plate-form XP Version Composant
11 mars 2006 22:11:44 :
- Ajout de SelectPort(Addr : WORD); équivaut à LPTport := Addr - Ajout de SelectPortByIndex(PortIndex : Integer); choisit le port en fonction du combobox - Ajout de GetPhysDWORD(Addr : DWORD ; var Return : DWORD):Boolean; Lecture de la Mémoire Physique en DWORD=LongWord - Ajout de SetPhysDWORD(Addr : DWORD ; Value : DWORD):Boolean; écriture de la Mémoire Physique - Ajout de EnumPorts(Strings : TStrings);overload; énumération des Ports disponibles dans un Combobox; EnumPorts;overload; // énumération des Ports dans la List(TCollection) - Ajout de MakeMemLoc(Offset : DWORD ; Segment : DWORD): DWORD; transforme une adresse logique en adresse physique [xx:xx]

 Sources du même auteur

Source avec Zip Source avec une capture SFCDELPHILITE(AVEC CETTE LIBRAIRIE VOUS POUVEZ CRÉER UNE APP...
Source avec Zip Source avec une capture SHININGDATABASE & VIRTUALDATABASE DEUX COMPOSANTS ORIENTÉS D...
Source avec Zip Source avec une capture FASTGRADIENT (METTEZ DES DÉGRADÉS DE COULEURS DANS VOS APPLI...
Source avec Zip COMPOSANT HASHPROTECTOR (PROTÉGEZ VOS APPLICATIONS CONTRE L...
Source avec Zip Source avec une capture COMPOSANT EMOTICONMANAGER (DONNEZ DE L'EMOTION À VOS APPLICA...

 Sources de la même categorie

Source avec Zip Source avec une capture EXTRAIRE PÉRIPHÉRIQUE USB ( HOTPLUG ) par yanb
Source avec Zip Source avec une capture LOGICIEL INTERRUPTEUR MONDIAL USB par ced55957
Source avec Zip Source avec une capture RETIRER LES PÉRIPHÉRIQUES USB par yanb
Source avec Zip CHARGER ET ENVOYER DES DONNÉES VIA L'USB par ldesmartin
Source avec Zip Source avec une capture GESTION DU CLAVIER G15 DE LOGITECH par delphitness

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture USB : 8 ENTREES / 16 SORTIES AVEC UN PIC18F4550 (HID). par rylryl
Source avec Zip Source avec une capture PORT SERIE : CONTRÔLER 8 SORTIES AVEC UN HCF4094. par rylryl
Source avec Zip PORT PARALLÈLE : CONTRÔLEZ MEDIAPLAYER AVEC UNE TÉLÉCOMMANDE... par rylryl
Source avec Zip UNE CLASSE POUR LE PORT RS232 OU LPT par medelias
Source avec Zip PORT-SCAN par Acoders

Commentaires et avis

Commentaire de shining le 25/04/2003 09:15:17

Avec ces fonctions on peut déja faire pas mal de choses, tel qu'un lecteur/encodeur de Carte T2G (carte téléphonique de nouvel generation), bien que cette derniere ne permet pas une grande protection contre la relecture(je fait allusion aux applications a base de serrure codé, dont la clé n'est autre qu'une carte T2G ect...)  mais ceci dit c'est pas bien compliqué de faire un soft de ce genre.

Commentaire de 0nE le 26/04/2003 04:50:38

de l'asm tt ce k'ya de plus simple.pas la peine de chercher à faire autrement sous 95/98 puisque c la soluce la + directe.

bon alors juste un truc : sous 2000 ou sous xp ca marche pas parce ke l'os interdit l'acces direct au materiel.il faut utiliser un pilote genre tdlportio (http://diskdude.cjb.net/) pour ke ca marche.Ou c port95nt je c plus... (il est tard lol).

concernant le lecteur à t2g,sans etre totalement sur, fo surtout pas lire la carte entierement pour la comparer puisque certains bits changent (c une des protection de la t2g et c pour ca ke c pas possible de faire un emulateur de carte telephonique avec un pic,par ex).et si mes souvenir sont bon y a ke 4 ou 8 bits ki changent a chaque lecture et a l epoque ou je m etais interesse au prob l'algo de protection n'avait tjrs pas été découvert.

concernant l ecriture sur ta carte,excuse la kestion ms ca fait 2 ans ke g pas fait d'elec ms je crois me souvenir ke la carte ne pouvait etre écrite k'une fois (on met les bit à 0 ou à 1 je c plus).

en tt cas c sympa parce ke ce bout de code c absolument obligatoire pour des gens ki font de l'elec et ki utilisent leur pc avec leur montage.

Commentaire de shining le 26/04/2003 09:23:58

Voila j'avais fais ca très vite, et de tête sans créé de Projet et...
maitenant j'ais remodifié ma source et la fonction INP fonctionne a présent, de plus la Table d'Adressage était incorrecte, j'ais donc rectifié les erreurs,ya la démo dans le Zip .... faut placé le Composant TSmartLed dans le même repertoire. En ce qui Concerne WinXP je pense qu'il bloque l'ecriture
des fichiers, genre Com1 ect.. tandis que la on travail directement avec le BIOS, donc c'est a tester sur XP, ca marche Impec sous Win98SE, dans les Carte T2G il reste toujours pas mal d'octet de libre qu'ont peut manipuler mais evidemment on ne peut plus inversé le Processus :). voila que dire de plus bah l'exemple lis etat du registre 888, j'ais desactivé la fonction qui ajoute+1 dans INP, car Base+1=Registre d'état
donc pour lire les états de Busy il faut faire INP(ActivePort+1) And 128;

Commentaire de kanon le 02/05/2003 22:49:02

Salut!
je suis nouveau et je n'y connais pas grand chose en prog
mais je fais un espèce d'exposé ou je dois commander un appareil électrqiue par un pc.
on a déjà la fonction outport, le pilote, mais je ne sais pas comment commander pin par pin:

une commande du type ouport(0x378,2) met le pin 1 à 1, donc met la broche 2 ok?
bon, je suis pas niais non plus, mais c juste pour savoir si ca marchera car je ne compte pas griller le pc de mon pote

rappel : 0x378: adresse du port parallèle

Commentaire de shining le 03/05/2003 09:29:10

petit Rappel de la Table d'adressage
en electronique on lis les données binaires de la droite vers la gauche okay!!!  d'ou .....

MSB                                           LSB
D7| D6 | D5 | D4 | D3 | D2 | D1 | D0 |
128| 64 | 32 | 16 |  8  |   4 |  2  |  1  |

voila si l'on veut mettre le pin 4(D3) à 1 on écrira Out(LPT1,8);
puisque 8 DECIMAL vaut  0000 1000 en binaire ce qui nous donne

D7| D6 | D5 | D4 | D3 | D2 | D1 | D0 |
128| 64 | 32 | 16 |  8  |   4 |  2  |  1  |
  0 |  0  |  0  |  0  |  1  |  0  |  0  |  0  |
alors c'est pour ca que j'ais créé  la fonction SetPin, elle a deux fonction surcharger:
si on lui attribue une valeur décimale alors la fonction vas tout simplement  mettre a 1 le pin voulu,

exemple:
SetPin(ActivePort,1) vas mettre a 1 la sortie D0(broche 2), en revanche si on lui attribue une valeur chaine, la fonction vas mettre a 1 tout les pins mis a 1 dans la chaine de type binaire c'est a dire SetPin(ActivePort,'0000,1000') aura la même fonction que SetPin(ActivePort,1) sauf que avec les chaines on peut geré plus de sortie, autre Exemple
SetPin(ActivePort,'0,1,0,1,0,0,1,0') vas mettre a 1 D6,D4,D1 et a zéro D0,D2,D3,D5,D7 okay??? faut juste ce rappelé qu'on part de la droite vers la guauche, il est donc inutile de créé la fonction OutPort puisque les commentaires que j'avais mis était pour le début de mon post, car il n'y avait pas les fonctions SetPin ect....
donc utilisez la fonction SetPin car elle vas facilité la gestion des sorties puisque elle fait le calcul d'adressage des sorties ;)
et il ne faut surtout pas croire que LPT1=0x378 car tout dépend de la configuration du Bios ect....., et LPT1 peut avoir la valeur 0x378 ou 0x3BC c'est le cas pour WinXP qui gère 3 ports LPT.

attention le composant TSmLed a subit quelque améliorations
et certaine propriété on changer de nom
par exemple Activate a été remplacer par Active, donc il suffit de faire la modife sinon je vais recompiler le projet avec pour ceux qui auront des problèmes(newbies oblige).






Commentaire de shining le 03/05/2003 09:35:31

arf SetPin(ActivePort,'0000,1000') aura la même fonction que SetPin(ActivePort,4)  et non SetPin(ActivePort,1) qui lui met a 1 D0
bien sur ActivePort renvoi le port choisit dans le ComboBox on peut
écrire SetPin(0x378,4) ou bien SetPin(LPT1,4); puisque LPT1 a été initialisé tout au début par la valeur 0x378(a changer si vous avez LPT1 sur une autre adresse)

Commentaire de shining le 03/05/2003 10:08:09

&lt; je fais un espèce d'exposé ou je dois commander un appareil électrqiue par un pc &gt;.
on ne peut pas commander de moteur, genre pas a pas directement
car le courant délivré est très faible pour cela il est préférable de réaliser
un protecteur de port centronics, parut dans INTERFACE PC Hors Série N°04
Octobre 1999, tiens je te donne l'adresse, regarde les archives il ce peut qu'ils donne le schéma + Nomenclature
http://www.electroniquepratique.com/

Commentaire de grandvizir le 06/07/2004 21:38:23

Ce code source est très simple à comprendre. Il manque certes SMLED.PAS, mais cela ne m'a pas empêché de le reproduire rapidement. Cependant, il y a un problème délicat. Par curiosité, j'ai fait des tests avec des ports autres que LPT1 et LPT2 (exemple: port=50) et je dois avouer que ça fait un plantage général (Win98SE) malgré que le code ne soit que de la lecture. C'est pareil parfois avec LPT1 et LPT2. Y'avait un timer réglé tel que dt=5 secondes.

Ces manifestations sont des messages illisibles lors d'un lancement avec mon Delphi 3. Si l'application est lancée à partir de Windows, on connait les messages: "Les canvas ne permettent pas de dessiner", "Paramètre"... tout cela avec des boîtes de dialogue rappellant étrangement un style 16 bits. Ca m'a bien gonflé... Ce test illustre qu'il faut aborder avec prudence de tels codes sources. Ceci dit, il est puissant.

Commentaire de shining le 12/07/2004 04:22:53

Salut grandvizir, en ce qui concerne SmLed il est dit plus  Dans le Nota, en fait c'est seulement là démo qui utilise ce composant. quand au port 50 que tu as exploité en lecture j'ignore la spécification de ce port, mais il est évident qu'il ne faut pas tenter de lire où écrire dans les registres spéciaux qu'on ne maîtrise pas sous risque de.... pour ceux qui sont intérresser, une mise à jour, va corriger le porblème lier à WinXP, en version Composant, il permetra une plus grande facilité de la gestion du port LPT; exemple D0:=True va tout simplement mettre la Broche 2 à l'état Haut, ce composant va automatiquement installer le driver(ZlPortIO) dans le repertoire du soft, le charger , et le détruire lors de la fermeture du Programme. Donc Patience pour la Mise à Jour ;)

Commentaire de jlen100 le 07/03/2006 14:49:09

salut shining;
mise à jour importante effectivement puisque les drivers Winio prennent en charge XP ce qui n'était pas le cas précédemment.
bonne mise à jour qui manquait

@+
jlen

Commentaire de shining le 08/03/2006 01:17:38

merci JLEN100, en effet avant je n'avais pas XP, il m'était donc difficile d'inclure la gestion de cet OS sans pouvoir tester sur place, bon maintenant que chui passer sous XP c'est une autre histoire :o)
@+

Commentaire de kle500 le 06/11/2006 09:17:45

bon travail a vous tous ,
j'utilise 3 pc d'ont 1 que j'utilise le w98 + delphi3 pour faire mes *.dll pour utiliser le port sur d'autre windows.
A+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Port Lpt sous delphi et winnt ?? [ par fredy24 ] Bonjours, je voudrais controler l'état d'une imprimante sous une application delphi avec winnt. j'ai installé la dll inpout32 avec son application, ok Ecrire sur Port LPT - en VBA Excel [ par raftanelle ] &nbsp;raftanelleBonjour. Un peu d'aide ne me faira pas de mal.Comme beaucouq je suis perdu.Sur Excel, il me faudrait une Macro pour activer les entr&# Capture de port LPT [ par Amadeus ] Quelqu'un connait-il un logiciel permettant de capturer les données envoyé vers une imprimante.Ou des composant delphi qui le permette info sur port lpt: esque je peu appliquer une tention 5v sur l'un des pins du port // [ par damomospike ] salut a tous,Je suis entrain de réaliser un projet ki utilise le port paralllelejai tout ski me faut, je sais lire et écrir sur le port ms jai quand m Barriere IR sur port parallele [ par VinceH ] Salut,je voudrais pouvoir, depuis une application Delphi, avoir l'etat d'une barriere infra-rouge reliee sur le port parallele.Le principe serait le s port //, esque c possible d'envoyer une tention de 5v sur un pin du port // et de le lire [ par damomospike ] Voila tt et ds le titre, je voulai savoir surtt si yavai pas des chance de griller ma carte mere, on ma di ki fallai metre un min a leta logique 0 pou communication avec le port série [ par cermav ] Bonjour,Je cherche à piloter un générateur de tension via le port série sous delphi5.je rentre les codes suivant: comport1.open;comport1.writesr('01') je voudrais un exemple pour Interroger directement le port parallele sous windows XP [ par ludolechinois ] J'ai realisee un petit montage electronique entrees et sorties sur le port parallele, mais sous windows XP cela ne marche pas. Avez vous un exemple so Comment ecrire sur le port série sous delphi 8 pour .net? [ par baris48 ] je viens de découvrir le delphi8 .net... j ai qlq pb avec l'ecriture et lecture sur le port série j ai utilisé les méthodes de l api Windows: openFil comment sur un port série sosu delphi 8 .net? [ par baris48 ] Bjr,j ai des pb pr ecrire sur le port série ss delphi 8 .net?j ai essayé d utiliser writeFile ReadFile, la sol de delphi 7 .. mais sans succès.. :(si


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,671 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales