Локализованные строковые значения для строк размера КБ, МБ, ГБ и т.д.?

#winapi #localization

#winapi #локализация

Вопрос:

Где эта строка ресурсов хранится в Windows? Мне нужно точно отображать размер на родном языке установленной Windows.

Комментарии:

1. Что заставляет вас думать, что эти строки хранятся в ресурсах, к которым вы можете получить доступ? Вы должны локализовать свои собственные строки, а не использовать строки из ОС.

2. CLDR содержит необходимую информацию. У каждой локали есть правило, как использовать K, M, G и т.д., А затем CLDR содержит локализованные имена каждого фактора, как длинные, так и короткие имена. Имейте в виду, что некоторые языки работают не с тысячами, а, например, с 10 000 (японский)

3. @Jaska спасибо за информацию, я прочитаю об этом

Ответ №1:

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

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

Ответ №2:

Это возможно с помощью библиотеки дисковых квот, которая доступна начиная с Windows XP:

 function FindStringResourceEx(AInstance: HINST; AStringID: UINT; ALangID: UINT): PWideChar;
var
  Res: HRSRC;
  LoadedRes: HGLOBAL;
  I: Integer;
begin
  Result := nil;
  Res := FindResourceEx(AInstance, RT_STRING, MAKEINTRESOURCE(AStringID div 16   1), ALangID);
  if Res <> 0 then begin
    LoadedRes := LoadResource(AInstance, Res);
    if LoadedRes <> 0 then
    try
      Result := PChar(LockResource(LoadedRes));
      if Assigned(Result) then
      try
        for I := 0 to (AStringID and 15) - 1 do
          Inc(Result, PWord(Result)^   1);
      finally
        UnlockResource(THandle(Result));
      end;
    finally
      FreeResource(LoadedRes);
    end;
  end;
end;

function GetSizeStrings(out sBytes, sKB, sMB, sGB, sTB, sPB, sEB: string): Boolean;
var
  hLib: HMODULE;
  sRes: string;
  I: Integer;
  SL: TStringList;
begin
  Result := False;
  hLib := LoadLibrary('dskquoui.dll');
  if hLib > 0 then
  try
    SL := TStringList.Create;
    try
      sRes := FindStringResourceEx(hLib, 14472, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
      Result := sRes <> '';
      if Result then begin
        sRes := sRes.Remove(0, 1);
        I := sRes.IndexOf(#$B);
        if I > -1 then
          sRes := sRes.Remove(I);
        SL.Delimiter := #2;
        SL.DelimitedText := sRes;
        sBytes := SL[0]; // bytes
        sKB    := SL[1]; // KB
        sMB    := SL[2]; // MB
        sGB    := SL[3]; // GB
        sTB    := SL[4]; // TB
        sPB    := SL[5]; // PB
        sEB    := SL[6]; // EB
      end;
    finally
      SL.Free;
    end;
  finally
    FreeLibrary(hLib);
  end;
  if not Result then begin
    sBytes := 'bytes';
    sKB    := 'KB';
    sMB    := 'MB';
    sGB    := 'GB';
    sTB    := 'TB';
    sPB    := 'PB';
    sEB    := 'EB';
  end;
end;