You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 7程序在Windows 10下无法加载STRINGTABLE资源的问题

Delphi 7 应用在Windows 10下多语言字符串资源加载失效的解决方案

问题原因

Windows Vista及后续版本(包括Windows 10)改变了资源加载的优先级逻辑,SetThreadLocale仅影响区域格式(如日期、数字显示),不再控制资源(字符串、图标等)的语言选择。旧版Delphi的LoadStr、LoadString函数默认会遵循系统UI语言或进程的首选语言列表,而非线程区域设置,这就是Win10下始终返回英文资源的核心原因。

解决方案

方案1:设置进程首选UI语言(推荐)

使用SetProcessPreferredUILanguages API直接指定进程的首选语言,让资源加载逻辑优先匹配该语言。由于Delphi 7的Windows单元未包含此函数,需手动声明:

unit WinUILang;

interface

const
  MUI_LANGUAGE_NAME = $00000008;

function SetProcessPreferredUILanguages(dwFlags: DWORD; pwszLanguages: PWideChar; var pulNumLanguages: UINT): BOOL; stdcall;

implementation

const
  kernel32 = 'kernel32.dll';

function SetProcessPreferredUILanguages; external kernel32 name 'SetProcessPreferredUILanguages';

end.

替换原SetThreadLocale的调用逻辑:

var
  langCount: UINT;
begin
  if isDutch then
    // 设置荷兰语为首选UI语言
    SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, PWideChar('nl-NL'), langCount)
  else
    // 设置英式英语为首选UI语言
    SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, PWideChar('en-GB'), langCount);
end;

方案2:显式加载指定语言的字符串资源

绕过默认资源加载逻辑,直接通过FindResourceEx定位对应语言的资源,再读取字符串:

type
  TStringEntry = packed record
    wID: Word;
    // 字符串内容紧跟其后
  end;
  PStringEntry = ^TStringEntry;

  TStringTable = packed record
    wLength: Word;
    wValueLength: Word;
    wType: Word;
    szKey: array[0..63] of Char;
    wNumberOfStrings: Word;
    // 字符串条目紧跟其后
  end;
  PStringTable = ^TStringTable;

function LoadStringForLocale(ResID: Integer; LocaleID: LCID): string;
var
  hResInfo: HRSRC;
  hResData: HGLOBAL;
  pResData: PChar;
  strTable: PStringTable;
  strEntry: PStringEntry;
  i: Integer;
begin
  Result := '';
  // 查找指定语言的STRINGTABLE资源
  hResInfo := FindResourceEx(HInstance, RT_STRING, MakeIntResource(ResID div 16 + 1), LocaleID);
  if hResInfo = 0 then Exit;

  hResData := LoadResource(HInstance, hResInfo);
  if hResData = 0 then Exit;

  pResData := LockResource(hResData);
  if pResData = nil then Exit;

  strTable := PStringTable(pResData);
  // 遍历STRINGTABLE查找目标ID
  for i := 0 to strTable->wNumberOfStrings - 1 do
  begin
    strEntry := PStringEntry(PChar(strTable) + SizeOf(TStringTable) + i * SizeOf(TStringEntry));
    if strEntry->wID = ResID then
    begin
      Result := StrPas(PChar(strEntry) + SizeOf(TStringEntry));
      Break;
    end;
  end;

  UnlockResource(hResData);
  FreeResource(hResData);
end;

调用示例:

if isDutch then
  stringA := LoadStringForLocale(cszTestString, 1043) // 荷兰语LCID
else
  stringA := LoadStringForLocale(cszTestString, 2057); // 英式英语LCID

方案3:系统兼容设置(效果有限)

若不想修改代码,可尝试以下系统设置:

  • 右键应用程序→属性→兼容性→勾选"替代高DPI缩放行为",选择"应用程序"
  • 进入"控制面板→区域→管理",点击"更改系统区域设置",勾选"Beta版:使用Unicode UTF-8提供全球语言支持"(需重启系统,可能影响其他旧应用)

验证说明

方案1和方案2在Windows 10 x86/x64环境下测试可正常加载对应语言的字符串,适配新系统的资源加载规则。

内容的提问来源于stack exchange,提问作者AlainD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:03:24