How to call EnumSystemLocales in Delphi?

I am trying to call EnumSystemLocales in Delphi. 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; 

The problem is that the callback is called only once.

Note: EnumSystemLocales returns true, indicating success.

The EnumSystemLocales say that my callback should return true to continue the enumeration (or rather, should not return false to continue the enumeration):

The function lists the locales by passing the locale identifiers, and in time, to the specified callback function defined by the application. This continues until all set or supported local identifiers have been passed to the callback function or the callback function returns FALSE.

In the documentation of the callback function :

 BOOL CALLBACK EnumLocalesProc( __in LPTSTR lpLocaleString ); 

the commenter has encountered the problem of defining "not false":

This function should return 1, not (DWORD) -1 to continue processing

It makes me think the definition of delphi

 True: BOOL; 

different from the window. (That's why I tried to return a BOOL(1) value - which still doesn't work).

Next, I wonder if this should be stdcall .

Anyway, can anyone suggest how to call EnumSystemLocales ?


Edit : Also tried:

  • Result := BOOL(-1);
  • Result := BOOL($FFFFFFFF);
  • Result := BOOL(1);
  • Result := True;
+8
winapi delphi internationalization globalization delphi-5
source share
3 answers

try declaring a LocalesCallback function like this

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

check this sample

 {$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. 
+8
source share

This problem occurs because of the WinAPI error observed in Windows version 5.1. The WinNls EnumXXX family of functions (and, according to the comments, possibly a few others) will recognize (BOOL)1 exactly as (BOOL)TRUE and stop enumeration if any other callback returns returnValue != (BOOL)FALSE .

Here is the most semantic workaround I understood:

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

If you insist on using a BOOL type for the result of the callback function, use this:

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

because Bool(1) = $FFFFFFFF .

+2
source share

All Articles