2010-03-31 35 views
6

Tôi có một hình thức delphi 7:Delphi 7 - Tại sao Windows 7 thay đổi mã hóa các ký tự trong thời gian chạy?

Form http://i44.tinypic.com/13ymott.jpg

và mã của tôi:

Code http://i44.tinypic.com/x1gh9c.jpg

khi tôi chạy hình thức này trong Windows 7, tôi thấy:

Windows7Form http://i41.tinypic.com/riglzl.jpg

Trong thời gian thiết kế, biểu mẫu có chữ cái đánh bóng trong linh sam t nhãn, nhưng nó không có chúng trong thời gian chạy. Có vẻ ok trên Vista hoặc Windows XP. Khi tôi đặt chú thích của nhãn thứ hai trong mã, mọi thứ hoạt động tốt và các ký tự được mã hóa chính xác.

5 mã đầu tiên của nhãn hàng đầu trên Windows 7: 65 97 69 101 83

First 5 quy tắc ứng nhãn hàng đầu trên Windows Vista/XP: 165 185 202 234 140

5 mã Trước nhãn đáy trên mọi hệ thống: 165 185 202 234 140

Windows 7 thay đổi mã hóa, tại sao? Cài đặt hệ thống của tôi có vẻ ổn. Tôi đã đặt ngôn ngữ thích hợp cho các ứng dụng không phải unicode trong bảng điều khiển.

EDIT

Vấn đề này không chỉ liên quan với các nhãn trên hình thức, mà còn với FastReport (nơi chuyển sang EASTERN_CHARSET giải quyết vấn đề) hoặc với accesing Microsoft Excel thông qua giao diện COM.

+0

Tôi không quen với Delphi, nhưng có thể Trình thiết kế biểu mẫu cho phép chỉ định mã hóa khác với mã hóa mặc định của bạn (ví dụ: Windows-1250) không? Và phiên bản nào của Delphi là cái này? Hỗ trợ Unicode IIC đã được thêm vào chỉ gần đây ... –

+0

@ 0xA3 Đây là Delphi 7 và nó không phải là ứng dụng unicode, nhưng tôi thiết lập ngôn ngữ đánh bóng cho các ứng dụng không unicode trong cài đặt khu vực. Đó là lý do tại sao Label2 hiển thị chính xác, nhưng đầu tiên vẫn không hoạt động. – LukLed

+0

Bạn đã kiểm tra xem Label1 và Label2 đã được xác định trong DFM chưa? Làm thế nào là Label1.caption lưu trong DFM? –

Trả lời

1

Câu trả lời cho câu hỏi này giải quyết vấn đề của tôi:

GetThreadLocale returns different value than GetUserDefaultLCID?

Một giải pháp:

Điều kỳ lạ, chúng tôi thấy là chuyển sang một khác nhau cài đặt khu vực thông qua Bảng điều khiển và sau đó chuyển trở lại NZ giải quyết vấn đề. Tôi tò mò muốn biết liệu cách giải quyết tương tự có giải quyết nó cho bạn chỉ để xác minh rằng chúng ta đang nhìn thấy hiện tượng tương tự.

và thứ hai:

initialization 
    SetThreadLocale(LOCALE_USER_DEFAULT); 
    GetFormatSettings; 

Cả hai giải pháp làm việc tuyệt vời và vấn đề với ứng dụng sẽ biến mất.

0

Kiểm tra thuộc tính Font.Charset của nhãn. Trong khi tôi không biết làm thế nào nó đã thay đổi (nó được tạo sẵn cho một số thuật sĩ?) - nó có thể có một miền địa phương khác nhau từ hệ thống một.

+0

Biểu mẫu có Font.Charset được đặt thành DEFAULT_CHARSET và các nhãn có ParentFont được đặt thành true. – LukLed

2

Tôi đã tái tạo hành vi trong Delphi 2010 để giành được XP.

procedure Button1Click(Sender : TObject); 
begin 
    ShowMessage(AnsiString(Label1.Caption)); 
end; 

Trong trường hợp này, việc chuyển đổi Label1.Caption thành AnsiString được thực hiện thông qua WideCharToMultiByte (Windows API).

API có các lưu ý sau:

Các trang mã ANSI có thể khác nhau trên các máy tính khác nhau, hoặc có thể được thay đổi cho một máy tính duy nhất, hàng đầu đến hỏng dữ liệu. Để có kết quả nhất quán, các ứng dụng nên sử dụng Unicode, chẳng hạn như UTF-8 hoặc UTF-16, thay vì mã cụ thể , trừ khi các tiêu chuẩn cũ hoặc dữ liệu định dạng ngăn sử dụng Unicode. Nếu không thể sử dụng sử dụng Unicode, ứng dụng phải gắn thẻ dữ liệu luồng với mã hóa thích hợp tên khi giao thức cho phép. HTML và Tệp XML cho phép gắn thẻ nhưng văn bản tệp thì không.

Vì vậy, tôi đoán tốt nhất là sự khác biệt về hành vi đến từ thực tế là phiên bản Windows 7 bạn có một CodePage hoạt động khác với trên các trạm vista/XP của bạn.

Tôi vẫn phải tìm cách tải trang mã hoạt động trên hệ thống ... Đoán tốt nhất của tôi là nó được xác định trong cài đặt khu vực trong bảng điều khiển. Nhưng tôi vẫn cần phải xác minh điều này ...

+0

Cài đặt Bảng điều khiển có vẻ ổn. Tôi chắc chắn rằng đây là vấn đề của Windows 7 có cách tiếp cận khác để hội tụ chuỗi, nhưng làm thế nào để giải quyết nó? – LukLed

+1

Hãy thử gọi GetThreadLocale từ ứng dụng của bạn trên hệ thống khác nhau, chỉ để đảm bảo cùng một giá trị được trả về trước khi chúng tôi điều tra thêm ... –

+0

Ý tưởng hay. Tôi sẽ làm điều đó vào ngày mai. – LukLed

2

Bạn gặp phải những gì tôi coi là "lỗi" trong phương pháp TWriter.WriteString và TWriter.ReadString. Hai phương thức này được Delphi sử dụng trong nội bộ để di chuyển TLabel.Caption của bạn từ đối tượng trực tiếp thực tế tại thời điểm thiết kế vào tệp DFM và sau đó quay trở lại đối tượng trực tiếp tại thời gian chạy.

Nếu bạn nhìn vào mã cho hai quy trình được đề cập, bạn sẽ thấy (trong trường hợp tôi giả định) rằng nội dung thực tế đi vào luồng được chuyển đổi sang Unicode bằng cách sử dụng trang mã mặc định của hệ điều hành! Đó là tốt và dandy miễn là trang mã được sử dụng trên máy phát triển chính xác phù hợp với trang mã được sử dụng trên máy thử nghiệm, và chúng có thể không khớp, và đó là khả năng nhất tại sao bạn nhận được lỗi. Xin lưu ý rằng EASTEUROPEAN_CHARSET bạn đang thiết lập cho Phụ đề trên biểu mẫu hoàn toàn không có giá trị, bởi vì phương pháp TWriter.WriteString không có ý tưởng về nó!

Tôi đã có một báo cáo lỗi về vấn đề này trên QC, nó đã ở đó trong nhiều năm ... Họ có thể nghĩ rằng đó là "theo thiết kế", nhưng tôi không nghĩ rằng đó là một thiết kế rất tốt.

Giải pháp tôi muốn giải quyết là chuyển đổi nhanh sang Delphi 2010. Tôi là nhà phát triển Delphi ở Romania và tôi đã gặp rất nhiều vấn đề với loại công cụ này, nhưng giờ đây tất cả đều là trong quá khứ vì Delphi 2010 là UNICODE nên tôi không còn phải lo lắng về việc chuyển đổi trang mã.

Nếu bạn không thể chuyển sang Delphi 2010, bạn có thể muốn "hack" tệp Classes.pas và thay đổi thường trình TReader.ReadString để luôn thực hiện chuyển đổi bằng cách sử dụng trang mã CỦA BẠN, chứ không phải hệ thống mặc định.

+0

Rất vui được biết, nhưng sự cố này chỉ liên quan đến Windows 7 và tôi đã tìm được giải pháp. Chuyển sang Delphi 2010 sẽ rất phức tạp. Ứng dụng của tôi sử dụng rất nhiều JVCL 2 và các thành phần cũ khác và có khoảng 1000 biểu mẫu. Delphi 2010 chờ đợi trên kệ để có thêm thời gian rảnh rỗi. – LukLed

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