Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

28 Jun 2021

UWP资源管理文档阅读笔记【一】

Localize your WinUI desktop app

需要在package.appxmanifest中添加应用所支持的语言。

打开wapproj的package.appxmanifest,找到下面的片段:

<Resources>
    <Resource Language="x-generate"/>
</Resources>

替换成:

<Resources>
    <Resource Language="en-US"/>
    <Resource Language="es-ES"/>
</Resources>

App resources and the Resource Management System

如何撰写,打包,以及消耗应用的字符串,图像,以及文件资源。字符串通常需要需要在不同的语言中有不同的版本,图像通常要有不同的分辨率。Resource Management System为这些功能提供支持。

应用资源有两种:

  • 文件资源,以文件形式存在。文件资源可以是位图,XAML,XML,HTML,活其他任意类别的数据。
  • 填埋的资源,指填埋在其他资源文件中的。常见例子是填埋在.resw或者.resjson资源文件中的字符串资源。

Resource Management System

RMS的特性分布在构建时以及运行时。构建时,会创建一个针对所有被打包的资源的索引,称为包资源索引(PRI)。运行时,系统根据用户和机器上的设定来决定如何从PRI中获取信息。

Package Resource Index (PRI) file

  • PRI文件包含字符串资源,以及指向其他资源文件的文件路径
  • 一个包通常针对每种语言有一个PRI文件,命名如resources.pri
  • 包顶层目录的resources.pri在ResourceManager例现化的时候自动加载
  • 可以用MakePRI.exe来生成和倒看pri文件的内容。
  • 通常不需要直接使用MakePRI.exe,因为VS在编译的时候的工作流程中包含了对MakePRI的使用。VS还提供编辑PRI的UI。
  • 每个PRI文件包含了具名资源集合,可以看作一个资源映射。PRI加载时i,资源映射会被检查是否匹配包身份名。
  • PRI只包含数据,不使用portable executable (PE)格式,不像Win32使用DLL来提供资源。

UWP API access to app resources

Basic functionality (ResourceLoader)

最简单的方式是通过Windows.ApplicationModel.Resources以及 ResourceLoader。

Advanced functionality (ResourceManager)

Windows.ApplicationModel.Resources.Core下的ResourceManager对资源提供列举和检视。

一个NamedResource对象表示单独的逻辑上的资源,可以针对多语言,以及其他格量化。它描述了资源的逻辑视图,比如字符串资源描述符Header1,或者一个资源文件名,如logo.jpg

ResourceCandidate表示单个具体的资源值,以及它的格量。比如"hello world"给英语,“logo-scale-100.jpg"给100%缩放的图形。

资源是层次化管理,可以通过ResourceMap对象来访问。ResourceManager类提供到顶层ResourceMap的现例的访问,其ResourceMap可能来自不同的软件包。MainResourceMap对应当前软件包的资源映射(不包含框架内的资源)。ResourceMap的命名是根据软件包名来的。ResourceMap内部是一颗子树(参考ResourceMap.GetSubtree),包含有NamedResource对象。此子树通常对应到资源文件。更多参考:

一个例子:

// using Windows.ApplicationModel.Resources.Core;
ResourceMap resourceMap =  ResourceManager.Current.MainResourceMap.GetSubtree("Resources");
ResourceContext resourceContext = ResourceContext.GetForCurrentView()
var str = resourceMap.GetValue("String1", resourceContext).ValueAsString;

资源标识符是URI片段, GetValue("Caption%20")相当于GetValue("Caption ")。不要在资源标识符中使用?或者#,因为它们会终结路径。

文件资源存在于ResourceMap中的"File"子树,\Images\logo.png对应于Files/images/logo.png.

StorageFile可以透明处理到文件资源的引用。建议再高级情形下使用ResourceManager,也就是当需要重定义当前上下文的时候。

ResourceContext

ResourceContext表示的是资源的格量要求,比如语言,缩放,对比等等。默认会根据应用的设置生成一个ResourceContext,但是这些可以被重新定义。每个应用视图都有一个不同的默认上下文,可以通过ResourceContext.GetForCurrentView来获取。获取资源候选的时候,可以传入ResourceContext来获取那个最适用于当前视图的。

(本篇完)