delphi7升级到delphi delphi xedelphi xe2总结.docx
- 文档编号:6740412
- 上传时间:2023-05-10
- 格式:DOCX
- 页数:9
- 大小:17.86KB
delphi7升级到delphi delphi xedelphi xe2总结.docx
《delphi7升级到delphi delphi xedelphi xe2总结.docx》由会员分享,可在线阅读,更多相关《delphi7升级到delphi delphi xedelphi xe2总结.docx(9页珍藏版)》请在冰点文库上搜索。
delphi7升级到delphidelphixedelphixe2总结
Delphi7升级到Delphi2010、DelphiXE、DelphiXE2总结.
Delphi7升级到Delphi2010、DelphiXE、DelphiXE2总结.
Delphi7升级到Delphi2010、DelphiXE、DelphiXE2总结
这两天把一个使用Delphi2007成功升级到了Delphi2010。
升级途中很艰辛,总结了以下经验与大家分享。
另外,D7使用的第三方组件,由于官方没有发布ForDelphi2010的更新,修改的第三方组件列表见文章尾部。
1,PChar
因为Delphi不支持无类型指针的算术运算,很多程序员使用PChar来代替Pointer,即使指针指向目标并不是PAnsiChar。
考虑如下代码:
var
P:
PChar;
Buffer:
Pointer;
begin
GetMem(Buffer,255);
P:
=Buffer;
p^:
=#1;Inc(P);
p^:
=#2;
FreeMem(Buffer,255);
end;
在2010中PChar已经不再表示PAnsiChar而是表示PWideChar,如果依然这样写,运行时很可能会得到一个内存访问错误。
因为每次Inc(P),实际上指针向前移动了2字节,因为SizeOf(WideChar)=2,Inc(P)相当于P:
=P+SizeOf(WideChar)。
解决方法是把PChar替换成PAnsiChar2,MoveFillCharCopyMemory
这些函数依赖的是字节长度,往往我们直接使用Length(Str)来获取,这是行不通的。
考虑如下代码:
var
P1,P2:
String;
begin
P1:
='test';
SetLength(P2,Length(P1));
Move(P1[1],P2[1],Length(P1));end
在2010中String默认映射到UnicodeString,单个字符是2字节,所以上文中P1实际占用了8字节内存,而传给Move函数的长度只有4字节,最终结果是P2="te"。
解决办法1:
修改String为AnsiString,该方案虽然可行,但你的程序就享受不到Unicode待遇了。
解决办法2:
SetLength函数不要修改,因为他的长度参数是字符长度,而不是字节长度。
Move函数的最后一个参数Length(P1)修改成Length(P1)*SizeOf(Char)。
注意:
不要偷懒使用万一老师说的ByteLength函数,该函数并没有ForAnsiString的重载,编译器会把参数隐式转化为UnicodeString然后,ByteLength函数计算UnicodeString的长度。
例如:
一旦你不小心传入了一个AnsiString类型长度为4的字符串,函数会返回8,而不是你期望的长度4。
3,Keyin['a'..'z','B','C']
这类代码最好替换成CharInSet(Key,['a'..'z','B','C'])不然会当作AnsiChar处理。
4,WideString
代码中的所有WideString都考虑替换成String,现在WideString只是为了与COM兼容而存在,且没有引用计数,性能低下。
5,Tnt控件
如果你的工程使用了Tnt控件或以前的WideTextPosWideStringReplace之类的东西都替换成标准的吧,不用曲线救国了。
---------经过修改,可以在Delphi2010下运作的第三方组件--------------
1,PNGDelphi
2,EmbeddedWB
3,SynEdit的语法高亮组件unihighlighter
4,JEDIWin32APIHeader这些组件现在可以在Delphi2010下运作了。
6,引用AnsiStrings单元
如果你有必要使用AnsiUpperCaseAnsiLowerCaseAnsiCompareStr之类的函数,一定要引用AnsiStrings单元。
如果你不引用该单元,即便编译不报错,你实际上是用的还是Unicode版本的函数,会有隐式的转化。
不信你打开参数自动完成,看看IDE提示给你的类型是什么?
天啊AnsiLowerCase参数竟然还是String,而不是AnsiString。
看来Delphi2010太迫切的要抛弃Ansi字符串了,以至于你不引用AnsiStrings单元,所有Ansixxxx函数实际上还是Unicode版本。
7,AnsiCopyAnsiPosAnsiDelete
不要用AnsiCopyAnsiPosAnsiDelete,因为CopyPosDelete三个函数已经有了ForAnsi的重载。
8,把Char转化为小写用什么?
答案:
试试看Character单元的新函数ToUpperToLower。
以前我都是用System里面的UpCase函数,现在依然可用不过却找不到LowCaseDownCase之类的函数,困扰我好久好久。
索性全使用Character单元提供的新函数吧。
9,编译期警告:
[DCCWarning]Unit1.pas(31):
W1057Implicitstringcastfrom'AnsiString'to'string'
如果你的代码中包含了两种字符串(Unicode、Ansi)之间进行隐式转化的时候就会出现该提示。
如下代码就会触发该警告:
varUnicode:
String;Ansi:
AnsiString;beginAnsi:
='test..';Unicode:
=Ansi;
把旧版本的Delphi项目升级到2010,我通常都是借助编译警告来快速寻找需要改动的部分。
通常你可以把赋值双方都声明为String(默认影射到UnicodeString),就可以避免该警告。
但如果你确定必须在此处保留Ansi并进行转化的时候,建议你显式的转化他们(例如:
Unicode:
=String(Ansi);),这样可以避免该警告,方便你在升级过程中继续寻找其他需要修改的地方。
10,ReadlnWriteln写入文件时候要注意
如果你传给Writeln一个AnsiString,那么它也会在文件中写入AnsiString,那么你读取得时候就必须传给Readln一个AnsiString的类型,否则就是乱码。
例如旧工程的配置文件是Ansi的,而你已经把相关读取配置的代码升级为支持Unicode,那么运行工程前你首先要用记事本之类的工具把配置文件另存为成Unicode编码。
当然你还要注意跳过Unicode文件头的两个字节FE
FF。
11,别再用String来操作二进制数据了
一定要记住String只是字符串,不要把它当作缓冲区、内存流使用。
我的项目中,有很多地方是使用字符串来处理二进制数据,导致在本次升级中颇为费脑。
如果当时用TBytes或TStream就好了。
反面教材:
varInt1,Int2,Int3,Int4:
Integer;Buf:
String;beginSetLength(Buf,12);Move(Int1,Buf[1],SizeOf(Integer));Move(Int1,Buf[5],SizeOf(Integer));Move(Int1,Buf[9],SizeOf(Integer));Buf:
=Buf+'前面有3个Integer。
';
12,还是PChar
注意在2010中是这样的:
PChar=PointertoaWideChararray;
PAnsiChar=PointertoaAnsiChararray;
如果你还像是在Delphi7中那样:
PChar(AnsiString)那后果过是很严重的。
一段转换例子
D7
unitReCode;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs;
FunctionJiaMi(Src:
String;Key:
String):
String;
FunctionJieMi(Src:
String;Key:
String):
String;
implementation
FunctionJiaMi(Src:
String;Key:
String):
String;
var
KeyLen:
Integer;
KeyPos:
Integer;
offset:
Integer;
dest:
String;
SrcPos:
Integer;
SrcAsc:
Integer;
Range:
Integer;
begin
KeyLen:
=Length(Key);
KeyPos:
=0;
Range:
=1;
Randomize;
offset:
=Random(Range);
dest:
=format('%1.2x',[offset]);
forSrcPos:
=1toLength(Src)do
begin
SrcAsc:
=(Ord(Src[SrcPos])+offset)MOD255;
ifKeyPos<KeyLenthenKeyPos:
=KeyPos+1elseKeyPos:
=1;
SrcAsc:
=SrcAscxorOrd(Key[KeyPos]);
dest:
=dest+format('%1.2x',[SrcAsc]);
offset:
=SrcAsc;
end;
Result:
=Dest;
end;
//解密函数
FunctionJieMi(Src:
String;Key:
String):
String;
var
KeyLen:
Integer;
KeyPos:
Integer;
offset:
Integer;
dest:
String;
SrcPos:
Integer;
SrcAsc:
Integer;
TmpSrcAsc:
Integer;
Range:
Integer;
begin
KeyLen:
=Length(Key);
ifKeyLen=0thenkey:
='starlin';
KeyPos:
=0;
SrcPos:
=0;
SrcAsc:
=0;
Range:
=1;
offset:
=StrToInt('$'+copy(src,1,2));
SrcPos:
=3;
repeat
try
SrcAsc:
=StrToInt('$'+copy(src,SrcPos,2));
except
SrcAsc:
=StrToInt('$00');
end;
ifKeyPos<KeyLenThenKeyPos:
=KeyPos+1elseKeyPos:
=1;
TmpSrcAsc:
=SrcAscxorOrd(Key[KeyPos]);
ifTmpSrcAsc<=offsetthen
TmpSrcAsc:
=255+TmpSrcAsc-offset
else
TmpSrcAsc:
=TmpSrcAsc-offset;
dest:
=dest+chr(TmpSrcAsc);
offset:
=srcAsc;
SrcPos:
=SrcPos+2;
untilSrcPos>=Length(Src);
Result:
=Dest;
Result:
=Copy(Result,1,Length(Result)-1);
end;
end.XE5unitReCode;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,AnsiStrings;
FunctionJiaMi(Src:
String;Key:
String):
String;
FunctionJieMi(Src:
String;Key:
String):
String;
implementation
FunctionJiaMi(Src:
String;Key:
String):
String;
var
KeyLen:
Integer;
KeyPos:
Integer;
offset:
Integer;
dest:
String;
SrcPos:
Integer;
SrcAsc:
Integer;
Range:
Integer;
IntTemp:
integer;
SrcAnsi:
PAnsiChar;
begin
KeyLen:
=Length(Key);
KeyPos:
=0;
Range:
=1;
Randomize;
offset:
=Random(Range);
dest:
=format('%1.2x',[offset]);
SrcAnsi:
=PAnsiChar(AnsiString(Src));
IntTemp:
=Length(SrcAnsi);
forSrcPos:
=1toIntTempdo
begin
SrcAsc:
=(Ord(SrcAnsi[SrcPos-1])+offset)MOD255;
ifKeyPos<KeyLenthenKeyPos:
=KeyPos+1elseKeyPos:
=1;
SrcAsc:
=SrcAscxorOrd(Key[KeyPos]);
dest:
=dest+format('%1.2x',[SrcAsc]);
offset:
=SrcAsc;
end;
Result:
=Dest;
end;
//解密函数
FunctionJieMi(Src:
String;Key:
String):
String;
var
KeyLen:
Integer;
KeyPos:
Integer;
offset:
Integer;
dest:
String;
SrcPos:
Integer;
SrcAsc:
Integer;
TmpSrcAsc:
Integer;
Range:
Integer;
SrcAnsi:
PAnsiChar;
IntTemp,i:
Integer;
ByteArray:
arrayofByte;
begin
KeyLen:
=Length(Key);
ifKeyLen=0thenkey:
='starlin';
KeyPos:
=0;
SrcPos:
=0;
SrcAsc:
=0;
Range:
=1;
offset:
=StrToInt('$'+copy(src,1,2));
SrcPos:
=3;
IntTemp:
=Length(Src)div2;
setlength(ByteArray,IntTemp);
i:
=0;
repeat
try
SrcAsc:
=StrToInt('$'+copy(src,SrcPos,2));
except
SrcAsc:
=StrToInt('$00');
end;
ifKeyPos<KeyLenThenKeyPos:
=KeyPos+1elseKeyPos:
=1;
TmpSrcAsc:
=SrcAscxorOrd(Key[KeyPos]);
ifTmpSrcAsc<=offsetthen
TmpSrcAsc:
=255+TmpSrcAsc-offset
else
TmpSrcAsc:
=TmpSrcAsc-offset;
ByteArray[i]:
=TmpSrcAsc;
i:
=i+1;
offset:
=srcAsc;
SrcPos:
=SrcPos+2;
untilSrcPos>=Length(Src);
CopyMemory(@SrcAnsi[0],@ByteArray[0],IntTemp);
dest:
=string(AnsiStrings.strpas(SrcAnsi));
Result:
=Dest;
end;
end.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- delphi7升级到delphi delphi xedelphi xe2总结 delphi7 升级 xe2 总结