1. Home
  2. Computing & Technology
  3. Delphi Programming

Generic Solution to Coloring the Focused Entry Control
OnEnter + OnExit := Wrong Way!

By Zarko Gajic, About.com

By (Windows) design, the control on a data entry form that has the input focus is not "drawn" differently from other controls (i.e. those without the input focus). In case of the TEdit control, only the blinking insertion point is displayed.

To provide visually more attractive user-friendly interfaces for your Delphi applications, you could decide to change the background color (and maybe some other properties) of the currently selected control - the control that has the input focus.
Of course, restoring to the original background color when the focus shifts to another control is also required.

OnEnter + OnExit := "Wrong Way"!

All Delphi controls that can receive the input focus (those derived from the base TWinControl class) expose the OnEnter and OnExit events. The OnEnter is fired when a control receives the input focus, OnExit is fired when the input focus shifts away from the current control to another.

Naturally, the first idea you got is to use the OnEnter and OnExit events of a control to change the Color property to "focused color" in the OnEnter event and restore the "original color" in the OnExit event.

Since Delphi controls can share event handlers, you could decide to write two common procedures to handle OnEnter and OnExit events for all the data entry controls on a form.

Let's say you have a TEdit ("Edit1"), a TMemo ("Memo1") and a TComboBox ("ComboBox1") on a form. If you set all those controls to share a common OnEnter and OnExit event handling procedures, your code would need to look something like:

"Bad Code Ahead" Warning!

const
   focusedColor = clSkyBlue;
var
   oldColor : TColor;

procedure TMainForm.FormCreate(Sender: TObject) ;
begin
   Button1.OnEnter := ControlOnEnter;
   ComboBox1.OnEnter := ControlOnEnter;
   Memo1.OnEnter := ControlOnEnter;

   Button1.OnExit := ControlOnExit;
   ComboBox1.OnExit := ControlOnExit;
   Memo1.OnExit := ControlOnExit;
end;

procedure TMainForm.ControlOnEnter(Sender: TObject) ;
begin
   if Sender is TEdit then
   begin
     oldColor := TEdit(Sender).Color;
     TEdit(Sender).Color := focusedColor;
   end;

   if Sender is TComboBox then
   begin
     oldColor := TComboBox(Sender).Color;
     TComboBox(Sender).Color := focusedColor;
   end;

   //... other cases
end;

procedure TMainForm.ControlOnExit(Sender: TObject) ;
begin
   if Sender is TEdit then
   begin
     TEdit(Sender).Color := oldColor;
   end;

   //... other cases
end;
Why is this approach far from ideal:
  • You lose the ability to handle the OnEnter and OnExit event on a control level - as Delphi (for Win32) does not support multicast events.
  • You cannot simply use "TWinControl(Sender).Color" as the Color property is not exposed by TWinControl - the class all input controls inherit from. The Color property comes from the TControl class as protected, controls make it public on their own.
  • As you drop more controls on the form, you have to make sure the correct class is already handled. For example, if you drop a TRadioButton, you need to add the code to check if the Sender is TRadioButton.
  • What if you want to provide such visuall feedback for all your data entry forms? No go!
So, what's the solution? How to handle those OnEnter and OnExit on a higher level?

The answer lies in using the TScreen's OnActiveControlChange event and Delphi's RTTI ... reveal the answer (and download the solution with source code) on the next page ...

Explore Delphi Programming
About.com Special Features

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

Easy ways to connect two computers for networking purposes. More >

  1. Home
  2. Computing & Technology
  3. Delphi Programming
  4. Using VCL Components
  5. TEdit, TMaskEdit
  6. Generic Solution to Coloring the Focused Data Entry Delphi Control

©2009 About.com, a part of The New York Times Company.

All rights reserved.