How to remove focus from currently focused component?
Asked Answered
L

4

8

I have a DB component which DataLink.UpdateRecord is called when it receives CM_EXIT message. This message is sent when it loses focus. When I click post button, it doesn't lose focus and value is not written to datasource. How can I reach an effect of component losing focus without switching it to other one?

Lyricist answered 15/2, 2010 at 6:36 Comment(1)
On a side note, none of the below solutions seem to work in the form's OnCreate or OnShow events.OnActive works, but then something ends up getting focus anyway after just clicking on the form.Subscript
A
16

You could use:

procedure TCustomForm.DefocusControl(Control: TWinControl; Removing: Boolean);
Aspic answered 15/2, 2010 at 8:8 Comment(4)
I looked at this procedure, tried using it, and it didn't work. Now I did it again and it works. It is time to go to sleep:)Lyricist
As it occurs, setting Self.ActiveControl := nil does the job too and is more intuitive. Obviously not for me....Lyricist
@Lyricist Thanks, this is great!Nowell
Does work on formactivate but not on formcreateFleabane
G
12

We accomplish this by setting the Self.ActiveControl := nil. That causes all of the exit events to fire. In our case we wanted to also re-focus back to the control after the save took place. That required a few extra checks to ensure we had a good control that could accept focus.

procedure TSaleEditor.SaveCurrentState();
var
  SavedActiveControl: TWinControl;
  AlternateSavedControl: TWinControl;
begin

  // Force the current control to exit and save any state.
  if Self.ActiveControl <> nil then
  begin
    SavedActiveControl := Self.ActiveControl;

    // We may have an inplace grid editor as the current control.  In that case we
    // will not be able to reset it as the active control.  This will cause the
    // Scroll box to scroll to the active control, which will be the lowest tab order
    // control.  Our "real" controls have names, where the dynamic inplace editor do not
    // find an Alternate control to set the focus by walking up the parent list until we
    // find a named control.
    AlternateSavedControl := SavedActiveControl;
    while (AlternateSavedControl.Name = '') and (AlternateSavedControl.Parent <> nil) do
    begin
      AlternateSavedControl := AlternateSavedControl.Parent;
    end;

    Self.ActiveControl := nil;

    // If the control is a radio button then do not re-set focus
    // because if you are un-selecting the radio button this will automatically
    // re-select it again
    if (SavedActiveControl.CanFocus = true) and
      ((SavedActiveControl is TcxRadioButton) = false) then
    begin
      Self.ActiveControl := SavedActiveControl;
    end
    else if (AlternateSavedControl.CanFocus = true) and
      ((AlternateSavedControl is TcxRadioButton) = false) then
    begin
      Self.ActiveControl := AlternateSavedControl;
    end;

  end;

end;
Grice answered 15/2, 2010 at 16:43 Comment(0)
F
4

Have a look at TCustomForm.FocusControl. You can't make it lose focus without switching focus to something else, but you can switch and then immediately switch back, which would probably work.

Fulfillment answered 15/2, 2010 at 6:50 Comment(1)
And how can I do it with FocusControl? Calling it on active control doesn't trigger events.Lyricist
R
2

There is a SetFocus function in windows unit. Try this:

Windows.SetFocus(0);

Roscoe answered 24/1, 2014 at 14:39 Comment(1)
Would be great, as I'm looking for a global level to accomplish this. Unfortunately I just tried in the form's OnCreate and OnShow but the focus still went in anyway.Subscript

© 2022 - 2024 — McMap. All rights reserved.