6
631229
Unregistered / Unconfirmed
GUEST, unregistred user!
我的简单编辑器可以编辑文本文件和EQ文件。EQ文件是File Of TEQ,关于TEQ的定义请看
程序。TEQConversion重载了TConversion的ConvertReadStream和ConvertWriteStream
函数,经运行ConvertReadStream函数没有问题,能显示EQ文件的内容,但存盘时死机,说
明ConvertWriteStream函数有问题,调试时发现到了ConvertWriteStream函数的第一
条Val语句时就死机。请各位大侠看这个ConvertWriteStream函数该如何写?
unit EditUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, StdCtrls, ComCtrls;
type
TEditForm = class(TForm)
MainMenu1: TMainMenu;
FileMenu: TMenuItem;
FileOpenItem: TMenuItem;
FileCloseItem: TMenuItem;
RichEdit1: TRichEdit;
OpenDialog: TOpenDialog;
procedure FileOpenItemClick(Sender: TObject);
procedure FileCloseItemClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type EarthQuake_Date_Time_Magnitude_Depth=Int64;
//地震的日期、时间、震级及震级类型、震源深度组成一个64位整数,其中:年为
//Smallint占16位,月占4位,日占5位,时占5位,分占6位,秒占10位(秒以整数
//存放不含小数点,如432代表43.2秒;深度占10位,震级占7位,震级类型占1位。
type EarthQuake_Longtitude=Smallint;
//震中经度(不含小数点,如11293代表112.93)占两个字节;
type EarthQuake_Latitude=Smallint;
// 震中纬度(不含小数点,如2818代表28.18度)占两个字节;
type EarthQuake_Serial_Accuracy=Smallint;
//序列号13位,精度3位组成一个Smallint;
//以上共14个字节组成一条地震事件记录。
type TEQ=Packed Record
EQDTMD:EarthQuake_Date_Time_Magnitude_Depth;
EQLon:EarthQuake_Longtitude;
EQLat:EarthQuake_Latitude;
EQSA:EarthQuake_Serial_Accuracy;
end;
type
TEQConversion = class(TConversion)
public
function ConvertReadStream(Stream:TStream; BufferChar;
BufSize:integer): integer; override;
function ConvertWriteStream(Stream:TStream; BufferChar;
BufSize:integer): integer; override;
end;
type
Teq2=Record
nian:smallint;
yue,ri,shi,fen:Byte;
weidu:smallint;
jingdu:smallint;
Ms,miao:Byte;
shendu:smallint;
serial:smallint;
end;
var
EditForm: TEditForm;
Const
TwoPower56:Int64=72057594037927936;
TwoPower48:Int64=281474976710656
TwoPower44:Int64=17592186044416
TwoPower40:Int64=1099511627776;
TwoPower39:Int64=549755813888
TwoPower34:Int64=17179869184
TwoPower32:Int64=4294967296;
TwoPower28:Int64=268435456
TwoPower24:Int64=16777216;
TwoPower18:Int64=262144
TwoPower16:Int64=65536;
TwoPower8:Int64=256
//以上常数是2的各次幂
implementation
{$R *.DFM}
procedure TEditForm.FormCreate(Sender: TObject);
begin
Richedit1.RegisterConversionFormat('EQ',TEQConversion);
end;
procedure TEditForm.FileOpenItemClick(Sender: TObject);
begin
OpenDialog.Execute;
Richedit1.Lines.LoadFromFile(OpenDialog.FileName);
Caption:=OpenDialog.FileName;
end;
procedure TEditForm.FileCloseItemClick(Sender: TObject);
begin
Richedit1.Lines.SaveToFile(Caption);
end;
function TEQConversion.ConvertReadStream(Stream:TStream; BufferChar;
BufSize:integer): integer;
var s:string;
buf:array[1..14] of char;
n:integer;
TempLonLat:Smallint;
ComplexRec:Int64;
begin
Result := 0;
s:='';
n := Stream.Read(buf,14);
if n = 0 then Exit;
ComplexRec:=(Int64(Ord(buf[8])) shl 56)+(Int64(Ord(buf[7])) shl 48)+
(Int64(Ord(buf[6])) shl 40)+(Int64(Ord(buf[5])) shl 32)+
(Int64(Ord(buf[4])) shl 24)+(Int64(Ord(buf[3])) shl 16)+
(Int64(Ord(buf[2])) shl 8)+Int64(Ord(buf[1]));
AppendStr(s,StringOfChar(' ',4-length(IntToStr(ComplexRec shr 48)))+IntToStr(ComplexRec shr 48)+',');
//ComplexRec shr 48为年的值
if length(IntToStr((ComplexRec And (TwoPower48-1)) shr 44))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower48-1)) shr 44)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower48-1)) shr 44)+',');
//(ComplexRec And (TwoPower48-1)) shr 44为月的值
if length(IntToStr((ComplexRec And (TwoPower44-1)) shr 39))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower44-1)) shr 39)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower44-1)) shr 39)+',');
//(ComplexRec And (TwoPower44-1)) shr 39为日的值
if length(IntToStr((ComplexRec And (TwoPower39-1)) shr 34))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower39-1)) shr 34)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower39-1)) shr 34)+',');
//(ComplexRec And (TwoPower39-1)) shr 34为时的值
if length(IntToStr((ComplexRec And (TwoPower34-1)) shr 28))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower34-1)) shr 28)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower34-1)) shr 28)+',');
//(ComplexRec And (TwoPower34-1)) shr 28为分的值
AppendStr(s,StringOfChar(' ',4-length(FloatToStr(((ComplexRec And (TwoPower28-1)) shr 18)/10)))+FloatToStr(((ComplexRec And (TwoPower28-1)) shr 18)/10)+',');
//((ComplexRec And (TwoPower28-1)) shr 18)/10为秒的值
TempLonLat:=256*Ord(buf[10])+Ord(buf[9]);
AppendStr(s,StringOfChar(' ',7-length(FloatToStr(TempLonLat/100)))+FloatToStr(TempLonLat/100)+',');
//256*Ord(buf[10])+Ord(buf[9])为经度的值*100
TempLonLat:=256*Ord(buf[12])+Ord(buf[11]);
AppendStr(s,StringOfChar(' ',6-length(FloatToStr(TempLonLat/100)))+FloatToStr(TempLonLat/100)+',');
//256*Ord(buf[12])+Ord(buf[11])为纬度的值*100
AppendStr(s,StringOfChar(' ',3-length(FloatToStr(((ComplexRec And (TwoPower8-1)) shr 1)/10)))+FloatToStr(((ComplexRec And (TwoPower8-1)) shr 1)/10)+',');
//((ComplexRec And (TwoPower8-1)) shr 1)/10为震级的值
AppendStr(s,IntToStr(ComplexRec And 1)+',');
//ComplexRec And 1为震级类型的值
AppendStr(s,StringOfChar(' ',3-length(IntToStr((ComplexRec And (TwoPower18-1)) shr 8)))+IntToStr((ComplexRec And (TwoPower18-1)) shr 8)+',');
//(ComplexRec And (TwoPower18-1)) shr 8为深度的值
AppendStr(s,StringOfChar(' ',3-Length(IntToStr((256*(Ord(buf[14]))+Ord(buf[13])) shr 3)))+IntToStr((256*(Ord(buf[14]))+Ord(buf[13])) shr 3)+',');
//(256*(Ord(buf[14]))+Ord(buf[13]))) shr 3为序列号的值
AppendStr(s,IntToStr((Ord(buf[13])) And 7));
//(Ord(buf[13])) And 7为精度的值
AppendStr(s,#13#10);
StrPCopy(Buffer,s);
Result := length(s);
end;
function TEQConversion.ConvertWriteStream(Stream:TStream; BufferChar;
BufSize:integer): integer;
var s:string;
buf:String[54];
n,code:integer;
EQ2Rec:TEQ2;
ComplexRec:Int64;
begin
Result := 0;
s:='';
n := Stream.Write(buf,54);
if n = 0 then Exit;
Val(Copy(buf,1,4),EQ2Rec.nian,code);
Val(Copy(buf,6,2),EQ2Rec.yue,code);
Val(Copy(buf,9,2),EQ2Rec.ri,code);
Val(Copy(buf,12,2),EQ2Rec.shi,code);
Val(Copy(buf,15,2),EQ2Rec.fen,code);
if pos('.',Copy(buf,18,4))=0 then Val(Copy(buf,18,4),EQ2Rec.miao,code)
else Val(Copy(buf,18,2)+Copy(buf,21,1),EQ2Rec.miao,code);
Val(Copy(buf,23,pos('.',Copy(buf,23,7))-1)+Copy(buf,23+pos('.',Copy(buf,23,7)),7-pos('.',Copy(buf,23,7))),EQ2Rec.jingdu,code);
Val(Copy(buf,31,pos('.',Copy(buf,31,6))-1)+Copy(buf,31+pos('.',Copy(buf,31,6)),6-pos('.',Copy(buf,31,6))),EQ2Rec.weidu,code);
if pos('.',Copy(buf,38,3))=0 then Val(Copy(buf,38,3),EQ2Rec.Ms,code)
else Val(Copy(buf,38,1)+Copy(buf,40,1),EQ2Rec.Ms,code);
Val(Copy(buf,44,3),EQ2Rec.shendu,code);
Val(Copy(buf,48,3),EQ2Rec.serial,code);
With EQ2Rec do
begin
ComplexRec:=nian*TwoPower48+Yue*TwoPower44+Ri*TwoPower39+ Shi*TwoPower34+Fen*TwoPower28+10*Miao*TwoPower18+Shendu*TwoPower8+2*Ms;
end;
AppendStr(s,chr(ComplexRec And (TwoPower8-1)));
AppendStr(s,chr((ComplexRec And (TwoPower16-1)) shr 8));
AppendStr(s,chr((ComplexRec And (TwoPower24-1)) shr 16));
AppendStr(s,chr((ComplexRec And (TwoPower32-1)) shr 24));
AppendStr(s,chr((ComplexRec And (TwoPower40-1)) shr 32));
AppendStr(s,chr((ComplexRec And (TwoPower48-1)) shr 40));
AppendStr(s,chr((ComplexRec And (TwoPower56-1)) shr 48));
AppendStr(s,chr(ComplexRec shr 56));
AppendStr(s,chr((EQ2Rec.jingdu) And (TwoPower8-1)));
AppendStr(s,chr((EQ2Rec.jingdu) shr 8));
AppendStr(s,chr((EQ2Rec.weidu) And (TwoPower8-1)));
AppendStr(s,chr((EQ2Rec.weidu) shr 8));
AppendStr(s,chr(((EQ2Rec.serial)*8) And (TwoPower8-1)));
AppendStr(s,chr(((EQ2Rec.serial)*8) shr 8));
StrPCopy(Buffer,s);
Result := length(s);
end;
end.
程序。TEQConversion重载了TConversion的ConvertReadStream和ConvertWriteStream
函数,经运行ConvertReadStream函数没有问题,能显示EQ文件的内容,但存盘时死机,说
明ConvertWriteStream函数有问题,调试时发现到了ConvertWriteStream函数的第一
条Val语句时就死机。请各位大侠看这个ConvertWriteStream函数该如何写?
unit EditUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, StdCtrls, ComCtrls;
type
TEditForm = class(TForm)
MainMenu1: TMainMenu;
FileMenu: TMenuItem;
FileOpenItem: TMenuItem;
FileCloseItem: TMenuItem;
RichEdit1: TRichEdit;
OpenDialog: TOpenDialog;
procedure FileOpenItemClick(Sender: TObject);
procedure FileCloseItemClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type EarthQuake_Date_Time_Magnitude_Depth=Int64;
//地震的日期、时间、震级及震级类型、震源深度组成一个64位整数,其中:年为
//Smallint占16位,月占4位,日占5位,时占5位,分占6位,秒占10位(秒以整数
//存放不含小数点,如432代表43.2秒;深度占10位,震级占7位,震级类型占1位。
type EarthQuake_Longtitude=Smallint;
//震中经度(不含小数点,如11293代表112.93)占两个字节;
type EarthQuake_Latitude=Smallint;
// 震中纬度(不含小数点,如2818代表28.18度)占两个字节;
type EarthQuake_Serial_Accuracy=Smallint;
//序列号13位,精度3位组成一个Smallint;
//以上共14个字节组成一条地震事件记录。
type TEQ=Packed Record
EQDTMD:EarthQuake_Date_Time_Magnitude_Depth;
EQLon:EarthQuake_Longtitude;
EQLat:EarthQuake_Latitude;
EQSA:EarthQuake_Serial_Accuracy;
end;
type
TEQConversion = class(TConversion)
public
function ConvertReadStream(Stream:TStream; BufferChar;
BufSize:integer): integer; override;
function ConvertWriteStream(Stream:TStream; BufferChar;
BufSize:integer): integer; override;
end;
type
Teq2=Record
nian:smallint;
yue,ri,shi,fen:Byte;
weidu:smallint;
jingdu:smallint;
Ms,miao:Byte;
shendu:smallint;
serial:smallint;
end;
var
EditForm: TEditForm;
Const
TwoPower56:Int64=72057594037927936;
TwoPower48:Int64=281474976710656
TwoPower44:Int64=17592186044416
TwoPower40:Int64=1099511627776;
TwoPower39:Int64=549755813888
TwoPower34:Int64=17179869184
TwoPower32:Int64=4294967296;
TwoPower28:Int64=268435456
TwoPower24:Int64=16777216;
TwoPower18:Int64=262144
TwoPower16:Int64=65536;
TwoPower8:Int64=256
//以上常数是2的各次幂
implementation
{$R *.DFM}
procedure TEditForm.FormCreate(Sender: TObject);
begin
Richedit1.RegisterConversionFormat('EQ',TEQConversion);
end;
procedure TEditForm.FileOpenItemClick(Sender: TObject);
begin
OpenDialog.Execute;
Richedit1.Lines.LoadFromFile(OpenDialog.FileName);
Caption:=OpenDialog.FileName;
end;
procedure TEditForm.FileCloseItemClick(Sender: TObject);
begin
Richedit1.Lines.SaveToFile(Caption);
end;
function TEQConversion.ConvertReadStream(Stream:TStream; BufferChar;
BufSize:integer): integer;
var s:string;
buf:array[1..14] of char;
n:integer;
TempLonLat:Smallint;
ComplexRec:Int64;
begin
Result := 0;
s:='';
n := Stream.Read(buf,14);
if n = 0 then Exit;
ComplexRec:=(Int64(Ord(buf[8])) shl 56)+(Int64(Ord(buf[7])) shl 48)+
(Int64(Ord(buf[6])) shl 40)+(Int64(Ord(buf[5])) shl 32)+
(Int64(Ord(buf[4])) shl 24)+(Int64(Ord(buf[3])) shl 16)+
(Int64(Ord(buf[2])) shl 8)+Int64(Ord(buf[1]));
AppendStr(s,StringOfChar(' ',4-length(IntToStr(ComplexRec shr 48)))+IntToStr(ComplexRec shr 48)+',');
//ComplexRec shr 48为年的值
if length(IntToStr((ComplexRec And (TwoPower48-1)) shr 44))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower48-1)) shr 44)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower48-1)) shr 44)+',');
//(ComplexRec And (TwoPower48-1)) shr 44为月的值
if length(IntToStr((ComplexRec And (TwoPower44-1)) shr 39))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower44-1)) shr 39)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower44-1)) shr 39)+',');
//(ComplexRec And (TwoPower44-1)) shr 39为日的值
if length(IntToStr((ComplexRec And (TwoPower39-1)) shr 34))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower39-1)) shr 34)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower39-1)) shr 34)+',');
//(ComplexRec And (TwoPower39-1)) shr 34为时的值
if length(IntToStr((ComplexRec And (TwoPower34-1)) shr 28))=2 then
AppendStr(s,IntToStr((ComplexRec And (TwoPower34-1)) shr 28)+',')
else AppendStr(s,'0'+IntToStr((ComplexRec And (TwoPower34-1)) shr 28)+',');
//(ComplexRec And (TwoPower34-1)) shr 28为分的值
AppendStr(s,StringOfChar(' ',4-length(FloatToStr(((ComplexRec And (TwoPower28-1)) shr 18)/10)))+FloatToStr(((ComplexRec And (TwoPower28-1)) shr 18)/10)+',');
//((ComplexRec And (TwoPower28-1)) shr 18)/10为秒的值
TempLonLat:=256*Ord(buf[10])+Ord(buf[9]);
AppendStr(s,StringOfChar(' ',7-length(FloatToStr(TempLonLat/100)))+FloatToStr(TempLonLat/100)+',');
//256*Ord(buf[10])+Ord(buf[9])为经度的值*100
TempLonLat:=256*Ord(buf[12])+Ord(buf[11]);
AppendStr(s,StringOfChar(' ',6-length(FloatToStr(TempLonLat/100)))+FloatToStr(TempLonLat/100)+',');
//256*Ord(buf[12])+Ord(buf[11])为纬度的值*100
AppendStr(s,StringOfChar(' ',3-length(FloatToStr(((ComplexRec And (TwoPower8-1)) shr 1)/10)))+FloatToStr(((ComplexRec And (TwoPower8-1)) shr 1)/10)+',');
//((ComplexRec And (TwoPower8-1)) shr 1)/10为震级的值
AppendStr(s,IntToStr(ComplexRec And 1)+',');
//ComplexRec And 1为震级类型的值
AppendStr(s,StringOfChar(' ',3-length(IntToStr((ComplexRec And (TwoPower18-1)) shr 8)))+IntToStr((ComplexRec And (TwoPower18-1)) shr 8)+',');
//(ComplexRec And (TwoPower18-1)) shr 8为深度的值
AppendStr(s,StringOfChar(' ',3-Length(IntToStr((256*(Ord(buf[14]))+Ord(buf[13])) shr 3)))+IntToStr((256*(Ord(buf[14]))+Ord(buf[13])) shr 3)+',');
//(256*(Ord(buf[14]))+Ord(buf[13]))) shr 3为序列号的值
AppendStr(s,IntToStr((Ord(buf[13])) And 7));
//(Ord(buf[13])) And 7为精度的值
AppendStr(s,#13#10);
StrPCopy(Buffer,s);
Result := length(s);
end;
function TEQConversion.ConvertWriteStream(Stream:TStream; BufferChar;
BufSize:integer): integer;
var s:string;
buf:String[54];
n,code:integer;
EQ2Rec:TEQ2;
ComplexRec:Int64;
begin
Result := 0;
s:='';
n := Stream.Write(buf,54);
if n = 0 then Exit;
Val(Copy(buf,1,4),EQ2Rec.nian,code);
Val(Copy(buf,6,2),EQ2Rec.yue,code);
Val(Copy(buf,9,2),EQ2Rec.ri,code);
Val(Copy(buf,12,2),EQ2Rec.shi,code);
Val(Copy(buf,15,2),EQ2Rec.fen,code);
if pos('.',Copy(buf,18,4))=0 then Val(Copy(buf,18,4),EQ2Rec.miao,code)
else Val(Copy(buf,18,2)+Copy(buf,21,1),EQ2Rec.miao,code);
Val(Copy(buf,23,pos('.',Copy(buf,23,7))-1)+Copy(buf,23+pos('.',Copy(buf,23,7)),7-pos('.',Copy(buf,23,7))),EQ2Rec.jingdu,code);
Val(Copy(buf,31,pos('.',Copy(buf,31,6))-1)+Copy(buf,31+pos('.',Copy(buf,31,6)),6-pos('.',Copy(buf,31,6))),EQ2Rec.weidu,code);
if pos('.',Copy(buf,38,3))=0 then Val(Copy(buf,38,3),EQ2Rec.Ms,code)
else Val(Copy(buf,38,1)+Copy(buf,40,1),EQ2Rec.Ms,code);
Val(Copy(buf,44,3),EQ2Rec.shendu,code);
Val(Copy(buf,48,3),EQ2Rec.serial,code);
With EQ2Rec do
begin
ComplexRec:=nian*TwoPower48+Yue*TwoPower44+Ri*TwoPower39+ Shi*TwoPower34+Fen*TwoPower28+10*Miao*TwoPower18+Shendu*TwoPower8+2*Ms;
end;
AppendStr(s,chr(ComplexRec And (TwoPower8-1)));
AppendStr(s,chr((ComplexRec And (TwoPower16-1)) shr 8));
AppendStr(s,chr((ComplexRec And (TwoPower24-1)) shr 16));
AppendStr(s,chr((ComplexRec And (TwoPower32-1)) shr 24));
AppendStr(s,chr((ComplexRec And (TwoPower40-1)) shr 32));
AppendStr(s,chr((ComplexRec And (TwoPower48-1)) shr 40));
AppendStr(s,chr((ComplexRec And (TwoPower56-1)) shr 48));
AppendStr(s,chr(ComplexRec shr 56));
AppendStr(s,chr((EQ2Rec.jingdu) And (TwoPower8-1)));
AppendStr(s,chr((EQ2Rec.jingdu) shr 8));
AppendStr(s,chr((EQ2Rec.weidu) And (TwoPower8-1)));
AppendStr(s,chr((EQ2Rec.weidu) shr 8));
AppendStr(s,chr(((EQ2Rec.serial)*8) And (TwoPower8-1)));
AppendStr(s,chr(((EQ2Rec.serial)*8) shr 8));
StrPCopy(Buffer,s);
Result := length(s);
end;
end.