
- 又 称
- 专家规定程序调查法
- 基本特点
- 匿名性
- 拟定调查表
- 调查者
- 中文名
- 德尔菲法
- 性 质
- 反馈匿名函询法
- 外文名
- Delphi Method
-
Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结
2017-08-23 09:59:16这两天把一个使用Delphi2007成功升级到了Delphi2010。升级途中很艰辛,总结了 以下经验与大家分享。另外,D7使用的第三方组件,由于官方没有发布For Delphi2010的更新,修改的第三 方组件列表见文章尾部。 1,...
这两天把一个使用Delphi2007成功升级到了Delphi2010。升级途中很艰辛,总结了 以下经验与大家分享。另外,D7使用的第三方组件,由于官方没有发布For Delphi2010的更新,修改的第三 方组件列表见文章尾部。
1,PChar
因为Delphi不支持无类型指针的算术运算,很多程序员使用 PChar来代替Pointer,即使指针指向目标并不是PAnsiChar。
考虑如下代码:
在2010中PChar已经不再表示PAnsiChar而是表示PWideChar,如果依然这样写,运行时很可能会得到一个内存访问错误。因为每 次Inc(P),实际上指针向前移动了2字节,因为SizeOf(WideChar)=2,Inc(P)相当于 P:=P+SizeOf(WideChar)。
解决方法是把PChar替换成PAnsiChar
2,Move FillChar CopyMemory
这些函数依赖的是字节长度,往往我们直接使用Length(Str)来获取,这是行不通的。
考虑如下代码:
在2010中String默认映射到UnicodeString,单个字符是2字节,所以上文中P1实际占用了8字节内存,而传给Move函数的长 度只有4字节,最终结果是P2="te"。
解决办法1:
修改String为AnsiString,该方案虽然可行,但你的程序就享受不到Unicode待遇了。
解决办法2:
SetLength 函数不要修改,因为他的长度参数是字符长度,而不是字节长度。
Move函数的最后一个参数 Length(P1) 修改成 Length(P1)*SizeOf(Char)。
注意:不要偷懒使用万一老师说的ByteLength函数,该函数并没有For AnsiString的重载,编译器会 把参数隐式转化为UnicodeString然后,ByteLength函数计算UnicodeString的长度。例如:一旦你不小心传入了一个 AnsiString类型长度为4的字符串,函数会返回8,而不是你期望的长度4。
3,Key in ['a'..'z','B','C']
这类代码最好替换成CharInSet(Key,['a'..'z','B','C']) 不然会当作AnsiChar处理。
4,WideString
代码中的所有WideString都考虑替换成String,现在 WideString只是为了与COM兼容而存在,且没有引用计数,性能低下。
5,Tnt控件
如果你的工程使用了Tnt控件或以前的WideTextPos WideStringReplace之类的东西都替换成标准的吧,不用曲线救国了。
---------经过修改,可以在Delphi2010下运作的第三方组件--------------
1,PNGDelphi
2,EmbeddedWB
3,SynEdit的语法高亮组件 unihighlighter
4,JEDI Win32API Header
这些组件现在可以在Delphi2010下运作了。
6,引用AnsiStrings单元
如果你有必要使用 AnsiLowerCase AnsiCompareStr之类的函数,一定要引用AnsiStrings单元。
如果你不引用该单元,即便编译不报错,你实际上是用的还是Unicode版本的函数,会有隐式的转化。不信你打开参数自动完成,看看IDE提示给你的类型是什么?天啊AnsiLowerCase参数竟然还是String,而不是AnsiString。看来Delphi2010太迫切的要抛弃Ansi字符串了,以至于你不引用AnsiStrings单元,所有Ansixxxx函数实际上还是Unicode版本。
7,AnsiCopy AnsiPos AnsiDelete
不要用AnsiCopy AnsiPos AnsiDelete,因为Copy Pos Delete三个函数已经有了For Ansi的重载。
8,把Char转化为小写用什么?
答案:试试看Character单元的新函数 ToUpper ToLower。以前我都是用System里面的UpCase函数,现在依然可用不过却找不到LowCase DownCase之类的函数,困扰我好久好久。索性全使用Character单元提供的新函数吧。
9,编译期警告:[DCC Warning] Unit1.pas(31): W1057 Implicit string cast from 'AnsiString' to 'string'
如果你的代码中包含了两种字符串(Unicode、Ansi)之间进行隐式转化的时候就会出现该提示。
如下代码就会触发该警告:
var Unicode:String; Ansi:AnsiString; begin Ansi:='test..'; Unicode:=Ansi;
把旧版本的Delphi项目升级到2010,我通常都是借助编译警告来快速寻找需要改动的部分。通常你可以把赋值双方都声明为String(默认影射到UnicodeString),就可以避免该警告。但如果你确定必须在此处保留Ansi并进行转化的时候,建议你显式的转化他们(例如:Unicode:=String(Ansi);),这样可以避免该警告,方便你在升级过程中继续寻找其他需要修改的地方。
10,Readln Writeln 写入文件时候要注意
如果你传给Writeln一个AnsiString,那么它也会在文件中写入AnsiString,那么你读取得时候就必须传给Readln一个AnsiString的类型,否则就是乱码。例如旧工程的配置文件是Ansi的,而你已经把相关读取配置的代码升级为支持Unicode,那么运行工程前你首先要用记事本之类的工具把配置文件另存为成Unicode编码。当然你还要注意跳过Unicode文件头的两个字节FE FF。
11,别再用String来操作二进制数据了
一定要记住String只是字符串,不要把它当作缓冲区、内存流使用。我的项目中,有很多地方是使用字符串来处理二进制数据,导致在本次升级中颇为费脑。如果当时用TBytes或TStream就好了。
反面教材:
var Int1,Int2,Int3,Int4:Integer; Buf:String; begin SetLength(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= Pointer to a WideChar array;
PAnsiChar = Pointer to a AnsiChar array;
如果你还像是在Delphi 7中那样:PChar(AnsiString)那后果过是很严重的。
一段转换例子D7unit
ReCode;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
Function
JiaMi(Src:
String
; Key:
String
):
String
;
Function
JieMi(Src:
String
; Key:
String
):
String
;
implementation
Function
JiaMi(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]);
for
SrcPos :=
1
to
Length(Src)
do
begin
SrcAsc:=(Ord(Src[SrcPos]) + offset)
MOD
255
;
if
KeyPos < KeyLen
then
KeyPos:= KeyPos +
1
else
KeyPos:=
1
;
SrcAsc:= SrcAsc
xor
Ord(Key[KeyPos]);
dest:=dest + format(
'%1.2x'
,[SrcAsc]);
offset:=SrcAsc;
end
;
Result:=Dest;
end
;
//解密函数
Function
JieMi (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);
if
KeyLen =
0
then
key:=
'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
;
if
KeyPos < KeyLen
Then
KeyPos := KeyPos +
1
else
KeyPos :=
1
;
TmpSrcAsc := SrcAsc
xor
Ord(Key[KeyPos]);
if
TmpSrcAsc <= offset
then
TmpSrcAsc :=
255
+ TmpSrcAsc - offset
else
TmpSrcAsc := TmpSrcAsc - offset;
dest := dest + chr(TmpSrcAsc);
offset:=srcAsc;
SrcPos:=SrcPos +
2
;
until
SrcPos >= Length(Src);
Result:=Dest;
Result:=Copy(Result,
1
,Length(Result)-
1
);
end
;
end
.
XE5
unit
ReCode;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,AnsiStrings;
Function
JiaMi(Src:
String
; Key:
String
):
String
;
Function
JieMi(Src:
String
; Key:
String
):
String
;
implementation
Function
JiaMi(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);
for
SrcPos :=
1
to
IntTemp
do
begin
SrcAsc:=(Ord(SrcAnsi[SrcPos-
1
]) + offset)
MOD
255
;
if
KeyPos < KeyLen
then
KeyPos:= KeyPos +
1
else
KeyPos:=
1
;
SrcAsc:= SrcAsc
xor
Ord(Key[KeyPos]);
dest:=dest + format(
'%1.2x'
,[SrcAsc]);
offset:=SrcAsc;
end
;
Result:=Dest;
end
;
//解密函数
Function
JieMi (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:
array
of
Byte
;
begin
KeyLen:=Length(Key);
if
KeyLen =
0
then
key:=
'starlin'
;
KeyPos:=
0
;
SrcPos:=
0
;
SrcAsc:=
0
;
Range:=
1
;
offset:=StrToInt(
'$'
+ copy(src,
1
,
2
));
SrcPos:=
3
;
IntTemp:=Length(Src)
div
2
;
setlength(ByteArray,IntTemp);
i:=
0
;
repeat
try
SrcAsc:=StrToInt(
'$'
+ copy(src,SrcPos,
2
));
except
SrcAsc:=StrToInt(
'$00'
);
end
;
if
KeyPos < KeyLen
Then
KeyPos := KeyPos +
1
else
KeyPos :=
1
;
TmpSrcAsc := SrcAsc
xor
Ord(Key[KeyPos]);
if
TmpSrcAsc <= offset
then
TmpSrcAsc :=
255
+ TmpSrcAsc - offset
else
TmpSrcAsc := TmpSrcAsc - offset;
ByteArray[i]:=TmpSrcAsc;
i:=i+
1
;
offset:=srcAsc;
SrcPos:=SrcPos +
2
;
until
SrcPos >= Length(Src);
CopyMemory(@SrcAnsi[
0
],@ByteArray[
0
],IntTemp);
dest:=
string
(AnsiStrings
.
strpas(SrcAnsi));
Result:=Dest;
end
;
end
.
-
Delphi 二维码生成
2014-05-19 16:51:32Delphi 调用ZINT 库 生成二维码, 非常简单 -
sip delphi demo 只要delphi 的
2016-07-27 03:01:16哪位大侠有sip的代码? 要Delphi的,俺知识面不广,只会Delphi -
delphi 10.4来了
2020-06-09 20:09:19RAD Studio 10.4是多年来对Delphi代码工具的最大,最大的改进,它使用语言服务器协议(LSP)的Delphi实现提供了Code Insight。LSP是一种在单独的过程中计算代码完成,导航或类似结果的技术。这意味着IDE不会在完成时...RAD Studio 10.4新功能
一、Delphi的新功能
1、Delphi Code Insight的重大改进
RAD Studio 10.4是多年来对Delphi代码工具的最大,最大的改进,它使用语言服务器协议(LSP)的Delphi实现提供了Code Insight。LSP是一种在单独的过程中计算代码完成,导航或类似结果的技术。这意味着IDE不会在完成时阻塞,并且Code Insight将提供准确的结果。在处理具有数百万行代码的大型项目时,10.4可大大提高开发人员的工作效率。
2、Delphi的新语言功能:自定义托管记录
作为Delphi语言的主要语言,Delphi记录类型现在支持自定义初始化,终结和复制操作。开发人员现在可以通过编写将在各个步骤执行的代码来定制记录的创建,复制和销毁方式。这为Delphi中的记录增加了附加功能,Delphi是一种与类相比可实现更高效率的构造。
3、统一内存管理
现在,Delphi内存管理使用对象内存管理的经典实现在所有受支持的平台(移动,桌面和服务器)之间进行了统一。与自动引用计数(ARC)相比,它与现有代码更好地兼容,并且为组件,库和最终用户应用程序提供了更简单的编码。ARC模型保留用于所有平台的字符串管理和接口类型引用。
对于C ++,此更改意味着C ++中的Delphi样式类的创建和删除与所有堆分配的C ++类一样,遵循正常的内存管理,从而大大降低了复杂性。
二、新的C ++ Builder功能
1、扩展的C ++库支持
在10.4中,我们已经将众多流行的C ++库移植到C ++ Builder中,从而为在C ++ Builder中使用提供了优化的支持。这包括ZeroMQ,SDL2,SOCI,libSIMDpp和Nematode等库,以及已经受支持的其他库(例如Eigen),可通过GetIt程序包管理器下载这些库。
2、Win 64-C ++调试和链接器
10.4引入了一个新的Windows 64位C ++调试器。该调试器基于LLDB,在调试64位应用程序时引入了显着的稳定性改进,以及一项关键的新功能,可帮助评估和检查C ++和Delphi字符串等类型以及包括std :: vector和std :: map等在内的STL集合。 。此外,为应用程序生成的调试信息使用其他调试格式。最终结果是更稳定,功能更丰富的调试体验,以及在调试时进行更强大的检查和评估。
3、工具链性能和质量改进
Dinkumware对STL进行了大量改进
基于为提高与通用C ++库的兼容性所做的工作,改进了几个关键的RTL方法和领域
CMake支持的几项改进
大量改善质量和稳定性
三、VCL Windows的新功能
1、高DPI的VCL样式更改
在10.4版中,VCL样式体系结构已得到显着扩展,以支持High DPI和4K监视器。现在,VCL表单上的所有UI控件都会自动缩放,以适合显示该表单的监视器的正确分辨率。
样式API已经过全面修订,以支持高DPI样式。可以从多尺度版本的库中选择每个UI元素,并缩放到任何DPI,从而在所有监视器上显示清晰的UI元素。
2、新的高DPI样式
我们已经更新了大量的内置和高级VCL样式,以支持新的High-DPI样式模式,使您可以为任何显示器设计视觉效果出色的应用程序。
3、VCL每个控件样式
VCL开发人员现在可以在一个应用程序中使用不同形式的多种VCL样式,甚至可以使用同一形式的不同可视控件。这还包括支持使用默认平台主题样式化任何元素。除了在样式上提供更大的灵活性之外,这还使您能够在样式化的VCL应用程序中使用第三方未样式化的控件。
4、新的VCL组件:边缘浏览器控件
10.4包括一个新的VCL Web浏览器组件TEdgeBrowser,它使用Microsoft的基于Chromium的新Edge WebView2。与旧的基于Internet Explorer的TWebBrowser相比,它提供了更加现代的HTML引擎和安全的HTML引擎。
此外,经典的TWebBrowser组件已得到扩展,允许现有应用程序中的浏览器控件使用现有Internet Explorer或Edge浏览器进行显示,具体取决于系统上可用的浏览器。
5、新的VCL组件:TTitleBarPanel和自定义标题栏
新的TTitleBarPanel控件和TForm.CustomTitleBar属性允许您自定义VCL表单的本机Windows标题栏。您可以将VCL控件放置在Windows标题栏上,控制元素的默认绘制,例如窗口图标和标题,在“最小化”,“最大化”和“关闭”按钮附近添加新的自定义系统按钮,甚至完全自定义绘制标题栏。这使您能够构建现代的增强标题栏,类似于Office,Explorer,Google Chrome或其他应用程序。
6、新的VCL组件:具有多分辨率支持的图像组件
有一个新的TVirtualImage组件,它支持多种分辨率和DPI缩放比例,使您可以通过替换经典的TImage组件来获得高质量的图像缩放比例和显示。
7、Windows API更新
我们增强了许多API声明并添加了其他声明,以进一步改善RAD Studio提供的出色平台集成。
四、FireMonkey平台的主要增强功能
1、Metal驱动程序对macOS和iOS的GPU支持:在macOS平台(Delphi)上,您现在可以针对Metal API而不是旧的Quartz API和OpenGL(Apple弃用)构建应用程序。FireMonkey Metal支持为将来的需求提供了平稳的迁移,并为屏幕渲染提供了更好的性能。在10.4中,我们还添加了对iOS(Delphi和C ++ Builder)上的Metal API的支持。
2、除了支持最新的iOS SDK,使用RAD Studio 10.4的开发人员还可以通过内置的IDE支持来满足Apple新的启动屏幕故事板要求。
3、此版本包括Windows平台上样式为TMemo组件的新FMX实现,为IME提供了更好的支持和其他增强功能。
4、Enterprise和Architect Edition客户可以利用FMXLinux集成来构建Linux GUI应用程序。
5、iOS的TWebBrowser控件现在使用WKWebView API实现
6、Media Player控件的macOS实现现已使用AVFoundation
7、使用FireMonkey框架的开发人员可以针对支持的操作系统的最新版本。
五、关键运行时库增强
1、增强的并行编程库支持:并行编程库(PPL)使您的应用程序能够在现代多核CPU中并行运行任务。在10.4中,我们对PPL库进行了许多性能和稳定性增强。
2、在10.4中,我们对FireDAC数据库访问库进行了一些常规增强,并更新了FireBird,PostgreSQL和SQLite的驱动程序。对于SQLite嵌入式数据库,我们现在提供了在静态或动态链接之间进行选择的功能。
3、我们使用其他HTTPS功能扩展了HTTP和REST客户端库,并扩展了对Amazon AWS服务的支持。
4、LiveBindings性能和功能增强
在10.4中,我们对VCL和FireMonkey应用程序的Visual LiveBindings体系结构和实现进行了许多增强,尤其着重于性能。结果,某些LiveBindings操作的速度提高了一个数量级。
其他改进包括绑定到TDataSet的VCL和FMX控件自动适应关联的TField属性(如DisplayWidth,Alignment和EditMask)的功能。
六、IDE的主要增强功能
1、GetIt软件包管理器增强功能
IDE中的GetIt软件包管理器在10.4中进行了重大改进。这包括显示每个程序包的发布日期,并可以按发布日期对它们进行排序;已安装软件包的新过滤选项,更新订阅客户可用的专有内容,可用更新的软件包;和更多。
2、用于在线和离线安装的统一安装程序
在10.4中,我们将使用GetIt安装程序技术引入统一的安装程序。这提供了一个单一安装程序,该安装程序同时支持联机(通过Internet连接)安装和脱机安装(通过ISO)。现在,在线安装和离线安装都允许您选择要安装的RAD Studio初始功能集,例如对编程语言和目标平台的特定组合的支持,语言支持或帮助资源,并可以随时添加或删除它们。
3、代码编辑器在生产率方面进行了几项改进,包括新设置,例如编辑器状态栏上的文件代码页和字体大小。
4、IDE和键对话框使用新的TCustomTitleBar控件在标题栏上实现搜索和设置,从而启用本机外观和Windows DWM行为。
功能特色
1、使用RAD Studio 设计漂亮的桌面和移动应用程序UI
您准备好设计一生中最好的UI了吗?我们屡获殊荣的Windows VCL框架和适用于跨平台UI的FireMonkey(FMX)可视框架为您提供了直观,美观的用户界面的基础,这些界面在每个平台(Windows,macOS,iOS,Android和Linux)上都可以使用。
一次快速设计您的主响应式UI布局,然后轻松自定义特定于平台和设备的视图,而无需重复设计工作。
使用我们的视觉设计器,可以轻松地从面板中拖放视觉和非视觉组件。
使用LiveBindings Designer将用户界面元素可视地连接到数据源。
使用实时设备上预览实时设计验证,以将活动表单同时广播到多个设备。
通过适用于台式机,平板电脑和智能手机的分辨率识别组件添加响应式设计。
特定于平台的真实本机控件,可改善用户体验。
2、使用RAD Studio更快,更聪明地编码
聪明的开发人员和敏捷软件团队使用现代的OOP实践以及RAD Studio的强大框架和功能丰富的IDE可以更快地编写更好的代码。
我们为每个平台使用高度优化的编译器,花费更少的时间等待冗长的编译。
从两种功能强大的语言(Delphi和增强的C ++)中进行选择,并自定义IDE以符合您的编码风格。
Code Insight™通过基于您的代码和使用过的库的现代语言服务器协议提供代码完成功能,以帮助您快速而准确地进行编码。
编写代码时,请从内联文档中获取提示和技巧。
使用VCL设计器,敏捷重构和实时模板,使您的开发保持敏捷。
与版本控制系统集成,包括Git,Subversion和Mercurial。
3、使用RAD Studio的集成本机调试更快地进行调试
集成的跨平台本机调试可更快地找到错误的根源。使用RAD Studio IDE,您可以调试在Windows,macOS,iOS,Android和Linux上远程运行的应用程序!
添加条件断点以在指定位置或发生特定条件时快速暂停程序执行。
浏览整个调用堆栈,以便您可以向后追溯以发现执行代码到达当前位置所采用的路线。
在调试期间程序暂停时检查变量的当前值。
调试时可以使用Code Insight™代码完成功能。
在任何设备上调试!将您的应用程序部署到任何iOS,Android,macOS或Linux设备上,并像在本地运行一样进行调试。在所有部署平台上进行实时调试,在本地和远程计算机上使用断点,堆栈探索,工具提示和表达式评估。
4、使用RAD Studio进行编译和部署
通过为他们的首选设备创建应用来吸引用户。使用RAD Studio从一个代码库创建桌面和移动应用程序,并部署到Windows,macOS,iOS,Android和Linux!
临时到App Store。快速生成可捆绑到Windows Store(使用桌面桥),Apple App Store和Google Play Store的应用程序捆绑包。
定义文件以按平台部署并构建配置。开发人员可以根据目标平台(例如Windows,macOS,Android,iOS,Linux)和构建配置(例如Debug或Release)识别每个项目中要部署的文件。
通过Delphi IDE轻松将文件直接部署到Windows,macOS,Android,iOS和Linux。直接从RAD Studio IDE部署文件。使用Platform Assistant服务器(PA Server)将文件快速部署到远程计算机。PA Server组合了为部署定义的文件,并将它们打包到一个应用程序实例中。
5、使用RAD Studio提高代码质量
更快的开发周期不必牺牲质量!RAD Studio包含许多功能,可帮助实施编码最佳实践,减少重复工作并帮助您成为编码巨星!
快速错误洞察会自动在代码中标记错误,并帮助您解决它们。
内置的重构使您可以简化,简化和提高应用程序代码的性能和可读性。
利用经过测试和高度优化的跨平台库,快速构建更好的代码。
将您的代码文档转变为您或团队中其他开发人员可以使用的即时内联帮助。
使用随附的DUnit和DUnitX框架为所有代码构建单元测试。
通过使用CodeSite Logging将实时日志添加到任何应用程序中,查看应用程序内部发生了什么,而不会中断应用程序流程。
6、与RAD Studio更好地协作
RAD Studio的协作和版本控制功能将帮助您以独立开发人员或团队成员的身份更快地创建更好的产品。代码协作可促进对代码的更深入理解,更好的测试和更好的产品。
使用版本控制系统(包括Subversion,Git和Mercurial存储库)快速跟踪和管理更改。
使用内置差异查看器的代码查看器中的“历史记录”选项卡,轻松导航更改和历史记录。
使用RAD Studio命令行编译器,非常适合使用我们对MSBuild或CMake项目的支持快速集成到连续的构建配置中。
7、扩展RAD Studio IDE
RAD Studio包含数百个组件,从创建用户界面到数据库连接,应有尽有,可快速轻松地为台式机和移动平台构建连接的业务应用程序。除了随附的VCL和FireMonkey组件外,Delphi和C ++ Builder社区还提供了广泛的工具和组件。
GetIt程序包管理器。通过下载和集成新组件来快速改善应用程序的功能。
为物联网而建。通过GetIt免费提供50多种IoT组件,将IoT功能快速添加到RAD Studio IDE中。
使用Embarcadero Technology Partners的工具和组件扩展IDE。
集成工具和组件。超越比较,FastReport,TeeChart,InterBase,IP * Works,CodeSight!
使用由数十个第三方制作的插件和插件来扩展IDE,以自定义IDE以按自己的方式工作
--------------------------------------------------------------------------------------------------------------------
下载地址 http://altd.embarcadero.com/download/radstudio/10.4/radstudio_10_4_99797b.iso
注册机 https://download.csdn.net/download/u011883102/12507844
1、装载radstudio_10_4_99797b.iso,管理员身份运行radstudio 10 4 esd 99797b.exe运行安装(强调),勾选我同意RAD Studio许可协议和隐私权政策,点击options
2、到注册界面先点击back,管理员身份运行RXKeyPatch.v10.4.exe,点击patch按钮
3、回到安装程序,点击next,选择Use Existing License选项,点击install安装
4、根据提示选择要安装的平台,完成后,第一次运行的时以管理员身份运行 -
Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结 .
2014-06-14 16:17:31Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结 这两天把一个使用Delphi2007成功升级到了Delphi2010。升级途中很艰辛,总结了 以下经验与大家分享。另外,D7使用的第三方组件,由于官方没有发布For Delphi...Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结
这两天把一个使用Delphi2007成功升级到了Delphi2010。升级途中很艰辛,总结了 以下经验与大家分享。另外,D7使用的第三方组件,由于官方没有发布For Delphi2010的更新,修改的第三 方组件列表见文章尾部。
1,PChar
因为Delphi不支持无类型指针的算术运算,很多程序员使用 PChar来代替Pointer,即使指针指向目标并不是PAnsiChar。
考虑如下代码:
<p><span class="kwd">var</span> <span class="pln"> P</span><span class="pun">:</span><span class="typ">PChar</span><span class="pun">;</span> <span class="pln"> </span><span class="typ">Buffer</span><span class="pun">:</span><span class="typ">Pointer</span><span class="pun">;</span> <span class="kwd">begin</span> <span class="pln"> </span><span class="typ">GetMem</span><span class="pun">(</span><span class="typ">Buffer</span><span class="pun">,</span><span class="lit">255</span><span class="pun">);</span> <span class="pln"> P</span><span class="pun">:=</span><span class="typ">Buffer</span><span class="pun">;</span> <span class="pln"> p</span><span class="pun">^:=</span><span class="com">#1;</span> <span class="pln"> </span><span class="typ">Inc</span><span class="pun">(</span><span class="pln">P</span><span class="pun">);</span> <span class="pln"> p</span><span class="pun">^:=</span><span class="com">#2;</span> <span class="pln"> </span><span class="typ">FreeMem</span><span class="pun">(</span><span class="typ">Buffer</span><span class="pun">,</span><span class="lit">255</span><span class="pun">);</span> <span class="kwd">end</span><span class="pun">;</span></p>
在2010中PChar已经不再表示PAnsiChar而是表示PWideChar,如果依然这样写,运行时很可能会得到一个内存访问错误。因为每 次Inc(P),实际上指针向前移动了2字节,因为SizeOf(WideChar)=2,Inc(P)相当于 P:=P+SizeOf(WideChar)。
解决方法是把PChar替换成PAnsiChar
2,Move FillChar CopyMemory
这些函数依赖的是字节长度,往往我们直接使用Length(Str)来获取,这是行不通的。
考虑如下代码:
<p><span class="kwd">var</span> <span class="pln"> P1</span><span class="pun">,</span><span class="pln">P2</span><span class="pun">:</span><span class="typ">String</span><span class="pun">;</span> <span class="kwd">begin</span> <span class="pln"> P1</span><span class="pun">:=</span><span class="str">'test'</span><span class="pun">;</span> <span class="pln"> </span><span class="typ">SetLength</span><span class="pun">(</span><span class="pln">P2</span><span class="pun">,</span><span class="typ">Length</span><span class="pun">(</span><span class="pln">P1</span><span class="pun">));</span> <span class="pln"> </span><span class="typ">Move</span><span class="pun">(</span><span class="pln">P1</span><span class="pun">[</span><span class="lit">1</span><span class="pun">],</span><span class="pln">P2</span><span class="pun">[</span><span class="lit">1</span><span class="pun">],</span><span class="typ">Length</span><span class="pun">(</span><span class="pln">P1</span><span class="pun">));</span></p><p><span class="kwd">end</span> </p>
在2010中String默认映射到UnicodeString,单个字符是2字节,所以上文中P1实际占用了8字节内存,而传给Move函数的长 度只有4字节,最终结果是P2="te"。
解决办法1:
修改String为AnsiString,该方案虽然可行,但你的程序就享受不到Unicode待遇了。
解决办法2:
SetLength 函数不要修改,因为他的长度参数是字符长度,而不是字节长度。
Move函数的最后一个参数 Length(P1) 修改成 Length(P1)*SizeOf(Char)。
注意:不要偷懒使用万一老师说的ByteLength函数,该函数并没有For AnsiString的重载,编译器会 把参数隐式转化为UnicodeString然后,ByteLength函数计算UnicodeString的长度。例如:一旦你不小心传入了一个 AnsiString类型长度为4的字符串,函数会返回8,而不是你期望的长度4。
3,Key in ['a'..'z','B','C']
这类代码最好替换成CharInSet(Key,['a'..'z','B','C']) 不然会当作AnsiChar处理。
4,WideString
代码中的所有WideString都考虑替换成String,现在 WideString只是为了与COM兼容而存在,且没有引用计数,性能低下。
5,Tnt控件
如果你的工程使用了Tnt控件或以前的WideTextPos WideStringReplace之类的东西都替换成标准的吧,不用曲线救国了。
---------经过修改,可以在Delphi2010下运作的第三方组件--------------
1,PNGDelphi
2,EmbeddedWB
3,SynEdit的语法高亮组件 unihighlighter
4,JEDI Win32API Header
这些组件现在可以在Delphi2010下运作了。
6,引用AnsiStrings单元
如果你有必要使用 AnsiLowerCase AnsiCompareStr之类的函数,一定要引用AnsiStrings单元。
如果你不引用该单元,即便编译不报错,你实际上是用的还是Unicode版本的函数,会有隐式的转化。不信你打开参数自动完成,看看IDE提示给你的类型是什么?天啊AnsiLowerCase参数竟然还是String,而不是AnsiString。看来Delphi2010太迫切的要抛弃Ansi字符串了,以至于你不引用AnsiStrings单元,所有Ansixxxx函数实际上还是Unicode版本。
7,AnsiCopy AnsiPos AnsiDelete
不要用AnsiCopy AnsiPos AnsiDelete,因为Copy Pos Delete三个函数已经有了For Ansi的重载。
8,把Char转化为小写用什么?
答案:试试看Character单元的新函数 ToUpper ToLower。以前我都是用System里面的UpCase函数,现在依然可用不过却找不到LowCase DownCase之类的函数,困扰我好久好久。索性全使用Character单元提供的新函数吧。
9,编译期警告:[DCC Warning] Unit1.pas(31): W1057 Implicit string cast from 'AnsiString' to 'string'
如果你的代码中包含了两种字符串(Unicode、Ansi)之间进行隐式转化的时候就会出现该提示。
如下代码就会触发该警告:
var Unicode:String; Ansi:AnsiString; begin Ansi:='test..'; Unicode:=Ansi;
把旧版本的Delphi项目升级到2010,我通常都是借助编译警告来快速寻找需要改动的部分。通常你可以把赋值双方都声明为String(默认影射到UnicodeString),就可以避免该警告。但如果你确定必须在此处保留Ansi并进行转化的时候,建议你显式的转化他们(例如:Unicode:=String(Ansi);),这样可以避免该警告,方便你在升级过程中继续寻找其他需要修改的地方。
10,Readln Writeln 写入文件时候要注意
如果你传给Writeln一个AnsiString,那么它也会在文件中写入AnsiString,那么你读取得时候就必须传给Readln一个AnsiString的类型,否则就是乱码。例如旧工程的配置文件是Ansi的,而你已经把相关读取配置的代码升级为支持Unicode,那么运行工程前你首先要用记事本之类的工具把配置文件另存为成Unicode编码。当然你还要注意跳过Unicode文件头的两个字节FE FF。
11,别再用String来操作二进制数据了
一定要记住String只是字符串,不要把它当作缓冲区、内存流使用。我的项目中,有很多地方是使用字符串来处理二进制数据,导致在本次升级中颇为费脑。如果当时用TBytes或TStream就好了。
反面教材:
var Int1,Int2,Int3,Int4:Integer; Buf:String; begin SetLength(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= Pointer to a WideChar array;
PAnsiChar = Pointer to a AnsiChar array;
如果你还像是在Delphi 7中那样:PChar(AnsiString)那后果过是很严重的。
一段转换例子D7unit
ReCode;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
Function
JiaMi(Src:
String
; Key:
String
):
String
;
Function
JieMi(Src:
String
; Key:
String
):
String
;
implementation
Function
JiaMi(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]);
for
SrcPos :=
1
to
Length(Src)
do
begin
SrcAsc:=(Ord(Src[SrcPos]) + offset)
MOD
255
;
if
KeyPos < KeyLen
then
KeyPos:= KeyPos +
1
else
KeyPos:=
1
;
SrcAsc:= SrcAsc
xor
Ord(Key[KeyPos]);
dest:=dest + format(
'%1.2x'
,[SrcAsc]);
offset:=SrcAsc;
end
;
Result:=Dest;
end
;
//解密函数
Function
JieMi (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);
if
KeyLen =
0
then
key:=
'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
;
if
KeyPos < KeyLen
Then
KeyPos := KeyPos +
1
else
KeyPos :=
1
;
TmpSrcAsc := SrcAsc
xor
Ord(Key[KeyPos]);
if
TmpSrcAsc <= offset
then
TmpSrcAsc :=
255
+ TmpSrcAsc - offset
else
TmpSrcAsc := TmpSrcAsc - offset;
dest := dest + chr(TmpSrcAsc);
offset:=srcAsc;
SrcPos:=SrcPos +
2
;
until
SrcPos >= Length(Src);
Result:=Dest;
Result:=Copy(Result,
1
,Length(Result)-
1
);
end
;
end
.
XE5
unit
ReCode;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,AnsiStrings;
Function
JiaMi(Src:
String
; Key:
String
):
String
;
Function
JieMi(Src:
String
; Key:
String
):
String
;
implementation
Function
JiaMi(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);
for
SrcPos :=
1
to
IntTemp
do
begin
SrcAsc:=(Ord(SrcAnsi[SrcPos-
1
]) + offset)
MOD
255
;
if
KeyPos < KeyLen
then
KeyPos:= KeyPos +
1
else
KeyPos:=
1
;
SrcAsc:= SrcAsc
xor
Ord(Key[KeyPos]);
dest:=dest + format(
'%1.2x'
,[SrcAsc]);
offset:=SrcAsc;
end
;
Result:=Dest;
end
;
//解密函数
Function
JieMi (Src:
String
; Key:
String
):
String
;
var
KeyLen :
Integer
;
KeyPos :
Integer
;
offset :
Integer
;
dest :
String
;
SrcPos :
Integer
;
SrcAsc :
Integer
;
TmpSrcAsc :
Integer
;
Range :
Integer
;
SrcAnsi: