delphidelphi-7linklabelcustom-drawtlabel

Implementing a TLabel with TabStop and FocusRect?


I'm using Delphi7 and I'm trying to implement a LinkLabel like the ones you can find under the Control Panel on Windows Vista and above.

Changing the cursor/color on hover is really simple, the only thing I need to do is to make the TLabel receive tab stops and to draw a focus rectangle around it.

Any ideas on how to do this? I understand that the TLabel doesn't receive tabs because of its nature. There is also TStaticText which does receive tabs, but it also doesn't have a focus rectangle.


Solution

  • Here's a derived static that draws a focus rectangle when focused. 'TabStop' should be set, or code that checks should be added. Doesn't look quite nice (the control doesn't actually have room for lines at all edges), but anyway:

    type
      TStaticText = class(stdctrls.TStaticText)
      private
        FFocused: Boolean;
      protected
        procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
        procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
        procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
      end;
    
    ...
    
    procedure TStaticText.WMSetFocus(var Message: TWMSetFocus);
    begin
      FFocused := True;
      Invalidate;
      inherited;
    end;
    
    procedure TStaticText.WMKillFocus(var Message: TWMKillFocus);
    begin
      FFocused := False;
      Invalidate;
      inherited;
    end;
    procedure TStaticText.WMPaint(var Message: TWMPaint);
    var
      DC: HDC;
      R: TRect;
    begin
      inherited;
      if FFocused then begin
        DC := GetDC(Handle);
        GetClipBox(DC, R);
        DrawFocusRect(DC, R);
        ReleaseDC(Handle, DC);
      end;
    end;