2011-12-06 20 views
5

Tôi đã thêm gợi ý cho các thành phần trên biểu mẫu của tôi. Khi các thành phần nhận được tiêu điểm, tôi muốn đặt chú thích của thành phần nhãn để hiển thị gợi ý.Hiển thị gợi ý

Tôi đã thêm một TApplicationEvents đối tượng và thiết lập các sự kiện OnShowHint để

procedure TImportFrm.ApplicationEvents1ShowHint(var HintStr: string; 
    var CanShow: Boolean; var HintInfo: THintInfo); 
begin 
    HelpLbl.Caption := HintStr; 
end; 

Tuy nhiên có vẻ như sự kiện ShowHint chỉ cháy với phong trào chuột. Có cách nào để kích hoạt mã gợi ý khi các thành phần nhận được tiêu điểm, mà không phải triển khai sự kiện OnEnter cho mỗi thành phần đơn lẻ trên biểu mẫu không?

+0

Bạn sử dụng gì, VCL hoặc FMX? – Kromster

+0

Tôi sử dụng VCL và XE2. –

Trả lời

4

Thêm một handler cho TScreen.OnActiveControlChange trong việc tạo form chính của bạn, và xử lý các gợi ý trong trường hợp:

type 
    TForm2=class(TForm) 
    ... 
    private 
    procedure ScreenFocusControlChange(Sender: TObject); 
    end; 

implementation 

procedure TForm2.FormCreate(Sender: TObject); 
begin 
    Screen.OnActiveControlChange := ScreenFocusControlChange; 
end; 

procedure TForm2.ScreenFocusControlChange(Sender: TObject); 
begin 
    Label1.Caption := ActiveControl.Hint; 
    Label1.Update; 
end; 

Lưu ý rằng Sender sẽ không làm bạn rất tốt; nó luôn là Screen. Bạn có thể lọc (ví dụ, chỉ thay đổi Label.Caption cho chỉnh sửa điều khiển) bằng cách kiểm tra ActiveControl:

if (ActiveControl is TEdit) then 
    // Update caption of label with ActiveControl.Hint 

Lưu ý rằng nếu bạn sẽ cần phải phân công lại sự kiện khi bạn hiển thị các hình thức con (một sự kiện trên mà dạng con), hoặc bạn sẽ luôn cập nhật nhãn của biểu mẫu gốc với các gợi ý. Cách đơn giản nhất để làm phân công lại là để cho mọi hình thức một handler OnActiveControlChange, và gán nó trong trường hợp của hình thức OnActivate và bỏ chỉ định nó trong OnDeactivate sự kiện:

procedure TForm1.FormActivate(Sender: TObject); 
begin 
    Screen.OnActiveControlChange := Self.ScreenActiveControlChange; 
end; 

procedure TForm1.FormDeactivate(Sender: TObject); 
begin 
    Screen.OnActiveControlChange := nil; 
end; 

này sẽ cho phép bạn cập nhật các điều khiển khác hơn Label1 trên mỗi biểu mẫu và chỉ sử dụng các thay đổi gợi ý trên biểu mẫu bạn muốn làm như vậy.

+0

Cảm ơn Ken. Sự kiện đó là chính xác những gì tôi đang tìm kiếm, tôi chỉ quên nhìn ra ngoài đối tượng TForm. –

4

Một giải pháp đơn giản là sử dụng OnIdle sự kiện:

procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean); 
begin 
    if Assigned(ActiveControl) then 
    Label1.Caption:= ActiveControl.Hint; 
end; 

Một giải pháp tiên tiến hơn là để ghi đè bảo vệ ActiveChanged phương pháp TForm:

type 
    TForm1 = class(TForm) 
    ... 
    protected 
    procedure ActiveChanged; override; 
    end; 

... 

procedure TForm1.ActiveChanged; 
begin 
    inherited; 
    if Assigned(ActiveControl) then 
    Label1.Caption:= ActiveControl.Hint; 
end; 

Nhận lấy nét và OnShowHint là những sự kiện hoàn toàn khác; OnShowHint cũng có thể được kích hoạt để kiểm soát không tập trung.

+1

+1 Để sử dụng OnIdle. Một gợi ý: sử dụng Screen.ActiveControl thay vì sau đó (Self) .ActiveControl để có được nó ứng dụng làm việc rộng; không chỉ cho TForm1, mà còn cho các dạng popup có thể và tương tự. – NGLN

+0

Đây là phương pháp tương tự tôi sử dụng trong bản demo "Con trỏ chuột ảo" TKinect của tôi ... hoạt động tốt! +1 – LaKraven

1

Tại sao bạn cần triển khai sự kiện OnEnter cho mỗi thành phần đơn lẻ? Bạn có thể tạo một trình xử lý sự kiện/phương thức chung chung như:

procedure TForm1.AnyControlEnter(Sender: TObject); 
begin 
    lbl1.Caption := TControl(Sender).Hint; 
end; 

và gán cho mọi thành phần bạn đã đặt trên biểu mẫu.

1

Bạn nói:

có vẻ như sự kiện ShowHint chỉ bắn với phong trào chuột

Đây là một hành vi bình thường. Vấn đề bạn có (đó là một dự đoán) là các gợi ý không được bắn trực tiếp. Đừng cố gắng giải quyết, những gì bạn cố gắng làm với MouseEnter chính xác là những gì đã xảy ra ... sự khác biệt duy nhất là bạn quên một điều gì đó ...

Giữ sự kiện ApplicationEvents1ShowHint() như bạn đã bước đầu thực hiện nhưng thêm này trong trường hợp hình thức constructor:

Application.HintPause := 1; 

Và sau đó gợi ý sẽ được hiển thị (hầu như) không chậm trễ.