如何在Delphi中调用EnumSystemLocales?

时间:2011-12-23 15:13:34

标签: delphi winapi internationalization globalization delphi-5

我试图在Delphi中调用EnumSystemLocalesFor example:

{ Called for each supported locale. }
function LocalesCallback(Name: PChar): BOOL; stdcall;
begin
   OutputDebugString(Name);
   Result := Bool(1); //True
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   EnumSystemLocales(@LocalesCallback, LCID_SUPPORTED);
end;

问题是回调只被调用一次。

注意: EnumSystemLocales 返回true,表示成功。

EnumSystemLocales的评论说我的回调必须返回 true 才能继续枚举(或者更准确地说,不得返回 false 继续枚举):< / p>

  

该函数通过传递区域设置标识符来枚举区域设置,其中一个位于   一段时间,到指定的应用程序定义的回调函数。这个   继续,直到所有已安装或支持的区域设置标识符   已被传递给回调函数或回调函数   返回FALSE。

documentation of the callback function上:

BOOL CALLBACK EnumLocalesProc(
  __in  LPTSTR lpLocaleString
);

评论者遇到了“非虚假”定义的问题:

  

此函数必须返回1,而不是(DWORD)-1才能继续处理

这让我觉得delphi的定义是

True: BOOL;

与Window不同。 (这就是为什么我尝试了BOOL(1)的返回值 - 它仍然失败了。)

接下来我想知道它是否应该是stdcall

无论哪种方式,有人可以建议如何在Delpi中致电EnumSystemLocales


修改:还尝试了:

  • Result := BOOL(-1);
  • Result := BOOL($FFFFFFFF);
  • Result := BOOL(1);
  • Result := True;

3 个答案:

答案 0 :(得分:9)

尝试像这样声明LocalesCallback函数

function LocalesCallback(Name: PChar): Integer; stdcall;

检查此示例

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,
  SysUtils;

function LocalesCallback(Name: PChar): Integer; stdcall;
begin
   Writeln(Name);
   Result := 1;
end;

begin
  try
    EnumSystemLocales(@LocalesCallback, LCID_SUPPORTED);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

答案 1 :(得分:4)

此问题是由Windows版本5.1中观察到的WinAPI错误引起的 WinNls EnumXXX函数系列(并且,根据评论,可能还有其他几个)仅仅将(BOOL)1识别为(BOOL)TRUE,并且如果回调返回任何其他returnValue != (BOOL)FALSE,将停止枚举。

这是我发现的最具语义性的解决方法:

  LongWord(Result) := LongWord(True);     // WINBUG: WinNls functions will continue
                                          // enumeration only if exactly 1 was returned
                                          // from the callback

答案 2 :(得分:2)

如果您坚持使用BOOL类型作为回调函数结果,请使用:

function LocalesCallback(Name: PChar): BOOL; stdcall;
begin
   OutputDebugString(Name);
   LongWord(Result) := 1;
end;

因为Bool(1) = $FFFFFFFF