MRM 中的限定符
资源索引器(和 MRT 运行时)使用“限定符”来确定应在其中使用给定资源候选项的上下文。 每个资源都有一个名称和一个或多个候选项(或值),每个候选项都有零个或多个限定符。 有关命名资源的详细信息,请参阅 MRM 中的资源名称。
例如,可能有一个名为 greeting 的字符串资源,其中有三个不同的本地化候选项:
- 对于英语,文本为“Hello”
- 对于德语,文本为“Hallo”
- 对于韩语,文本为“안녕하세요”
这些候选项将使用正确的语言限定符添加到索引器中,并存储在 PRI 文件中,以便 MRT 知道在运行时使用哪个限定符。 例如,若要将这三个字符串添加到索引器,可以使用:
HRESULT hr{};
hr = MrmIndexString(indexer, L"ms-resource:///strings/greeting", L"Hello", L"language-en");
hr |= MrmIndexString(indexer, L"ms-resource:///strings/greeting", L"Hallo", L"language-de");
hr |= MrmIndexString(indexer, L"ms-resource:///strings/greeting", L"안녕하세요", L"language-ko");
if (FAILED(hr)) { /* error handling */ }
语言只是可能的限定符之一;其他通用限定符包括比例(用于指定不同分辨率的图像)或对比度(对于不同的对比度设置)。 ResourceContext.QualifierValues 主题中列出了限定符的完整列表。
请注意,MRM API 不支持限定符的“短”形式(例如,“lang”而不是“language”);必须使用长格式。 然而,从文件路径推断限定符的函数 MrmIndexFileAutoQualifiers 和 MrmIndexResourceContainerAutoQualifiers 确实支持短形式。
限定符以 name-value
的形式指定为字符串,例如 language-en
或 scale-200
。
(Language 限定符的值也可能包含连字符,如 en-us
。)名称和值都不区分大小写,因此 LANGUAGE-EN-US
、Language-En-Us
和 language-en-us
是等效的。
请注意,为同一资源指定两个具有相同限定符但值不同的候选项是错误的。 遗憾的是,当资源添加到索引器(例如调用 MrmIndexString 时),这个错误不会出现;但在生成 PRI 文件时,生成将返回 ERROR_MRM_DUPLICATE_ENTRY,但是不提供哪个资源导致了这个问题的指示。
例如,添加重复候选项时,此代码片段将成功,但稍后在 PRI 生成过程中失败:
// Add "color = red". Returns S_OK, since all arguments are valid.
hr = MrmIndexString(indexer, L"ms-resource:///strings/color", L"red", L"language-en");
// Add "color = blue". Returns S_OK, since all arguments are valid (in isolation).
hr = MrmIndexString(indexer, L"ms-resource:///strings/color", L"blue", L"language-en");
// Fails with ERROR_MRM_DUPLICATE_ENTRY since there are two English candidates for "strings/color"
// ("red" and "blue").
hr = MrmCreateResourceFile(indexer, MrmPackagingModeStandaloneFile, MrmPackagingOptionsNone, fileName);
如果将完全相同的候选项添加两次(例如,在上面的代码中,如果第二次调用重复“红色”而不是使用“蓝色”),则忽略重复项,不会产生错误。
限定符列表
资源候选项可以有多个限定符。 例如,图像文件可能需要基于比例(100%、200% 等)和对比度(标准或高) 的候选项。 如果图像包含文本,则可能需要根据语言对其进行限定。
在单个字符串中指定了多个限定符,用下划线分隔。 例如,比例为 200% 的高对比度的图像候选项将使用限定符 contrast-high_scale-200
。 列表中指定限定符的顺序并不重要;MRT 对每个限定符都有一个内置的重要性顺序(例如,语言比比例更重要)。
虽然在限定符列表中重复限定符(即使具有不同的值)并不是错误,但除了第一个以外的所有限定符都将被忽略。
language-en_language-en
(指定英语两次 - 有效语言为英语)language-en_language-de
(指定英语,然后指定德语 - 有效语言为英语)language-de_language-en
(指定德语,然后指定英语 - 有效语言为德语)
如上所述,添加两个具有相同限定符但值不同的资源候选项是错误的。 这与限定符列表中限定符的顺序无关。
中性候选项
在将资源候选项添加到索引器时,你可以指定一个空字符串(或空指针)作为限定符,以表示候选项是“中性的”,可以匹配任何上下文。 例如,“开始”菜单中显示的应用名称可能是中性的候选项名称,因为应用名称通常不进行本地化(并且它们不依赖于其他因素,如比例或对比度)。 如果需要,除了特定候选项外,还可以使用中性候选项。
例如:
// The name of the app is the same, regardless of language, scale, etc.
hr = MrmIndexString(indexer, L"ms-resource:///strings/AppName", L"Contoso Widgets", nullptr);
// The name of the publisher is always "Contoso Inc." except in Australia, where it is "Contoso PTY LTD".
hr = MrmIndexString(indexer, L"ms-resource:///strings/AppPublisher", L"Contoso Inc.", nullptr);
hr = MrmIndexString(indexer, L"ms-resource:///strings/AppPublisher", L"Contoso PTY LTD", L"homeregion-au");
默认限定符
创建配置文件(通过 MrmCreateConfig... 函数之一)或创建资源索引器(通过 MrmCreateResourceIndexer... 函数之一)时,defaultQualifiers 是限定符(例如语言),用于指示在找不到更好的匹配项时要使用的资源候选项。 例如,如果一个应用有英语和法语的资源,但它在语言设置为日语的系统上运行,则将使用创建 PRI 文件时指定为“默认限定符”的语言。 默认限定符还确定在使用 AutoSplit 打包时应使用哪个语言和比例来创建主 PRI 文件(有关详细信息,请参阅 MrmPackagingMode)。
请注意,所有资源都应具有使用默认限定符(或中性候选项)指定的候选项,否则如果没有最佳匹配项,则无法回退到任何资源。 请注意,未能提供回退候选项并不被视为错误(索引器将为你生成空字符串候选项),但这可能会导致用户体验不佳或应用程序错误。