2010-03-23 45 views
5

我需要找到当前版本的Windows正在使用的一些字符串。例如,当我创建一个新文件夹时,它最初在英文Vista上被命名为“新文件夹”。我需要以编程方式查找该文件夹将在我可能运行的任何语言和版本的Windows上命名。查找本地化的Windows字符串

任何人有任何想法如何做到这一点?

谢谢Morinar - 我也偶然发现了那篇文章。不幸的是,stringID似乎不是常数 - 我的Vista上是30396,这与他们为XP显示的不一样。所以它会出现MS不保持稳定。

编辑:看起来像这是不可能的...?这个应用程序运行在德国,荷兰,法国,西班牙,巴西,墨西哥,越南,台湾,中国,日本,韩国,印度,以色列,匈牙利的计算机上......你明白了。安装所有不同的语言包并花费很长时间才能找出每种语言的“新文件夹”。

也许最好的选择是默认为“新建文件夹”,并让用户更改该值,如果他们想。我只是希望尽可能多地找出软件,并避免用户配置_yet_another_setting_。

+0

这不会像您想象的那么容易。如果您创建了一个新文件夹并将其命名为“新文件夹”,然后再创建另一个新文件夹,则以名称“新文件夹(2)”开始。它的语法可能会因语言而改变(我不知道)。 –

+1

为什么你需要知道这个? – Michael

+0

我不希望资源字符串ID在主要版本的操作系统之间稳定。字符串资源被添加并删除,并在主要版本之间重新编译,让我们面对它 - 你在OS模块的私有数据中寻找。 Windows API不公开这些字符串,因此没有表达或暗示的稳定性合同。 – dthorpe

回答

6

无耻地从http://blogs.msdn.com/oldnewthing/archive/2004/01/30/65013.aspx cribbed。这大部分是正确的,但如果有一个资源字符串“New Folder something else”,它将匹配:

LPCWSTR FindStringResourceEx(HINSTANCE hinst, 
    UINT uId, UINT langId) 
{ 
    // Convert the string ID into a bundle number 
    LPCWSTR pwsz = NULL; 
    HRSRC hrsrc = FindResourceEx(hinst, RT_STRING, 
     MAKEINTRESOURCE(uId/16 + 1), 
     langId); 
    if (hrsrc) { 
     HGLOBAL hglob = LoadResource(hinst, hrsrc); 
     if (hglob) { 
      pwsz = reinterpret_cast<LPCWSTR> 
       (LockResource(hglob)); 
      if (pwsz) { 
       // okay now walk the string table 
       for (int i = 0; i < (uId & 15); i++) { 
        pwsz += 1 + (UINT)*pwsz; 
       } 

       pwsz+= 1; 
      } 
     } 
    } 
    return pwsz; 
} 

UINT FindResourceStringId(HMODULE resource_handle, LPCWSTR string, UINT langId) 
{ 
    UINT resource_id= -1; 

    for (int i= 0; i<65536; ++i) 
    { 
     LPCWSTR resource_string= FindStringResourceEx(resource_handle, i, langId); 

     if (resource_string && wcsncmp(resource_string, string, wcslen(string))==0) 
     { 
      resource_id= i; 
     } 
    } 

    return resource_id; 
} 

int main() 
{ 
    HMODULE shell_handle= LoadLibraryW(L"shell32.dll"); 
    UINT new_folder_id= FindResourceStringId(shell_handle, L"New Folder", 0x409); // look for US English "New Folder" resource id. 
} 
+0

那很高兴找到身份证。想象一下,该计划在中国正在运行。在这种情况下,你通过什么L“新文件夹”?我实际上并不需要身份证,我需要知道中文相当于“新建文件夹”。和法国人相同,德国人,荷兰人,越南人,韩国人等等等等。:( – DougN

+4

@DougN,你可以使用英语的语言环境获得ID,然后使用FindResourceStringEx(resource_handle,new_folder_id,language_id)'为其他语言。是英文的语言ID,所以如果你想要简体中文,你可以使用'FindResourceStringEx(resource_handle,new_folder_id,0x0804)',用于法语'FindResourceStringEx(resource_handle,new_folder_id,0x080c)'等 – MSN

+1

啊啊,这就是光滑! – DougN

2

不确定是否有一个更优雅的方式或没有(我似乎无法找到一个),但这些字符串存储在%windir%\System32\Shell32.dll。理论上,你可以只读取该文件并提取适当的字符串。

看起来有点乱七八糟,但应该完成工作。这里有一篇文章的链接,讨论他们在上述文件中的位置: http://www.askvg.com/customize-new-folder-and-new-shortcut-text-in-windows-xp/

似乎有可能,甚至应该是他们通过Windows API的接口,但通过文档拖动我找不到。也许你会有更多的运气。

+0

我也在看资源。不幸的是,从一个版本的Windows到下一个版本,资源ID并不稳定:( – DougN

4

这并不容易。这些字符串是Windows资源管理器的私有数据,因此它们可以(也可能)在不同版本之间进行更改。你可以在那里进行大量版本检查并阅读适当的资源字符串,但这似乎是一场失败的战斗。你想达到什么目的?

+0

我有一个文件监控应用程序,用于在创建新目录时提醒用户。用户不希望收到关于“新建文件夹”的警报,然后稍后关于“新文件夹”重命名为“我的文档”的警报,因此我希望能够捕捉并忽略第一次警报,但必须识别“新文件夹” – DougN

+0

如果用户没有重新命名它?另外,正如其他人所说,如果他们创建了多个新文件夹(“新文件夹(2)”等),这并不能帮到你。 – Luke

+0

没错,有一些我不能处理的角落案例。但我宁愿为大多数用户处理80%的情况。 – DougN

-1

如果您想处理80%的案例,您可以从“新建文件夹”开始。

正如我猜你在企业环境中,你可以将文件夹名称存回存储器,然后在一周(或任何时间)之后通过名称获得;更新你的应用;发布新版本,让用户满意。 (然后在此处发布结果)

您可以在怀疑用户使用的平台范围内抢先测试您的应用。获取第一系列文件夹名称。

这样可以避免处理与您查看的每个平台相关的特定代码的问题。

编辑 嗯,我得到关于第二个想法,我猜你可能想提醒有关“新建文件夹”的用户,如果它不是一段时间(一分钟)后改名?那么我想你会需要添加一个列表和一个计时器...