2009-05-28 26 views
19

Tôi đã có nguyên nhân cần một nhãn có phông chữ lớn trên biểu mẫu Delphi và nhận thấy rằng các đường cong của nó vẫn hơi bị lởm chởm. Tôi so sánh điều này với cùng kích thước và phông chữ trong MSWord mượt mà hơn nhiều. Sau khi nghiên cứu tôi tìm thấy mã số cho phép tôi làm trơn các phông chữ của mình nhưng nó lộn xộn và tôi đã tự hỏi liệu có cách nào tốt hơn không? Nhìn trong nguồn VCL, TFont dường như gắn bó với NONANTIALIASED_QUALITY đó là thay vì bực bội ...Làm mịn phông chữ ở Delphi

Cảm ơn Bri

procedure TForm1.SetFontSmoothing(AFont: TFont); 
var 
    tagLOGFONT: TLogFont; 
begin 
    GetObject(
    AFont.Handle, 
    SizeOf(TLogFont), 
    @tagLOGFONT); 
    tagLOGFONT.lfQuality := ANTIALIASED_QUALITY; 
    AFont.Handle := CreateFontIndirect(tagLOGFONT); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    I : integer; 
begin 
    For I :=0 to ComponentCount-1 do 
    If Components[I] is TLabel then 
     SetFontSmoothing(TLabel(Components[I]).Font); 
end; 
+3

Vì vậy, mã này có hoạt động (và bạn chỉ muốn làm sạch nó và tìm một số cách dễ dàng) hoặc nó vẫn không đủ mượt hoặc không hoạt động? – schnaader

+0

Phần nào của mã này bạn cho là lộn xộn? –

+0

Có vẻ như lãng phí mà tôi đã phải chọc mỗi phông chữ trên mỗi nhãn khi VCL đã làm điều này. Tôi đã tìm kiếm thứ gì đó mà tôi có thể ghi đè hoặc phân lớp nhưng không có may mắn. Tôi đoán đây là cách duy nhất để đạt được những gì tôi muốn. Bri –

Trả lời

29

Bạn có thể lừa VCL để tạo lớp của riêng bạn kế thừa từ TLabel. Đây là mã chứng minh-khái niệm, được thử nghiệm với Delphi 4, sẽ giúp bạn bắt đầu.

Tạo một đơn vị mới cho lớp TLabel riêng bạn:

unit AntiAliasedLabel; 

interface 

uses 
    Windows, Messages, SysUtils, Controls, StdCtrls, Graphics; 

type 
    TLabel = class(StdCtrls.TLabel) 
    private 
    fFontChanged: boolean; 
    public 
    procedure Paint; override; 
    end; 

implementation 

procedure TLabel.Paint; 
var 
    LF: TLogFont; 
begin 
    if not fFontChanged then begin 
    Win32Check(GetObject(Font.Handle, SizeOf(TLogFont), @LF) <> 0); 
    LF.lfQuality := ANTIALIASED_QUALITY; 
    Font.Handle := CreateFontIndirect(LF); 
    fFontChanged := TRUE; 
    end; 
    inherited; 
end; 

end. 

Bây giờ thay đổi đơn vị mẫu của bạn có chứa nhãn, thêm các đơn vị AntiAliasedLabelsauStdCtrls. Điều này dẫn đến lớp học của riêng bạn AntiAliasedLabel.TLabel được tạo ở nơi thông thường StdCtrls.TLabel sẽ được tạo.

+0

+1 giải pháp rất thú vị! – jpfollenius

+4

+1 Woah - Tôi không biết bạn có thể lấy đi những thủ đoạn như thế. Cảm ơn vì làm tôi sáng mắt ra! – robsoft

+0

Rất, rất, rất, rất, rất, rất, rất .... NICE! Cảm ơn bạn đã lừa này dễ dàng. – Codebeat

3

Cách đơn giản nhất là để tạo ra thành phần của riêng bạn dựa trên TLabel, chẳng hạn như TSmoothLabel hoặc TAntiAliasedLabel và thêm mã làm mịn của bạn vào đó. Sau đó, bạn sử dụng thành phần của bạn thay vì TLabel chuẩn.

+0

Đúng, nhưng tôi đang tải một DFM hiện có chỉ định lớp TLabel, do đó đề xuất của bạn có thể hoạt động nếu có cách đăng ký lại TLAbel. Bri –

+1

Có một cách nhưng nó đòi hỏi phải thay thế mục nhập VMT.NewInstance VMT bằng một phương thức riêng khi chạy. JCL (Thư viện mã JEDI) có các chức năng để thực hiện việc này. –

+3

@Brian: Tại sao bạn không thể sửa các tệp DFM và PAS (từ bên ngoài IDE) để sử dụng lớp mới của bạn? Thay thế: Nếu bạn đang sử dụng phiên bản Delphi hỗ trợ chúng, bạn có thể sử dụng trình trợ giúp lớp cho TLabel. (Chỉ định Delphi nào trong tương lai.) Tôi không khuyên bạn nên sử dụng route helper class nếu có cách nào khác, bởi vì nó sẽ ảnh hưởng đến bất kỳ TLabel nào nằm trong phạm vi của nó. –

7

IMHO, VCL phải kiểm tra Làm mịn phông chữ mặc định của hệ thống và áp dụng làm mặc định lúc chạy. Nếu không, ít nhất nó nên mặc định để làm mịn hợp lý hơn. Người ta có thể tranh luận, trong trường hợp này, ClearType sẽ là một mặc định tốt hơn, xem xét> 50% màn hình những ngày này là LCD (và lớn hơn 50% các máy đang chạy XP hoặc tốt hơn).

Đây là một hack được thừa nhận (và như Ken White đề cập, không phải là cách tiếp cận tốt nhất nếu có lựa chọn thay thế), nhưng tôi cần một cách để sửa lỗi này trên toàn cầu cho các biểu mẫu có chứa hàng trăm loại thành phần của bên thứ ba. không thực tế).

Tôi đã thay đổi mặc định Font chất lượng trong Graphics.pas, TFont.GetHandle như sau:

// lfQuality: = DEFAULT_QUALITY;

lfQuality: = 5; // (HACK) CLEARTYPE_QUALITY, lực lượng ClearType

5

Từ:. http://objectmix.com/delphi/725245-tlabel-antialiasing-possibile-3.html

"chỉ đơn giản là sử dụng một font có hỗ trợ phông chữ mịn nên sửa lỗi này Delphi sử dụng (hoặc ít nhất là sử dụng để sử dụng) MS Sans Serif là mặc định, không phải là hỗ trợ làm mịn (ClearType hoặc cách khác) nếu bạn đặt phông chữ thành Tahoma (tốt nhất cho XP) hoặc Giao diện người dùng Segoe (tốt nhất cho Vista), bạn sẽ tự động làm mịn phông chữ theo cài đặt hệ thống trong ứng dụng Delphi của bạn. "

Xác nhận, nó hoạt động tốt đẹp bằng cách sử dụng Delphi XE và Win7.Bận rộn thay đổi tất cả phông chữ của tôi ngay bây giờ ;-)

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