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”);必须使用长格式。 然而,从文件路径推断限定符的函数 MrmIndexFileAutoQualifiersMrmIndexResourceContainerAutoQualifiers 确实支持短形式。

限定符以 name-value 的形式指定为字符串,例如 language-enscale-200。 (Language 限定符的值也可能包含连字符,如 en-us。)名称和值都不区分大小写,因此 LANGUAGE-EN-USLanguage-En-Uslanguage-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)。

请注意,所有资源都应具有使用默认限定符(或中性候选项)指定的候选项,否则如果没有最佳匹配项,则无法回退到任何资源。 请注意,未能提供回退候选项并被视为错误(索引器将为你生成空字符串候选项),但这可能会导致用户体验不佳或应用程序错误。