delphi通过将数据放入EXE的资源信息中的方式制作自已的安装工具


本文整理自网络,侵删。

 

关键点:读取资源,然后使用;如果是动态添加的资源则应该在使用前检查。

 

一、资源导入:在Delphi XE版本中有个工具,可以直接将文件当做资源导入到程序中,编译时会自动编译到资源中去。




 

通过上面的步骤完成资源导入,则工程文件的program下应该多一行{$R *.dres}


二、资源使用
var
  rs: TResourceStream;
begin
  rs := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
  try
    //资源流中可以是图片,文本等数据...
  finally
    rs.Free;
  end;
end;

三、多语言方案

安装包一般是将多种语言集成在一起,由用户选择安装语言,可以先将做一个中文的键值对文件,做为UI字典,通过方法一导入工程中,实现几上公共方法,用于加载字典和翻译:LoadDict,T(Key),这样UI中所有的需要文字描述的地方使用T(Key)的方式取得,以后再添加语言时也无需修改代码。
var
  UIDict: TDictionary<string,string> = nil;//全局变量
  UICurrentLang: string = 'EN';//当前UI语言

procedure LoadUIDict;
var
  rs: TResourceStream;
  sl: TStrings;
  I: Integer;
  UICode: Word;
  UIList: string;
  ResName, sLine: string;
begin
  //从资源中加载语言字典
  if not Assigned(UIDict) then
    UIDict := TDictionary<string,string>.Create;

  sl := TStringList.Create;
  try
    ResName := Format('UIDICT_', [UICurrentLang]);
    rs := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
    try
      sl.LoadFromStream(rs);
      for I := 0 to sl.Count - 1 do
        if sl[I] <> '' then
          UIDict.AddOrSetValue(SL.Names[I], SL.ValueFromIndex[I]);
    finally
      rs.Free;
    end;
  finally
    sl.Free;
  end;
end;


function T(UIKey: string): string;
begin
  //翻译UIKey
  if not UIDict.TryGetValue(UIKey, Result) then
    Result := '(Unknow)';
end;

如果是文本且用于UI,则需要注意尽量使用UTF8对文本或文件进行编码,否则在非中文操作系统环境下会显示乱码。

四、动态添加资源

主要使用以下几个API实现:BeginUpdateResource、UpdateResource、EndUpdateResource
var 
  hrSrc: THandle;
  ResStream: TMemoryStream;
begin

  hrSrc := BeginUpdateResource(PChar(ExeFile), False);//一定是Exe或Dll
  if hrSrc = 0 then
  begin
    ShowMessage('BeginUpdateResource[Error]');
    Exit;
  end;

  //以下这段可以封装并多次使用,比如:添加LOGO图片,添加UI字典,添加程序压缩包等
  ResStream := TMemoryStream.Create;
  try
    ResStream.LoadFromFile('D:\dict_cn.txt');
    ResName := 'UIDICT_CN';//例子
    if not UpdateResource(hrSrc, RT_RCDATA, PChar(ResName), 0, ResStream.Memory, ResStream.Size) then
    begin
      ShowMessage('UpdateResource[Fail]');
      Exit;
    end;
  finally
    ResStream.Free;
  end;

  //将之前更新的资源写回文件中
  if not EndUpdateResource(hrSrc, False) then
  begin
    ShowMessage('EndUpdateResource[Error]');
    Exit;
  end;
end;

function CheckResExists(resList: TArray<string>): Boolean;
var
  hrSrc: THandle;
  resName: string;
begin
  //检查资源ID是否存在,如果是动态添加资源方式,在使用前一定要检查
  Result := False;
  for resName in resList do
  begin
    hrSrc := FindResource(HInstance, PChar(resName), RT_RCDATA);
    if hrSrc = 0 then
      Exit;
    FreeResource(hrSrc);
  end;
  Result := True;
end;

五、高级方案

可以写个控制台的构建工具,比如叫:BuildTool,通过分析配置文件将安装所需的信息动态添加到安装壳程序中

注意事项:如果是添加字符串资源,可以使用TStringStream,并指定编码方式为UTF8或Unicode

 

来源:https://blog.csdn.net/cmd9x/article/details/83655620

相关阅读 >>

Delphi 判断一个颜色是否是亮色

Delphi 让嵌入窗体的 webbrowser 控件无边框

Delphi xe5 中tmemo控件的应用――for android

Delphi �c 如何使用datasnap获取作为标头传递的标记?

Delphi 一个分割文本文件的代码

Delphi 一个绘制虚线的非常规函数(常规方法,打印机上绘制不出虚线)

Delphi 匿名管道

Delphi 10 firedac 连接池设置

Delphi 2009 之 tcategorypanelgroup[2]: headeralignment、gradientdirection

Delphi 遍历某字段并插入到combobox

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...