Componentes - criar borda de foco ao redor do selecionado
|Top Previous Next|
// Comentario do Junior - é bom e funciona. O problema é o foco em tela com
// RadioGroup e TabSheet, fica meio feio
Herbert J. Beemster's article Give Your Editbox Some Attention! derived an edit box that display an extra border when it has
focus. Great idea, but a real pain in the #!$e deriving a new control every time you wanted to add that functionality.
That set me thinking about an idea i had ages ago - to trap delphi's Cn_FocusChanged message, and draw a border around any
control that has just received the focus.
Attached is the control TucsFocus (delphi 3) - basically it waits for a control to send out a Cn_FocusChanged message, and
then resizes itself and positions inself *under* the focused control to produce a border effect.
To place the TucsFocus under and control on a form, it is necessary to change it's parent - this caused a problem because when
the message handler is active, the parent is looping through it's controls list to notify all it's children, so changing the parent in the
message handler resulted in an index out of bounds exception. To handle this i had to post a WM_USER message to the
control which would then be processed after all of the parent's children had been notified. It is the WM_USER message
handler that does all the work.
I've added two properties: Color (naturally) and BorderSize (the width of the border).
I dare say it could be improved - for instance not using the WM_USER message - but i hope some of you find a use for it.
Consultancy and programing services
TucsFocus by Eamonn Mulvihill of Update Computer Services.
This control uses delphi's notification message cm_FocusChanged
to follow the focus around the form. When a control receives
focus, it paints a bold border around it, basically by resixing
itself and placing itself behind the focused control.
This source is free for any use, but i would appreciate a mention
in any controls that are derived from it.
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
TucsFocus = class(TCustomControl)
fBorderSize : integer;
procedure CMFocusChanged(var msg:TCMFocusChanged); message Cm_FocusChanged;
procedure MSGAfterFocus(var msg:TCMFocusChanged); message WM_USER;
procedure Paint; override;
constructor Create(AOwner:TComponent); override;
property BorderSize:integer read fBorderSize write fBorderSize;
//set property defaults
width := 20;
height := 20;
color := clBtnShadow;
BorderSize := 3;
//paint the control
with canvas do
//draw filled rectangle
brush.color := color;
//a little extra in design mode
if csDesigning in ComponentState then
pen.color := clBlack;
font.name := 'Arial';
font.size := 11;
font.style := [fsBold];
//Delphi is currently looping throught the parent's controls list.
//Canging the parent here will cause an exception, so post a USER
//message, which will be processed after all controls have been
procedure TucsFocus.CMFocusChanged(var msg:TCMFocusChanged);
UserMsg := TMessage(msg);
UserMsg.msg := WM_USER;
//OK, now we can move the TucsFocus, size it and change the parent too!
procedure TucsFocus.MSGAfterFocus(var msg:TCMFocusChanged);
var rect :TRect;
//calculate size and position
rect := msg.Sender.BoundsRect;
rect.left := rect.left - BorderSize;
rect.top := rect.top - BorderSize;
rect.right := rect.right + BorderSize;
rect.bottom := rect.bottom + BorderSize;
BoundsRect := rect;
//and change parents
parent := msg.Sender.parent;