2010-03-23 2 views
5

Мне нужно найти строки, которые использует текущая версия Windows. Например, когда я создаю новую папку, она первоначально называется «Новая папка» на английском языке Vista. Мне нужно программно найти то, что эта папка будет называться на любом языке и версии Windows, на которых я мог бы работать.Найти локализованные строки Windows

У кого-нибудь есть идеи, как это сделать?

Спасибо Моринар - Я просто наткнулся на эту статью. К сожалению, stringID не кажется постоянным - это 30396 на моей Vista, что не то же самое, что и для XP. Таким образом, казалось бы, MS не сохранила стабильность.

EDIT: Похоже, что это невозможно ...? Эти приложения работают на компьютерах в Германии, Нидерландах, Франции, Испании, Бразилии, Мексике, Вьетнаме, Тайване, Китае, Японии, Южной Корее, Индии, Израиле, Венгрии ... У вас есть идея. Это займет очень много времени, чтобы установить все различные языковые пакеты и узнать, что такое «Новая папка» на каждом языке.

Возможно, лучшим вариантом является по умолчанию «Новая папка» и заставить пользователя изменить это значение, если оно того захочет. Я просто предпочитаю, чтобы программное обеспечение определялось как можно больше, и избавляло пользователя от настройки _yet_another_setting_.

+0

Это не так просто, как вы могли бы подумать. Если вы создадите новую папку и оставьте ее под названием «Новая папка», затем создайте новую новую папку, вы начнете с имени «Новая папка (2)». Грамматика этого может меняться от языка к языку (я не знаю). –

+1

Зачем вам это нужно знать? – Michael

+0

Я бы не ожидал, что идентификаторы строк ресурсов будут стабильными между основными версиями ОС. Ресурсы String добавляются и удаляются и перекомпилируются между основными выпусками, и давайте посмотрим правде в глаза - вы заглядываете в частные данные модуля ОС. API Windows не раскрывает эти строки, поэтому не существует договора стабильности, выраженного или подразумеваемого. – dthorpe

ответ

6

Бесстыдно скрещенное от http://blogs.msdn.com/oldnewthing/archive/2004/01/30/65013.aspx.Это в основном правильно, но если есть строка ресурсов «Новая папка что-то еще», она будет соответствовать этому:

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, вы можете получить идентификатор, используя английскую локаль, а затем использовать 'FindResourceStringEx (resource_handle, new_folder_id, language_id)' для других языков. 0x409 это идентификатор языка для английского, поэтому, если вы хотите упрощенного китайского языка, вы должны использовать «FindResourceStringEx (resource_handle, new_folder_id, 0x0804)», для французского 'FindResourceStringEx (resource_handle, new_folder_id, 0x080c)' и т. д. – MSN

+1

Ahhh, это пятно! – DougN

2

Не уверен, есть ли более элегантный способ или нет (я не мог найти его), но эти строки хранятся в %windir%\System32\Shell32.dll. Теоретически вы можете просто прочитать этот файл и извлечь соответствующие строки.

Кажется немного хаки-иш, но должен выполнить свою работу. Вот ссылка на статью, которая обсуждает, где они живут в указанном файле: http://www.askvg.com/customize-new-folder-and-new-shortcut-text-in-windows-xp/

Похоже, там может или даже должен быть интерфейс к ним через API Windows, но троллинг через документации, которую я не мог найти. Возможно, вам повезет больше.

+0

Я тоже смотрел на ресурсы. К сожалению, идентификатор ресурса не стабилен от одной версии Windows к следующей :( – DougN

4

Это непросто. Эти строки являются частными данными для Windows Explorer, и поэтому они могут (и, вероятно, делать) изменять между релизами. Вы можете взломать что-то там, где вы делаете много проверки версий и читаете соответствующую строку ресурса, но это похоже на потерю битвы. Что вы пытаетесь достичь?

+0

У меня есть приложение для мониторинга файлов, которое предупреждает пользователей о создании новых каталогов. Пользователи не хотят получать предупреждения о «Новой папке» и то через несколько мгновений будет предупрежден о «новой папке», переименованной в «Мои документы». Поэтому я хотел бы уловить и проигнорировать это первое предупреждение. Признать «новую папку», однако. – DougN

+0

Что произойдет, если Пользователь не переименовал его? Кроме того, как сказал кто-то другой, это не поможет вам, если они создадут несколько новых папок («Новая папка (2)» и т. д.) – Luke

+0

Правда, есть угловые случаи, с которыми я не могу справиться. Но я бы предпочел обрабатывать 80% случаев для большинства пользователей. – DougN

-1

Если вы хотите обрабатывать 80% случаев, вы можете начать с «Новая папка».

Как я думаю, вы находитесь в корпоративной среде, вы можете вернуть имена папок в хранилище, а затем через неделю (или в любое время) вы получите имена; обновите приложение; выпустит новую версию, которая понравится пользователям. (затем опубликуйте результаты здесь)

Вы можете предварительно протестировать свое приложение на платформе, которую вы подозреваете в использовании пользователями. для получения первой серии имен папок.

Это позволит избежать проблемы с конкретным кодом с каждой из платформ, на которые вы смотрите.

EDIT Ну я получаю вторую мысль о том, что, я думаю, вы могли бы хотеть, чтобы предупредить пользователя о том, что «Новая папка», если это не было переименовывать через некоторое время (скажем, в минуту)? то, наверное, вам нужно будет добавить список и таймер ...

Смежные вопросы