此文章是vip文章,如何查看?  

1,点击链接获取密钥 http://nicethemes.cn/product/view29882.html

2,在下方输入文章查看密钥即可立即查看当前vip文章


Delphi XE10.3.1 使用心得-2019-12-08

  • 时间:
  • 浏览:
  • 来源:互联网

Delphi XE10.3.1 使用心得

  • 写在前头
  • 工具安装
  • 创建项目
  • 类的创建和引用
  • 变量的声明和引用
    • 1.类的成员
    • 2.全局变量
    • 3.局部变量
  • 函数的声明和实现
    • 1.直接说说function,procedure只是没有返回值
  • 其他一些东西- -
    • 1.TFileCtrlEx
    • 2.使用字典类型
    • 3.遍历目录中的文件以及删除文件夹
    • 4.RichEdit改变一行的颜色
    • 5.解压缩
  • 项目中的一些小坑
    • 1.Delphi中的Foreach字典类型的不确定情况哈哈哈
    • 2.重复引用
    • 3.注释哟
    • 4.对了,还有Region折叠块的写法

参考文档-www.baidu.com
参考文档-B站UP主:舞动的代码

写在前头

不是为了啥…只是觉得自己记性不好- -,不希望每次要用Delphi的时候都要从头开始,所以写下这些,能帮助自己节省一些时间吧…

工具安装

详见B站教程: 破解安装…
emmm…虽然项目中使用的是公司买的正版的- -,但是问题不大,这个应该可以使用。
不得不说的一点是,CnPack这个工具一定一定要去安装,不然太难受了- -,对用用惯了补全的我来说,没有补全提示真得是太太太不友好了!!!
CnPack官方网址:没有这个真的太难了

创建项目

算了,这个我不想写了- -,感觉一步步截图好累的说,就这样吧昂,我创建的是这个,窗体应用的说…
在这里插入图片描述

类的创建和引用

第一步,先创建个Unit单元,没错,在项目里新建一个就好了…这样,命名啥的随意了- -

在这里插入图片描述
上图好伐,大概情况时这样的吧…我是只用到这些,emmm…别问,问就是菜鸡- -具体的方法函数啥的我就不贴了,辣眼睛哦…
加粗样式
emmm,忘了一点的说,Delphi中构造函数的话,是使用Create
声明如下

constructor Create;overload;

实现的话…

constructor FileOperationT.Create;
begin
   //吧啦吧啦~
end;

变量的声明和引用

1.类的成员

类的成员需要在类中进行声明哦,至于初始化的赋值,建议是在初始化函数中进行统一的赋值啦。不然直接赋值是会错的哦
类的成员声明的时候就进行赋值会出错

2.全局变量

全局变量的话就简单了,直接在pas中,声明赋值就好了。
在这里插入图片描述

3.局部变量

局部变量需要在方法函数的begin之前用Var声明,并且以";"作为结束。赋值的话直接在方法函数里面实现就行了。
在这里插入图片描述

函数的声明和实现

瓦感觉写到这里,光是前面的截图好像就已经有很多函数声明的截图了吧…emmm,好吧,没有,真可惜,还要继续截图,啊呀呀呀。
大致可以分为function和procedure这两种,前者(function)有返回值(但是非必须,如果没有返回值最多是waring),后者(procedure)没有返回值。

1.直接说说function,procedure只是没有返回值

function的返回值就是Result不需要声明,Result的类型和声明的function的类型是一致的,直接使用即可
若要退出,则使用exit;而不是像C或者C++一样return xxx 这样。

//声明...
function WriteLog(str:string;LogName:string;Directpath:string):boolean;overload;
function WriteLog(str:string;LogName:string):boolean;overload;
//out 声明时和其他的语言中一样,但是使用的过程中是不需要再写out的,具体如下
function WriteLog(str:string;LogName:string;out rel:boolean):boolean;overload;

//实现
function WriteLog(str,LogName: string): boolean;
var
cnt:integer;//定义局部变量
begin
  Result:=WriteLog(str,LogName,_logfileDir);//Result表示返回值;
end;

//引用
procedure Main
var
rel:boolean;
begin
	rel:=WriteLog('str','LogName','Directpath');
	rel:=WriteLog('str','LogName');
	WriteLog('str','LogName',rel);//引用的时候不需要使用out
	if rel then
	begin
		exit;//退出该函数
	end;
end;

其他一些东西- -

1.TFileCtrlEx

这里面有包括一些扩展的窗体控件,很实用,我这次使用的是CheckDirectoryBox的控件。
下载地址:https://crack4download.com/crack?s=TFileCtrlEx&id=112972

2.使用字典类型

在Delphi中要想使用TDirectory<T,T>类型,必须要引用System.Generics.Collections

//定义变量
Var
dic:TDictionary<string,string>;
//使用
procedure main
begin
	//初始化
    dic:=TDictionary<string,string>.Create();
    dic.AddOrSetValue('1','1');
    dic.Add('2','2');
    dic.TryGetValue('1',str);
    dic.Remove('2');
end;

扩展一下,如果想要遍历字典的话,可以使用键值对TPair<key,Value>哦~

procedure main
Var
FilePair:TPair<string,string>;
dic:TDictionary<string,string>;
begin
	//初始化
    dic:=TDictionary<string,string>.Create();
    dic.AddOrSetValue('1','1');
    dic.Add('2','2');
    dic.TryGetValue('1',str);
    dic.Remove('2');
    //遍历字典
    for FilePair in dic do
    begin
    	FilePair.key;
    	FilePair.Value;
    end;
end;

3.遍历目录中的文件以及删除文件夹

// <summary>
// 删除文件夹
// <summary>
// <param name="filepath">待删除的文件夹</param>
function FileOperationT.DeleteDirs(Dirpath: string): boolean;
var
  sr: TSearchRec;
  sPath, sFile: WideString;
begin
  Result:=False;
  //检查目录名后面是否有 '\'
  if Copy(Dirpath,Length(Dirpath),1) <> '\' then
    sPath := Dirpath + '\'
  else
  sPath := Dirpath;
  if FindFirst(sPath+'*.*',faAnyFile, sr) = 0 then
  begin
    repeat
      sFile:=Trim(sr.Name);
      //排除当前目录
      if sFile='.' then Continue;
      //排除上级目录
      if sFile='..' then Continue;
      sFile:=sPath+sr.Name;
      if (sr.Attr and faDirectory)<>0 then
      begin
        DeleteDirs(sFile);
        Result:=True;
      end
      else if (sr.Attr and faAnyFile) = sr.Attr then
      DeleteFile(sFile); //删除文件
    until FindNext(sr) <> 0;
    FindClose(sr);
  end;
  RemoveDir(sPath);
end;

4.RichEdit改变一行的颜色

//添加到消息框,基础+写日志
function TMainForm.RicheditAdd(addstr: string; rhedit: TRichEdit; writelog: boolean): boolean;
begin
  //根据内容改变颜色
  if addstr.Contains('false') then
  begin
    richedit1.SelAttributes.Color := clred;//改变接下去RichEdit控件的颜色
  end
  else
  begin
    richedit1.SelAttributes.Color := clBlack;//改变接下去RichEdit控件的颜色
  end;
  //添加内容
  rhedit.Lines.Add(addstr+'   '+formatdatetime('yyyy-MM-dd hh:mm:ss',Now));
  //跟随内容滚动条到底
  result:=postmessage(rhedit.Handle, wm_vscroll, sb_bottom, 0);
end;

5.解压缩

该方法是同事写的,我这边只是引用,防止以后给忘了还得找…侵删哈…

// <summary>
// 解压文件至目标文件
// <summary>
// <param name="filepath">待解压的文件</param>
// <param name="Destinfile">目的地文件夹路径</param>
function FileOperationT.UzipFileToDes(filepath, Destinfile: string): boolean;
var
Zip: TZipFile;
Exact:string;
ShExecInfo: SHELLEXECUTEINFO;
begin
  Exact:=ExtractFileExt(filepath);
  Zip := TZipFile.Create;
  try
    if not DirectoryExists(Destinfile) then
    begin
      CreateDir(Destinfile);
    end;
    if Exact='.rar' then
    begin
      ShExecInfo.cbSize:= sizeof(SHELLEXECUTEINFO);
      ShExecInfo.fMask:= SEE_MASK_NOCLOSEPROCESS;
      //ShExecInfo.Wnd:= Handle;
      ShExecInfo.lpVerb:= 'open';
      ShExecInfo.lpFile:='WinRar';
      ShExecInfo.lpParameters :=PChar('x '+filepath+'  '+Destinfile);
	  //ShExecInfo.lpDirectory:=null;
      ShExecInfo.nShow:=SW_HIDE;
      //ShExecInfo.hInstApp:=NULL;
      ShellExecuteEx(@ShExecInfo);
      WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
      CloseHandle(ShExecInfo.hProcess);
    end
    else
    begin
      Zip.Open(filepath, TZipMode.zmRead);
      Zip.ExtractAll(Destinfile);
    end;
  finally
   Zip.Free;
  end;
  result:=true;
end;

项目中的一些小坑

1.Delphi中的Foreach字典类型的不确定情况哈哈哈

emmm…怎么说呢,吃了个哑巴亏吧,其实在Delphi中是没有Foreach的,只是使用For xx in xxS do…这样的来达到和Foreach同样的效果。
在遍历的过程中,如果使用Remove等类似的方法去改变正在遍历的变量,那么会导致一些异常:在C#中是会直接异常提示,但是在Delphi中,我遍历字典过程中Remove是没有出现异常提示,不过吧…Remove的数据出现了状况。

//前
procedure main
Var
FilePair:TPair<string,string>;
ExcludeDirDic:TDictionary<string,string>;
FinalDirDic:TDictionary<string,string>
RootPath:string;
begin  
	... 
    fileoperator.ReadDirList(RootPath,FinalDirDic);//从RootPath读取文件夹目录到FinalDirDic,自己封装的函数...
    for FilePair in FinalDirDic do 
    begin
      if ExcludeDirDic.ContainsKey(FilePair.Key) then
      begin
        FinalDirDic.Remove(FilePair.Key);
      end;
    end;
end;
//上述代码中,本来要将FinalDirDic中的所有的有包含ExcludeDirDic主键的键值对删除。
//但是在FinalDirDic第一个键值对删除之后,FinalDirDic就发生了变化,后续的就没有再删除了。
//修改后
procedure main
Var
FilePair:TPair<string,string>;
ExcludeDirDic:TDictionary<string,string>;
FinalDirDic:TDictionary<string,string>
RootPath:string;
begin  
	... 
    fileoperator.ReadDirList(RootPath,FinalDirDic);//从RootPath读取文件夹目录到FinalDirDic,自己封装的函数...
    for FilePair in ExcludeDirDic do //需要注意,不能以要删除的字典作为循环的条件,不然会出错
    begin
      if FinalDirDic.ContainsKey(FilePair.Key) then
      begin
        FinalDirDic.Remove(FilePair.Key);
      end;
    end;
end;

2.重复引用

嗷,关于重复引用的问题,如果A.pas和B.pas需要互相引用到各自的方法,这时候不能在interface后的uses中声明引用,但是我们又要用该怎么办呢,简单,在implementation后使用uses就好了,上图上图…
在这里插入图片描述

3.注释哟

我就用这两种吧,// 或者 {} 和其他语言是差不多的说- -

//这是注释

{
这也是注释
}

4.对了,还有Region折叠块的写法

巨巨巨无敌喜欢折叠块,为啥呢,舒服呀~写法如下

{$region '折叠块'}
constructor FileOperationT.Create;
begin
   //self._logfileDir:='C:\Updata\log';
end;
{$endregion}

本文链接http://element-ui.cn/news/show-577184.aspx