现代工厂里最实用的控件---- ( 积分: 50 )

  • 主题发起人 主题发起人 懒少爷
  • 开始时间 开始时间

懒少爷

Unregistered / Unconfirmed
GUEST, unregistred user!
序列号生成器----为什么是现代工厂里最实用的控件?因为现代产品都有序列号,你必须要产生序列号呀!
呵呵,其实我是想问问题的-----
第一次写控件,很多糗在里面滴,大家指点错误之处,帮忙改好它,可在我大富翁的BLOG里留言
我主要的问题是:如何在产生序列号过程中终断它执行?如何去做这个方法?并产生一个终止的事件?

{*************************************************}
{ Serial Number generator Version 0.5 }
{ 序列号生成器 0.5 }
{ (但在组件里取了个奇怪的名,我也不知怎么回事了) }
{ Developed by:懒少爷 }
{欢迎使用,版权不留 但你不可以用于商业目的出售的 }
{如你在此基础上开发了新版本给一份我呀! }
{ 请到我的大富翁BLOG里留言就可以了 }
{简介: }
{只有三个属性:StartSN,EndSN,SNseed }
{ 分别为开始,结束号和序列号的种子 }
{两个方法:getTotalSN ---获取所有序列号个数 }
{ Start---------生成序列号 }
{一个事件:onNewSNComing---每产生一个序列号触发一次}
{同时返回该序列号 }
{*************************************************}
unit CMultiDigits;

interface

uses
SysUtils, Classes,Math;

type
TOnNewSNComeEvent=procedure(Sender:Tobject;SN:string) of object;

TCMultiDigits = class(Tcomponent)
private
{ Private declarations }
FSNseed:string;
FStartSN:string;
FEndSN:string;
FOnNewSN:TOnNewSNComeEvent;
procedure setSNS(S:string);
procedure setStartSN(S:string);
procedure setEndSN(S:string);
procedure GenNewSN(SN:string);
protected
{ Protected declarations }
function MyPower(a,b:integer): integer;
function RightAt(S,C:string):integer;
function ConvNto10(SN,SNSeed:string):integer;
function Conv10toN(N:integer;SNSeed:string):string;
function Dec2N(n:integer;SNseed:string):string;
function N2Dec(sn,SNseed:string):integer;
function VerifySENo(Sn,SNseed:string):boolean; //verify start and end number
function VerifyOverall:boolean;
function IsCharDup(S:string):boolean; //is any char duplicate in string?
procedure DoOnNewSNComing(SN:string);

public
{ Public declarations }
constructor Create( AOwner: TComponent );override;
destructor Destroy;override;

published
{ Published declarations }
property SNSeed:string read FSNseed write setSNS;
property StartSN:string read FStartSN write setStartSN;
property EndSN:string read FEndSN write setEndSN;
property OnNewSNComing:TOnNewSNComeEvent read FOnNewSN write FOnNewSN;
procedure Start;
function getTotalSN:integer;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TCMultiDigits]);
end;

constructor TCMultiDigits.create(AOwner: TComponent);
begin
inherited Create( AOwner );
end;
destructor TCMultiDigits.destroy;
begin
inherited destroy;
end;
function TCMultiDigits.RightAt(S:string;C:string):integer;
var i:integer;
begin
result:=0;
for i:=length(S) downto 1 do
begin
if copy(S,i,1)=C then
begin
result:=i;
break;
end;
end;
end;
function TCMultiDigits.ConvNto10(SN:string;SNSeed:string):integer;
begin
//convert other system value to decimal value (one digital,no carry)
result:=pos(SN,SNSeed)-1;
end;
function TCMultiDigits.Conv10toN(N:integer;SNSeed:string):string;
begin
//convert decimal value to other system value (one digital)
if N>length(SNSeed) then
begin
//application.MessageBox('Invalid serial number!','Error',mb_ok+mb_iconerror);
exception.Create('Invalid serial number!');
result:='-1';
end;
result:=copy(SNSeed,N+1,1);
end;
function TCMultiDigits.Dec2N(n:integer;SNseed:string):string;
var CarryNum,Quotient,i,j:integer;
A:array of integer;
Vresult:string;
begin
CarryNum:=length(SNseed);
setlength(A,1);
Quotient:=n;
i:=0;
while true do
begin
if n=0 then
begin
A:=0;
break;
end;
A:=Quotient mod CarryNum;
Quotient:=floor(Quotient/CarryNum);
if Quotient<CarryNum then
begin
if Quotient<>0 then
begin
inc(i);
setlength(A,i+1); //expand the array
A:=Quotient;
end;
break;
end;
inc(i);
setlength(A,i+1);
end;
Vresult:='';
for j:=i downto 0 do
begin
Vresult:=Vresult+conv10toN(A[j],SNseed);
end;
result:=Vresult;
end;
function TCMultiDigits.N2Dec(sn,SNseed:string):integer;
var
HMD,CarryNum,i,Vresult:integer;
A:array of string;
begin
CarryNum:=length(SNseed);
HMD:=length(SN); //How Many Digital
if HMD=0 then
begin
result:=-1; //error handle
exit;
end;
setlength(A,HMD); //every digital....
for i:=0 to HMD-1 do
begin
A:=copy(SN,i+1,1);
if pos(A,SNseed)=0 then
begin
result:=-1;
exit;
end;
end;
Vresult:=0;
for i:=0 to HMD-1 do
begin
Vresult:=Vresult+ConvNto10(A,SNseed)*MyPower(CarryNum,HMD-1-i);
end;
result:=Vresult;
end;
function TCMultiDigits.MyPower(a,b: integer): integer;
var x,y:integer;
begin
x:=a;
if b=0 then
begin
result:=1;
end else
begin
if b=1 then result:=a else
begin
for y:=1 to b-1 do
x:=x*a;
result:=x;
end;
end;
end;
procedure TCMultiDigits.setSNS(S:string);
begin
if IsCharDup(S) then
begin
raise exception.Create('Duplicate char in SNseed!');
end else
FSNseed:=S;
end;
procedure TCMultiDigits.setStartSN(S:string);
begin
FStartSN:=S;
end;
procedure TCMultiDigits.setEndSN(S:string);
begin
FEndSN:=S;
end;
function TCMultiDigits.getTotalSN:integer;
begin
if VerifyOverall then
result:=N2Dec(EndSN,SNseed)-N2Dec(StartSN,SNseed)
else
result:=-1;
end;
procedure TCMultiDigits.GenNewSN(SN:string);
var s:string;
begin
s:=dec2N(n2dec(SN,SNSeed)+1,SNSeed);
DoOnNewSNComing(s);
if S<>FEndSN then
GenNewSN(s)
else
exit;
end;
procedure TCMultiDigits.DoOnNewSNComing(SN:string);
begin
if assigned(FOnNewSN) then
FOnNewSN(self,SN);
end;
procedure TCMultiDigits.Start;
//var i:integer;
begin
if VerifyOverall then
GenNewSN(FStartSN);
end;
function TCMultiDigits.VerifySENo(SN,SNseed:string):boolean;
var HMD,i:integer;
A:array of string;
begin
//Èç·´»ØFALSE,ÔòÓÐ×Ö·û²»ÔÚSNseedÀï,²»ÄÜÔËÐÐ
HMD:=length(SN); //How Many Digital
setlength(A,HMD); //every digital....
for i:=0 to HMD-1 do
begin
A:=copy(SN,i+1,1);
if pos(A,SNseed)=0 then
begin
result:=false;
exit;
end;
end;
result:=true;
end;
function TCMultiDigits.VerifyOverall:boolean;
begin

if (StartSN='') or (EndSN='') or (SNSeed='') then
begin
raise exception.Create('SNseed or StartSN or EndSN did not assign value!');
result:=false;
exit;
end;
if not verifySENo(StartSN,SNseed) then
begin
raise exception.Create('StartSN is invalid!');
result:=false;
exit;
end;
if not verifySENo(EndSN,SNseed) then
begin
raise exception.Create('EndSN is invalid!');
result:=false;
exit;
end;
if N2Dec(EndSN,SNSeed)-N2Dec(StartSN,SNseed)<0 then
begin
raise exception.Create('EndSN can not small than StartSN!');
result:=false;
exit;
end;
result:=true;
end;
function TCMultiDigits.IsCharDup(s:string):boolean;
var i:integer;
begin
for i:=0 to length(S)-1 do
begin
if pos(s,copy(s,i+1,length(S)-i))>0 then
begin
result:=true;
exit;
end;
end;
result:=false;
end;
end.
 
序列号生成器----为什么是现代工厂里最实用的控件?因为现代产品都有序列号,你必须要产生序列号呀!
呵呵,其实我是想问问题的-----
第一次写控件,很多糗在里面滴,大家指点错误之处,帮忙改好它,可在我大富翁的BLOG里留言
我主要的问题是:如何在产生序列号过程中终断它执行?如何去做这个方法?并产生一个终止的事件?

{*************************************************}
{ Serial Number generator Version 0.5 }
{ 序列号生成器 0.5 }
{ (但在组件里取了个奇怪的名,我也不知怎么回事了) }
{ Developed by:懒少爷 }
{欢迎使用,版权不留 但你不可以用于商业目的出售的 }
{如你在此基础上开发了新版本给一份我呀! }
{ 请到我的大富翁BLOG里留言就可以了 }
{简介: }
{只有三个属性:StartSN,EndSN,SNseed }
{ 分别为开始,结束号和序列号的种子 }
{两个方法:getTotalSN ---获取所有序列号个数 }
{ Start---------生成序列号 }
{一个事件:onNewSNComing---每产生一个序列号触发一次}
{同时返回该序列号 }
{*************************************************}
unit CMultiDigits;

interface

uses
SysUtils, Classes,Math;

type
TOnNewSNComeEvent=procedure(Sender:Tobject;SN:string) of object;

TCMultiDigits = class(Tcomponent)
private
{ Private declarations }
FSNseed:string;
FStartSN:string;
FEndSN:string;
FOnNewSN:TOnNewSNComeEvent;
procedure setSNS(S:string);
procedure setStartSN(S:string);
procedure setEndSN(S:string);
procedure GenNewSN(SN:string);
protected
{ Protected declarations }
function MyPower(a,b:integer): integer;
function RightAt(S,C:string):integer;
function ConvNto10(SN,SNSeed:string):integer;
function Conv10toN(N:integer;SNSeed:string):string;
function Dec2N(n:integer;SNseed:string):string;
function N2Dec(sn,SNseed:string):integer;
function VerifySENo(Sn,SNseed:string):boolean; //verify start and end number
function VerifyOverall:boolean;
function IsCharDup(S:string):boolean; //is any char duplicate in string?
procedure DoOnNewSNComing(SN:string);

public
{ Public declarations }
constructor Create( AOwner: TComponent );override;
destructor Destroy;override;

published
{ Published declarations }
property SNSeed:string read FSNseed write setSNS;
property StartSN:string read FStartSN write setStartSN;
property EndSN:string read FEndSN write setEndSN;
property OnNewSNComing:TOnNewSNComeEvent read FOnNewSN write FOnNewSN;
procedure Start;
function getTotalSN:integer;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TCMultiDigits]);
end;

constructor TCMultiDigits.create(AOwner: TComponent);
begin
inherited Create( AOwner );
end;
destructor TCMultiDigits.destroy;
begin
inherited destroy;
end;
function TCMultiDigits.RightAt(S:string;C:string):integer;
var i:integer;
begin
result:=0;
for i:=length(S) downto 1 do
begin
if copy(S,i,1)=C then
begin
result:=i;
break;
end;
end;
end;
function TCMultiDigits.ConvNto10(SN:string;SNSeed:string):integer;
begin
//convert other system value to decimal value (one digital,no carry)
result:=pos(SN,SNSeed)-1;
end;
function TCMultiDigits.Conv10toN(N:integer;SNSeed:string):string;
begin
//convert decimal value to other system value (one digital)
if N>length(SNSeed) then
begin
//application.MessageBox('Invalid serial number!','Error',mb_ok+mb_iconerror);
exception.Create('Invalid serial number!');
result:='-1';
end;
result:=copy(SNSeed,N+1,1);
end;
function TCMultiDigits.Dec2N(n:integer;SNseed:string):string;
var CarryNum,Quotient,i,j:integer;
A:array of integer;
Vresult:string;
begin
CarryNum:=length(SNseed);
setlength(A,1);
Quotient:=n;
i:=0;
while true do
begin
if n=0 then
begin
A:=0;
break;
end;
A:=Quotient mod CarryNum;
Quotient:=floor(Quotient/CarryNum);
if Quotient<CarryNum then
begin
if Quotient<>0 then
begin
inc(i);
setlength(A,i+1); //expand the array
A:=Quotient;
end;
break;
end;
inc(i);
setlength(A,i+1);
end;
Vresult:='';
for j:=i downto 0 do
begin
Vresult:=Vresult+conv10toN(A[j],SNseed);
end;
result:=Vresult;
end;
function TCMultiDigits.N2Dec(sn,SNseed:string):integer;
var
HMD,CarryNum,i,Vresult:integer;
A:array of string;
begin
CarryNum:=length(SNseed);
HMD:=length(SN); //How Many Digital
if HMD=0 then
begin
result:=-1; //error handle
exit;
end;
setlength(A,HMD); //every digital....
for i:=0 to HMD-1 do
begin
A:=copy(SN,i+1,1);
if pos(A,SNseed)=0 then
begin
result:=-1;
exit;
end;
end;
Vresult:=0;
for i:=0 to HMD-1 do
begin
Vresult:=Vresult+ConvNto10(A,SNseed)*MyPower(CarryNum,HMD-1-i);
end;
result:=Vresult;
end;
function TCMultiDigits.MyPower(a,b: integer): integer;
var x,y:integer;
begin
x:=a;
if b=0 then
begin
result:=1;
end else
begin
if b=1 then result:=a else
begin
for y:=1 to b-1 do
x:=x*a;
result:=x;
end;
end;
end;
procedure TCMultiDigits.setSNS(S:string);
begin
if IsCharDup(S) then
begin
raise exception.Create('Duplicate char in SNseed!');
end else
FSNseed:=S;
end;
procedure TCMultiDigits.setStartSN(S:string);
begin
FStartSN:=S;
end;
procedure TCMultiDigits.setEndSN(S:string);
begin
FEndSN:=S;
end;
function TCMultiDigits.getTotalSN:integer;
begin
if VerifyOverall then
result:=N2Dec(EndSN,SNseed)-N2Dec(StartSN,SNseed)
else
result:=-1;
end;
procedure TCMultiDigits.GenNewSN(SN:string);
var s:string;
begin
s:=dec2N(n2dec(SN,SNSeed)+1,SNSeed);
DoOnNewSNComing(s);
if S<>FEndSN then
GenNewSN(s)
else
exit;
end;
procedure TCMultiDigits.DoOnNewSNComing(SN:string);
begin
if assigned(FOnNewSN) then
FOnNewSN(self,SN);
end;
procedure TCMultiDigits.Start;
//var i:integer;
begin
if VerifyOverall then
GenNewSN(FStartSN);
end;
function TCMultiDigits.VerifySENo(SN,SNseed:string):boolean;
var HMD,i:integer;
A:array of string;
begin
//Èç·´»ØFALSE,ÔòÓÐ×Ö·û²»ÔÚSNseedÀï,²»ÄÜÔËÐÐ
HMD:=length(SN); //How Many Digital
setlength(A,HMD); //every digital....
for i:=0 to HMD-1 do
begin
A:=copy(SN,i+1,1);
if pos(A,SNseed)=0 then
begin
result:=false;
exit;
end;
end;
result:=true;
end;
function TCMultiDigits.VerifyOverall:boolean;
begin

if (StartSN='') or (EndSN='') or (SNSeed='') then
begin
raise exception.Create('SNseed or StartSN or EndSN did not assign value!');
result:=false;
exit;
end;
if not verifySENo(StartSN,SNseed) then
begin
raise exception.Create('StartSN is invalid!');
result:=false;
exit;
end;
if not verifySENo(EndSN,SNseed) then
begin
raise exception.Create('EndSN is invalid!');
result:=false;
exit;
end;
if N2Dec(EndSN,SNSeed)-N2Dec(StartSN,SNseed)<0 then
begin
raise exception.Create('EndSN can not small than StartSN!');
result:=false;
exit;
end;
result:=true;
end;
function TCMultiDigits.IsCharDup(s:string):boolean;
var i:integer;
begin
for i:=0 to length(S)-1 do
begin
if pos(s,copy(s,i+1,length(S)-i))>0 then
begin
result:=true;
exit;
end;
end;
result:=false;
end;
end.
 
看看再说
 
function TCMultiDigits.VerifySENo(SN,SNseed:string):boolean;
var HMD,i:integer;
A:array of string;
begin
//Èç·´»ØFALSE,ÔòÓÐ×Ö·û²»ÔÚSNseedÀï,²»ÄÜÔËÐÐ


乱码?
 
to royal1442:
那是中文注释,COPY过来就变乱码了,无所谓的..............
 
后退
顶部