该控件全部代码如下:<br><br>unit LptCtrl;<br>{--------------------------------------------------------------------<br>IDENTIFICATION<br>Unit Name: LptCtrl<br>Reg No: -<br>Revision: See revision history.<br>File Name: LptCtrl.pas<br>Target: PC w Intel 386+, LPT port, Windows 3.1 or compatible.<br>Compiler: Delphi 1.x. Note! This unit will probably<br> not compile with Delphi 2.x.<br>Issued By: (c) Tord Andersson, 1996. (anderssonto@decus.se).<br> Legal disclaimer. The author will take no responsibilty <br> for damages that could be the result of using this<br> component.<br>Reviewed By: -<br>Tested By: -<br><br>DESCRIPTION<br>This unit holds TlptCtrl, a class/component which is intended<br>for reading/writing directly to an LPT port.<br><br>REVISION HISTORY<br>Version Date Change/addition Resp<br>0.2 960606 Released to the public domain. Tord Andersson<br><br>====================================================================}<br><br><br>interface<br><br>uses<br> SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,<br> Forms, Dialogs;<br><br>type<br> TLpt = (None, Lpt1, Lpt2, Lpt3);<br> TLptAvail = array [1..3] of boolean; { is port available? }<br> TPortAddrArr = array [1..3] of word;<br> TlptCtrl = class(TComponent)<br> private<br> { Private declarations }<br> FLpt: TLpt;<br> FPortAddrArr: TPortAddrArr; { LPT port addresses }<br> FPortAddr: word; { selected LPT port address }<br> FLptAvail: TLptAvail;<br> FData: byte; { LPT data out }<br> FDummy: byte; { will only be used to make 'Status' published }<br><br> procedure SetLptPort(Value: Tlpt);<br> { SetPortAddress will usually be automatically handled<br> through SetLptPort. }<br> procedure SetPortAddress(Value: word);<br> procedure SetData(Value: byte);<br> function GetStatus: byte;<br> function GetCtrl: byte;<br> procedure SetCtrl(Value: byte);<br> procedure FindLptAddr;<br><br><br> protected<br> { Protected declarations }<br> public<br> { Public declarations }<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br> property LptAvail: TLptAvail read FLptAvail; { what ports are available? }<br><br> published<br> { Published declarations }<br> property LptPort: TLpt read FLpt write SetLptPort default None;<br> property PortAdress: word read FPortAddr write SetPortAddress;<br> property Data: byte read Fdata write SetData default 0;<br> property Status: byte read GetStatus write FDummy;<br> property Ctrl: byte read GetCtrl write SetCtrl;<br> end;<br><br>procedure Register;<br><br>implementation<br><br>{ FindLptAddr - Will find the addresses of LPT port (1-3).<br> Non valid ports will result in address 0.<br> Note FLptPortAddr[] and FLptAvail will be affected. }<br>procedure TlptCtrl.FindLptAddr;<br>begin<br> { Yes, I know, this could have been coded as a loop... }<br> FPortAddrArr[1] := mem[$0040:$08] + mem[$0040:$09]*256;<br> if FPortAddrArr[1] > 0 then FLptAvail[1] := true;<br><br> FPortAddrArr[2] := mem[$0040:$0A] + mem[$0040:$0B]*256;<br> if FPortAddrArr[2] > 0 then FLptAvail[2] := true;<br><br> FPortAddrArr[3] := mem[$0040:$0C] + mem[$0040:$0D]*256;<br> if FPortAddrArr[3] > 0 then FLptAvail[3] := true;<br>end;<br><br>procedure TLptCtrl.SetLptPort(Value: Tlpt); { To set up the choosen port }<br>begin<br> case Value of<br> Lpt1: if FLptAvail[1] then<br> begin<br> FPortAddr := FPortAddrArr[1];<br> FLpt := Lpt1;<br> end;<br> Lpt2: if FLptAvail[2] then<br> begin<br> FPortAddr := FPortAddrArr[2];<br> FLpt := Lpt2;<br> end;<br> Lpt3: if FLptAvail[3] then<br> begin<br> FPortAddr := FPortAddrArr[3];<br> FLpt := Lpt3;<br> end;<br> else<br> begin<br> FPortAddr := 0;<br> FLpt := None;<br> end;<br> end;<br>end;<br><br>procedure TlptCtrl.SetPortAddress(Value: word); { for those who hate automation : ) }<br>begin<br> FPortAddr := Value;<br>end;<br><br>procedure TlptCtrl.SetData(Value: byte); { put data on LPT data lines }<br>begin<br> if FLpt <> None then<br> begin<br> Port[FPortAddr] := Value;<br> FData := Value;<br> end;<br>end;<br><br>function TlptCtrl.GetStatus: byte; { read data from LPT status lines }<br>begin<br> if FLpt <> None then<br> begin<br> Result := Port[FPortAddr + 1];<br> end<br> else<br> Result := 0;<br>end;<br><br>function TlptCtrl.GetCtrl: byte;{ to read what was put on the Ctrl lines }<br>begin<br>if FLpt <> None then<br> begin<br> Result := Port[FPortAddr + 2];<br> end<br> else<br> Result := 0;<br>end;<br><br>procedure TlptCtrl.SetCtrl(Value: byte); { put data on Ctrl lines }<br>begin<br> if FLpt <> None then<br> begin<br> Port[FPortAddr + 2] := Value;<br> end;<br>end;<br><br>procedure Register;<br>begin<br> RegisterComponents('I/O', [TlptCtrl]);<br>end;<br><br>{ constructor }<br>constructor TLptCtrl.Create(AOwner: TComponent);<br>begin<br> inherited Create(AOwner);<br> FindLptAddr; (* find available LPT ports *)<br>end;<br><br>{ destructor - just as a placeholder if cleanup will be necessary }<br>destructor TLptCtrl.Destroy;<br>begin<br> inherited Destroy;<br>end;<br><br>end.