delphi - How to correctly respond to focus messages in a custom control? -


i need create own panel derived tcustompanel - here doing own custom painting on panel such drawing header @ top.

one of requirements need need able draw 2 different colors depending on whether panel has focus or not, need way of knowing whether or not child control inside panel has focus - of course though there no knowing of child contents be.

so example, if panel (or child controls inside panel) has focus, color clskyblue. if panel (or none of child controls inside panel) not have focus, color clwhite.

here quick layout of custom panel: (to keep simple example there no header drawing, basic color changing)

type   tmypanel = class(tcustompanel)   private     //   protected     // procedure paint; override;      procedure wmmousedown(var message: twmlbuttondown); message wm_lbuttondown;             procedure wmkillfocus(var message: twmkillfocus); message wm_killfocus;     procedure wmsetfocus(var message: twmsetfocus); message wm_setfocus;   public     constructor create(aowner: tcomponent); override;     destructor destroy; override;   end;  constructor tmypanel.create(aowner: tcomponent); begin   inherited create(aowner);    self.parentbackground := false;   self.parentcolor := false; end;  destructor tmypanel.destroy; begin   inherited destroy; end;  procedure tmypanel.wmmousedown(var message: twmlbuttondown); begin   self.setfocus; end;  procedure tmypanel.wmkillfocus(var message: twmkillfocus); begin   self.color := clwhite;   invalidate; end;  procedure tmypanel.wmsetfocus(var message: twmsetfocus); begin   self.color := clskyblue;   invalidate; end; 

the first problem ran making panel focusable, i'm sure there proper solution have overlooked in case used dirty trick intercepting wm_lbuttondown message , making panel focused. of course denies other requirement mentioned before child controls decide color panel should depending on whether or not panel or it's child controls focused.

this happens when click on panel:

enter image description here

this happens when clicking on child control:

enter image description here

as can see panel turned white, need turn clskyblue indicate panel or it's child contents has focus, should like:

enter image description here

so, solution correctly identify whether or not custom control or it's child controls has focus or not?

i had thought iterating through each child control inside panel determine if had focus or not not sure how fire such event in first place clicking directly on child control surely ignore messages custom panel waiting intercept.

all twincontrol descendants focusable , tcustompanel descendant, too. there's no need additional work in regard.

what not done automatically (and think want do) show focus state of component visually. 1 possible way handling cm_enter , cm_exit messages:

  tmypanel = class(tcustompanel)   private     procedure focuschanged(value: boolean);   protected     procedure cmenter(var message: tcmenter); message cm_enter;     procedure cmexit(var message: tcmexit); message cm_exit;   end;  procedure tmypanel.cmenter(var message: tcmenter); begin   focuschanged(true); end;  procedure tmypanel.cmexit(var message: tcmexit); begin   focuschanged(false); end;  procedure tmypanel.focuschanged(value: boolean); const   colors: array[boolean] of tcolor = (clwhite, clskyblue); begin   color := colors[value]; end; 

Comments