2014-11-11 17 views
6

Tôi đang gặp sự cố với các ký tự Unicode được hiển thị không chính xác trên giao diện người dùng của tôi. Tôi có một DLL tài nguyên chỉ chứa một bảng chuỗi được sử dụng cho nội địa hóa giao diện người dùng. Tôi tạo DLL trong Delphi XE3 với một dự án chỉ DLL (chỉ có {$R 'lang.res' 'lang.rc'} trong tệp DPR, và cho tôi lang.dll). Tôi đã xác minh rằng tệp lang.rc của tôi có định dạng UTF-8 với ngắt dòng CRLF của Windows. Khi tôi tải các chuỗi từ DLL, các ký tự Unicode bị lộn xộn trên giao diện. Dưới đây là một số chi tiết.Đặt chú thích Unicode từ chuỗi chuỗi tài nguyên DLL

Một đoạn mã từ bảng chuỗi:

STRINGTABLE 
{ 
59,"180˚" 
60,"90˚ CW" 
61,"90˚ CCW" 
} 

Dưới đây là đoạn mã mà minh họa cho vấn đề tôi đang gặp với các ký tự Unicode:

// explicitly assigning the degrees character shows 180˚ properly 
ImageMenu180Action.Caption := '180˚'; 

// getting the resource from the DLL shows some weird two-character string for the degrees character 
ImageMenu90CWAction.Caption := TLangHelper.LoadStr(IDS_ImageMenuRotationCW90); 

// OutputDebugString shows the degrees character in the debugger output correctly 
OutputDebugString(PChar('IDS_ImageMenuRotationCW90: '+TLangHelper.LoadStr(IDS_ImageMenuRotationCW90))); 

Dưới đây là chức năng Delphi của tôi sử dụng để tải các chuỗi từ tài nguyên DLL:

class function TLangHelper.LoadStr(ResourceId: Integer):String; 
var 
    Buff: String; 
    L: Integer; 
begin 
    Result := ''; 
    if LangDllHandle = 0 then begin 
    LangDllHandle := LoadLibrary(LANGUAGE_DLL_LOCATION); 
    if LangDllHandle = 0 then begin 
     ShowMessage('Error loading language localization resources.'); 
    end; 
    end; 
    if LangDllHandle <> 0 then begin 
    L := 1024; 
    SetLength(Buff, L+1); 
    LoadString(LangDllHandle, ResourceId, PChar(Buff), L); 
    Result := String(PChar(Buff)); 
    end; 
end; 

Mọi đề xuất?

THEO-UP:

Đối với chữ Hán, tôi đã có thêm một L trước các định nghĩa chuỗi trong file rc để biên soạn DLL nhận chúng như Unicode. Ví dụ (tiếng Anh, Trung Quốc truyền thống, tiếng Trung giản thể, tiếng Pháp):

STRINGTABLE 
{ 
35,"Status Bar" 
1035,L"狀態欄" 
2035,L"状态栏" 
3035,"Barre d'état" 
} 
+1

Chuỗi không phải là UTF-16 thay vì UTF-8? –

+0

Trường hợp bạn thấy rằng việc sử dụng UTF-8 trong tệp .rc của bạn sẽ dẫn đến việc mã hóa đúng trong tệp .res? Tôi tìm thấy [một tài liệu tham khảo từ năm 2002] (http://www.delphipages.com/forum/archive/index.php/t-63889.html) mà nói rằng bạn cần phải sử dụng một tùy chọn dòng lệnh đặc biệt để brcc32 ('- c65001') để cho nó biết mã hóa của tệp .rc. Tôi nghi ngờ IDE sử dụng tùy chọn đó theo mặc định. –

+1

@RobKennedy Điều đó làm việc, đánh giá cao nó nhiều. Đối với thiếu tài liệu nói cách khác (tôi không thể tìm thấy bất kỳ), tôi giả định brcc32 sẽ mặc định để mã hóa văn bản của tập tin. Giả định xấu. Nó có vẻ như công cụ này nên được tài liệu tốt hơn. Tôi không thể là người duy nhất cố gắng làm điều này. Tôi sẽ chấp nhận một câu trả lời nếu bạn muốn viết một câu trả lời. – spurgeon

Trả lời

6

tôi thấy a reference from 2002 chỉ ra rằng bạn cần phải nói với trình biên dịch tài nguyên như thế nào các tập tin rc được mã hóa. Đối với UTF-8, đó là mã trang 65001, vì vậy bạn muốn chạy này:

 
brcc32 -c65001 lang.rc 

Sau đó, tất nhiên, bạn muốn loại bỏ các phần 'lang.rc' từ chỉ thị $R trong mã của bạn vì bạn không còn muốn IDE để tự gọi trình biên dịch tài nguyên.

Nếu phiên bản Delphi của bạn đủ gần đây, bạn có thể giữ chỉ thị $R đầy đủ và thay vào đó đặt tùy chọn -c65001 trong các tùy chọn dự án của bạn.

Thật khó để biết mã hóa của tệp chỉ bằng cách xem tệp. Có thể có nhiều dự đoán hợp lệ. Tùy chọn -c được ghi lại nhưng the documentation không đề cập đến thời điểm bạn cần sử dụng hoặc IDE sử dụng khi chạy trình biên dịch tài nguyên. IDE có lẽ chỉ sử dụng mặc định, giống như brcc32.exe, là trang mã ANSI mặc định của hệ thống.

+0

Bạn không thể chỉ đặt Dự án -> Tùy chọn -> Trình biên dịch tài nguyên -> Tùy chọn bổ sung thành '-c65001' (sử dụng Delphi XE3 ở đây)? Điều đó làm việc cho tôi. – spurgeon

+0

Cảm ơn bạn đã đề cập đến điều đó. Tôi đã cập nhật câu trả lời. Phiên bản cuối cùng của Delphi tôi đã sử dụng không có tùy chọn đó. –

+0

Câu trả lời rất hay cho một câu hỏi rất hay! –

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