How can a control be notified when its parent gains and loses focus in Delphi?

As the name says, I want the component (say, a label ) to be notified when its parent (say, a panel ) receives and loses focus. I wandered around the Delphi source a bit, hoping to use TControl.Notify , but it was only used to notify child controls of some property changes, such as font and color. Any suggestions?

+4
source share
1 answer

Whenever the active control in an application changes, the CM_FOCUSCHANGED message is CM_FOCUSCHANGED to all the controls. Just intercept it and act accordingly.

In addition, I assumed that when a parent (say, a panel) gains and loses focus, you mean whenever a (nested) child control on that parent / panel gains or loses focus.

 type TLabel = class(StdCtrls.TLabel) private function HasCommonParent(AControl: TWinControl): Boolean; procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED; end; procedure TLabel.CMFocusChanged(var Message: TCMFocusChanged); const FontStyles: array[Boolean] of TFontStyles = ([], [fsBold]); begin inherited; Font.Style := FontStyles[HasCommonParent(Message.Sender)]; end; function TLabel.HasCommonParent(AControl: TWinControl): Boolean; begin Result := False; while AControl <> nil do begin if AControl = Parent then begin Result := True; Break; end; AControl := AControl.Parent; end; end; 

If you do not like the subclass of TJvGradientHeader , then you can create it in the general case using Screen.OnActiveControlChange :

  TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FHeaders: TList; procedure ActiveControlChanged(Sender: TObject); end; procedure TForm1.FormCreate(Sender: TObject); begin FHeaders := TList.Create; FHeaders.Add(Label1); FHeaders.Add(Label2); Screen.OnActiveControlChange := ActiveControlChanged; end; procedure TForm1.FormDestroy(Sender: TObject); begin FHeaders.Free; end; function HasCommonParent(AControl: TWinControl; AMatch: TControl): Boolean; begin Result := False; while AControl <> nil do begin if AControl = AMatch.Parent then begin Result := True; Break; end; AControl := AControl.Parent; end; end; procedure TForm1.ActiveControlChanged(Sender: TObject); const FontStyles: array[Boolean] of TFontStyles = ([], [fsBold]); var I: Integer; begin for I := 0 to FHeaders.Count - 1 do TLabel(FHeaders[I]).Font.Style := FontStyles[HasCommonParent(Screen.ActiveControl, TLabel(FHeaders[I]))]; end; 

Note that I chose TLabel to demonstrate that this works for TControl derivatives as well.

+5
source

Source: https://habr.com/ru/post/1434360/


All Articles