已经在用的节选 library TonyDLL;{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }uses SysUtils, Windows, Classes, Graphics; Type TSimpleComm = Packed Record CommName : Pchar; BaudRate : Dword; //current baud rate ByteSize : Byte; // number of bits/byte, 4-8 Parity : Byte; // 0-4=no,odd,even,,space StopBits : Byte; // 0,1,2 = 1, 1.5, 2 end;{$R *.res}Function OpenComm(SimpleComm:TSimpleComm;var CommHandle:Thandle):Byte;stdcall; var DCB:TDCB; begin Result:=0; CommHandle := CreateFile(SimpleComm.CommName, Generic_Read Or Generic_Write, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0); //Generic_Read or Generic_Write, 0,nil,Open_Existing,File_Attribute_Normal,0 if CommHandle =INVALID_HANDLE_VALUE then begin Result:=9; Exit; end; if not SetupComm(CommHandle,1024,1024) then begin CloseHandle(CommHandle); Result:=11; Exit; end; if not PurgeComm(CommHandle,Purge_TXClear or Purge_RXClear or Purge_RXAbort or Purge_TxAbort)then begin Result:=14; exit; end; If not GetCommState(CommHandle,DCB) then begin CloseHandle(Commhandle); Result:=12; Exit; end; DCB.BaudRate := SimpleComm.BaudRate ; DCB.ByteSize := SimpleComm.ByteSize ; DCB.StopBits := SimpleComm.StopBits ; DCB.Parity := SimpleComm.Parity ; If not SetCommState(CommHandle,DCB) then begin CloseHandle(Commhandle); Result:=13; Exit; end; end;Function ReadLongCom(Const CommHandle:THandle; Var DataBlk:TDataBlock; var DataSize:LongWord; Const TimeOutSec:Byte; Var ErrorVal:Byte):Boolean;stdcall; var ComStat:TComStat; Time:TDateTime; Comm_Read_Bytes:LongWord; Buf:Byte; begin Result:=true; ErrorVal:=0; Time:=now+TimeOutSec/(3600*24); DataSize:=0; if not chkdog then begin Result:=false; ErrorVal:=71; exit; end; While true do begin ClearCommError(Commhandle,Comm_Read_Bytes,@Comstat); if Comstat.cbInQue = 0 then begin If Time < Now then begin Result:=false; ErrorVal:=10; Break; end else begin continue; sleep(1); end; end; //the cbInQue > 1 the Time:=now+TimeOutSec/(3600*24); //reset the timeout begin inc(DataSize); Setlength(DataBlk,DataSize); Result:=ReadFile(commhandle,Buf,1,Comm_Read_Bytes,nil); if not Result then begin Errorval:=15; Break end; DataBlk[DataSize-1]:=buf; if buf = 27 then //识别结束,或者是操作字符 begin Result:=ReadFile(commhandle,Buf,1,Comm_Read_Bytes,nil); if not Result then begin Errorval:=15; Break; end; if buf <> 27 then begin inc(DataSize); Setlength(DataBlk,DataSize); DataBlk[DataSize-1]:=buf; if buf =3 then Break; end; end; end; if Result then begin if DataBlk[1] = 21 then begin Result:=false; Errorval := DataBlk[3]; end; end; end; exports Opencomm; begin end.
[email protected]
能用控件吗?
如SPCOMM
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;const
Wm_commNotify=Wm_User+12;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
Procedure comminitialize;
Procedure MsgcommProcess(Var
Message:Tmessage); Message Wm_commnotify;
{ Private declarations }
public
{ Public declarations }
end; //线程声明
TComm=Class(TThread)
protected
procedure Execute;override;
end;var
Form1: TForm1;
hcom,Post_Event:Thandle;
lpol:Poverlapped;
implementation{$R *.DFM}Procedure TComm.Execute; //线程执行过程
var
dwEvtMask:Dword;
Wait:Boolean;
Begin
fillchar(lpol,sizeof(toverlapped),0);
While True do Begin
dwEvtMask:=0;
Wait:=WaitCommEvent(hcom,dwevtmask,lpol);
//等待串行口事件;
if Wait Then Begin
waitforsingleobject(post_event,infinite);
//等待同步事件置位;
resetevent(post_event); //同步事件复位;
PostMessage(Form1.Handle,
WM_COMMNOTIFY,0,0);//发送消息;
end;
end;
end;procedure Tform1.comminitialize;
//串行口初始化
var
lpdcb:Tdcb;
Begin
hcom:=createfile('com2',generic_read or
generic_write,0,nil,open_existing,
file_attribute_normal or
file_flag_overlapped,0);//打开串行口
if hcom=invalid_handle_value then
else
setupcomm(hcom,4096,4096);
//设置输入,输出缓冲区皆为4096字节
getcommstate(hcom,lpdcb);
//获取串行口当前默认设置
lpdcb.baudrate:=2400;
lpdcb.StopBits:=1;
lpdcb.ByteSize:=8;
lpdcb.Parity:=EvenParity; //偶校验
Setcommstate(hcom,lpdcb);
setcommMask(hcom,ev_rxchar);
//指定串行口事件为接收到字符;
end;Procedure TForm1.Msgcomm
Process(Var Message:Tmessage);
var
Clear:Boolean;
Coms:Tcomstat;
cbNum,ReadNumber,lpErrors:Integer;
Read_Buffer:array[1..100]of char;
Begin
Clear:=Clearcommerror(hcom,lpErrors,@Coms);
if Clear Then Begin
cbNum:=Coms.cbInQue;
ReadFile(hCom,Read_Buffer,
cbNum,ReadNumber,lpol);
//处理接收数据
SetEvent(Post_Event);
//同步事件置位
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
comminitialize;
post_event:=CreateEvent
(nil,true,true,nil); //创建同步事件;
Tcomm.Create(False);
//创建串行口监视线程;
end;end.
自己改一下
vc++的盘上就有
一、函数声明:procedure PostPara(port:integer;syspara:pchar);stdcall;external 'lock739.dll';
function Reset:integer; stdcall;external 'lock739.dll';
function OpenCom:boolean;stdcall;external 'lock739.dll';
procedure CloseCom;stdcall;external 'lock739.dll';
function ChkCard:integer;stdcall;external 'lock739.dll';
function CmpSc(sc:pchar):integer;stdcall;external 'lock739.dll';
function WriteSc(sc:pchar):integer;stdcall;external 'lock739.dll';
function ReadSc(inbuff:pchar;sclen:integer):integer;stdcall; external 'lock739.dll';
function RdDat(cardtype,start,len:integer;inbuff:pchar):integer;stdcall; external 'lock739.dll';
function WrDat(cardtype,start,len:integer;outbuff:pchar):integer;stdcall;external 'lock739.dll'; 二、源码节选: unit fMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,ExtCtrls,ComCtrls ;
type
TForm1 = class(TForm)
RG1: TRadioGroup;
StatusBar1: TStatusBar;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Label3: TLabel;
Label4: TLabel;
procedure FormShow(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure RG1Click(Sender: TObject);
private
{ Private declarations }
public
sc:array[0..3] of char; //存储卡密码;
iStart,iLen:integer; //读写卡起始地址及读写字节长度;
Procedure ErrorMessage(iError:integer); //显示错误信息
{ Public declarations }
end; var
Form1: TForm1;
implementation
uses DllDef; //接口函数声明;
{$R *.DFM}
procedure TForm1.FormShow(Sender: TObject);
begin
//卡密码3个Byte:
sc[0]:=chr(strtoint('$FF'));
sc[1]:=chr(strtoint('$FF'));
sc[2]:=chr(strtoint('$FF'));
//传入读写器使用串口
PostPara(RG1.ItemIndex+1,NIL);
end; procedure TForm1.Button3Click(Sender: TObject);
begin
Application.Terminate;
end; //读到卡数据
procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
str1:array[0..255] of char; //存储读取的卡数据
str2:string;
begin
try
iStart:=strtoint(Edit2.Text);
iLen:=strtoint(edit3.Text);
except
Application.MessageBox('请正确输入读写起始地址和长度!','提示信息',64);
StatusBar1.Panels[1].Text:='';
Exit;
end; //打开串口
if not OpenCom() then begin
Application.MessageBox('串口连接失败!','提示信息',64);
StatusBar1.Panels[1].Text:='';
Exit;
end;
//检查卡是否到位
i:=ChkCard();
if (i<>0) then begin
ErrorMessage(i);
StatusBar1.Panels[1].Text:='';
CloseCom();
Exit;
end;
//读卡信息;
i:=RdDat(1,iStart,iLen,str1);
if (i<>0) then begin
ErrorMessage(i);
CloseCom();
Exit;
end;
for i:=0 to iLen-1 do
str2:=str2+str1[i];
StatusBar1.Panels[1].Text:=str2;
end; //写卡数据
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
try
iStart:=strtoint(Edit2.Text);
iLen:=strtoint(edit3.Text);
except
Application.MessageBox('请正确输入读写起始地址和长度!','提示信息',64);
StatusBar1.Panels[1].Text:='';
Exit;
end; //打开串口
if not OpenCom() then begin
Application.MessageBox('串口连接失败!','提示信息',64);
StatusBar1.Panels[1].Text:='';
Exit;
end;
//检查卡是否到位
i:=ChkCard();
if (i<>0) then begin
ErrorMessage(i);
StatusBar1.Panels[1].Text:='';
CloseCom();
Exit;
end;
//核对卡密码
i:=CmpSc(sc);
if (i<>0) then begin
ErrorMessage(i);
CloseCom();
Exit;
end;
i:=WrDat(1,iStart,iLen,pchar(edit1.Text));
if (i<>0) then begin
ErrorMessage(i);
CloseCom();
Exit;
end
else begin
Application.MessageBox('写卡成功!','提示信息',64);
CloseCom();
end;
end; procedure TForm1.RG1Click(Sender: TObject);
begin
PostPara(RG1.ItemIndex+1,NIL);
end; procedure TForm1.ErrorMessage(iError:integer);
begin
case iError of
1: Application.MessageBox('写入错误或密码错误','提示信息',64);
2: Application.MessageBox('卡已损坏或参数越界','提示信息',64);
3: Application.MessageBox('请插卡!','提示信息',64);
4: Application.MessageBox('通信错误!','提示信息',64)
else
Application.MessageBox('未知错误!','提示信息',64);
end;
end;
end.
If .PortOpen = True Then .PortOpen = False
.CommPort = 1 '这里是串口号
.Settings = "9600,N,8,1" '设置参数
.InputLen = 0
.InputMode = comInputModeBinary ' 以二进制的方式读入
.PortOpen = True '打开串口
.RThreshold = 83 '当缓冲区接受大于设置时引起ONCOMM事件
End With
然后:
Public Sub DoComPort(oComm As MSComm)
Dim InString As Variant
InString = oComm.Input '这里的InStrig 是读入的东西了
End Sub
library TonyDLL;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Windows,
Classes,
Graphics;
Type
TSimpleComm = Packed Record
CommName : Pchar;
BaudRate : Dword; //current baud rate
ByteSize : Byte; // number of bits/byte, 4-8
Parity : Byte; // 0-4=no,odd,even,,space
StopBits : Byte; // 0,1,2 = 1, 1.5, 2
end;{$R *.res}Function OpenComm(SimpleComm:TSimpleComm;var CommHandle:Thandle):Byte;stdcall;
var
DCB:TDCB;
begin
Result:=0;
CommHandle := CreateFile(SimpleComm.CommName,
Generic_Read Or Generic_Write,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,0);
//Generic_Read or Generic_Write, 0,nil,Open_Existing,File_Attribute_Normal,0
if CommHandle =INVALID_HANDLE_VALUE then
begin
Result:=9;
Exit;
end;
if not SetupComm(CommHandle,1024,1024) then
begin
CloseHandle(CommHandle);
Result:=11;
Exit;
end;
if not PurgeComm(CommHandle,Purge_TXClear or Purge_RXClear or
Purge_RXAbort or Purge_TxAbort)then
begin
Result:=14;
exit;
end;
If not GetCommState(CommHandle,DCB) then
begin
CloseHandle(Commhandle);
Result:=12;
Exit;
end;
DCB.BaudRate := SimpleComm.BaudRate ;
DCB.ByteSize := SimpleComm.ByteSize ;
DCB.StopBits := SimpleComm.StopBits ;
DCB.Parity := SimpleComm.Parity ;
If not SetCommState(CommHandle,DCB) then
begin
CloseHandle(Commhandle);
Result:=13;
Exit;
end;
end;Function ReadLongCom(Const CommHandle:THandle;
Var DataBlk:TDataBlock;
var DataSize:LongWord;
Const TimeOutSec:Byte;
Var ErrorVal:Byte):Boolean;stdcall;
var
ComStat:TComStat;
Time:TDateTime;
Comm_Read_Bytes:LongWord;
Buf:Byte;
begin
Result:=true;
ErrorVal:=0;
Time:=now+TimeOutSec/(3600*24);
DataSize:=0;
if not chkdog then
begin
Result:=false;
ErrorVal:=71;
exit;
end;
While true do
begin
ClearCommError(Commhandle,Comm_Read_Bytes,@Comstat);
if Comstat.cbInQue = 0 then
begin
If Time < Now then
begin
Result:=false;
ErrorVal:=10;
Break;
end
else
begin
continue;
sleep(1);
end;
end;
//the cbInQue > 1 the
Time:=now+TimeOutSec/(3600*24); //reset the timeout begin
inc(DataSize);
Setlength(DataBlk,DataSize);
Result:=ReadFile(commhandle,Buf,1,Comm_Read_Bytes,nil);
if not Result then
begin
Errorval:=15;
Break
end;
DataBlk[DataSize-1]:=buf;
if buf = 27 then //识别结束,或者是操作字符
begin
Result:=ReadFile(commhandle,Buf,1,Comm_Read_Bytes,nil);
if not Result then
begin
Errorval:=15;
Break;
end;
if buf <> 27 then
begin
inc(DataSize);
Setlength(DataBlk,DataSize);
DataBlk[DataSize-1]:=buf;
if buf =3 then
Break;
end;
end;
end;
if Result then
begin
if DataBlk[1] = 21 then
begin
Result:=false;
Errorval := DataBlk[3];
end;
end;
end;
exports
Opencomm;
begin
end.