2010-03-23 95 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%的案例,您可以從「新建文件夾」開始。

正如我猜你在企業環境中,你可以將文件夾名稱存回存儲器,然後在一週(或任何時間)之後通過名稱獲得;更新你的應用;發佈新版本,讓用戶滿意。 (然後在此處發佈結果)

您可以在懷疑用戶使用的平臺範圍內搶先測試您的應用。獲取第一系列文件夾名稱。

這樣可以避免處理與您查看的每個平臺相關的特定代碼的問題。

編輯 嗯,我得到關於第二個想法,我猜你可能想提醒有關「新建文件夾」的用戶,如果它不是一段時間(一分鐘)後改名?那麼我想你會需要添加一個列表和一個計時器...