2011-12-23 30 views
8

tôi đang cố gắng gọi EnumSystemLocales ở Delphi. For example:Làm thế nào để gọi EnumSystemLocales trong Delphi?

{ 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; 

Vấn đề là gọi lại chỉ được gọi một lần.

Lưu ý:EnumSystemLocales trả về true, cho biết thành công.

Các nhận xét của EnumSystemLocales nói rằng callback tôi phải trả lại đúng để tiếp tục liệt kê (hay đúng hơn, không phải trả lại sai để tiếp tục liệt kê):

Chức năng liệt kê miền địa phương bằng cách định danh locale , một tại một lần, với hàm gọi lại do ứng dụng xác định. Điều này tiếp tục cho đến khi tất cả các mã định danh đã được cài đặt hoặc hỗ trợ đã được chuyển đến hàm gọi lại hoặc hàm gọi lại trả về FALSE.

Trên documentation of the callback function:

BOOL CALLBACK EnumLocalesProc(
    __in LPTSTR lpLocaleString 
); 

một commenter đã đi qua một vấn đề với định nghĩa của "không sai":

chức năng này phải trả về 1, không (DWORD) - 1 để tiếp tục xử lý

Điều này khiến tôi nghĩ định nghĩa của delphi là

True: BOOL; 

khác với của Window. (Đó là lý do tại sao tôi đã thử một giá trị trả về của BOOL(1) - mà vẫn không thành công).

Tiếp theo, tôi tự hỏi nếu nó thậm chí không được coi là stdcall.

Dù bằng cách nào, ai đó có thể đề xuất cách thức, trong Delpi, gọi EnumSystemLocales?


Sửa: Cũng thử:

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

Vấn đề dường như được tập trung vào cách thức để viết các hàm callback thay vì gọi EnumSystemLocales. Tôi có đúng không? – menjaraz

+0

Phiên bản Windows? – OnTheFly

+0

@menjaraz Nó rất tốt có thể được - nhưng tôi không muốn giảm giá bất kỳ possiblity. –

Trả lời

8

thử declarating các LocalesCallback chức năng như kiểm tra

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

này mẫu này

{$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. 
+0

Tuyệt vời, bạn thắng! –

+0

Chúng tôi có thể gọi đó là giải pháp thay thế không? – menjaraz

+3

@menjaraz - Đó là giải pháp cho thiếu/kiểu dữ liệu không tương thích trong ngôn ngữ. Xem http://qc.embarcadero.com/wc/qcmain.aspx?d=72852 –

2

Nếu bạn nhấn mạnh vào việc sử dụng BOOL kiểu cho kết quả hàm callback, sử dụng này:

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

Bool(1) = $FFFFFFFF.

+0

Đó có phải là cách giải quyết hoặc có vấn đề về trình biên dịch khi truyền sang loại BOOL không? – menjaraz

+0

AFAIK trong C cũ loại BOOL là kiểu Integer, và true =! False; kể từ false = 0, điều đó có nghĩa là true = không 0 = $ FFFFFFFF (giả sử sizeof (bool) = 4). Đó là phỏng đoán của tôi, tôi có thể sai. – kludg

+0

C không có kiểu boolean nào cho đến C99. INT (số nguyên) có thể được kiểm tra mà không có == mặc dù, và sau đó ngữ nghĩa bạn tên là hợp lệ (false = 0 true =! False). Nhưng các API có các quy ước khác nhau. GTK GBoolean là như nhau. Chúng thực sự gần gũi hơn với kiểu boolean Pascal, nhưng nó tồn tại trong Delphi với 8 bit. –

3

Vấn đề này xảy ra do lỗi WinAPI, quan sát thấy trong phiên bản Windows 5.1 WinNls EnumXXX chức năng gia đình (và, theo các ý kiến, có lẽ một số người khác) chỉ được công nhận một cách chính xác (BOOL)1 như (BOOL)TRUE và sẽ ngừng liệt kê nếu gọi lại trả về bất kỳ khác returnValue != (BOOL)FALSE .

Đây là một workaround ngữ nghĩa nhất tôi đã tìm ra:

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

Vấn đề là có quá nhiều phép toán để chọn (http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx) –

+1

@IanBoyd, không thực sự, [nguồn tài liệu chính của chúng tôi ] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd317822%28v=vs.85%29.aspx) nêu rõ loại chúng tôi (nhà phát triển khách hàng) phải sử dụng. Vấn đề là những gì mà NLS subsytem không tuân thủ các quy tắc riêng của nó. Và những gì mr. Chen miễn cưỡng xác nhận trong cuốn nhật ký của mình - là những gì mà các nhà quản lý dự án MS không thể điều phối được phong cách chung giữa các nhóm, cho phép được mô tả * kiểu zoo * để trải rộng trên mã-base. – OnTheFly

+0

hungarian có tiền tố kiểu sở thú. –

Các vấn đề liên quan