我试图在Delphi中调用EnumSystemLocales
。 For 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;
答案 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
。