6

I got two TEdit controls. When I tab out of edit1, edit2 receives the focus. On my OnExit event of Edit1 I have the following code:

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  edit2.Enabled := false;
  edit2.Enabled := true;
  edit2.setfocus;
end;

Edit2 has the focus. However, there is no caret in it. I can start typing but it's confusing as I do not know which control has the focus.

I'm more interested on what's with the flipping of the Enabled property that's causing some messages to be not firing properly ? For instance edit2's OnEnter event is not being triggered.

This is on D2006 if it matters at all.

Thanks for the reply.

NGLN
  • 43,011
  • 8
  • 105
  • 200
Rick
  • 1,301
  • 1
  • 16
  • 28
  • there's a bunch of codes between disabling and enabling edit2. it's not necessarily edit2, but whatever is the activecontrol. so after re-enabling the activecontrol, i'd like to reset the focus in it. well, it sure is the activecontrol, but there is no caret. – Rick Sep 05 '11 at 08:18

4 Answers4

9

I don't understand why you disable and enable edit2, but you do this:

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  edit2.Enabled := false;
  edit2.Enabled := true;
  edit2.setfocus;
  PostMessage(edit2.Handle, WM_SETFOCUS, 0, 0);
end;

BTW, I agree with Andreas Rejbrand.

Whiler
  • 7,998
  • 4
  • 32
  • 56
  • 1
    I personally prefer this approach if Assigned(ActiveControl) then PostMessage(ActiveControl.Handle,WM_SETFOCUS,0,0); after setting focus to another control. After certain operations windows api seems to not recognize active control and therefore OnExit/OnEnter events do not trigger properly. This line corrects it. – ertx Sep 05 '11 at 10:00
  • This works, thanks ! I tried to trace the chain of events figuring out why it won't redraw the focus and the caret. Hit the wall on WndProc and it just loops there and I've lost track what message its processing. – Rick Sep 05 '11 at 23:03
9

I seriously suspect you are doing something in a bad way, and the best solution is most likely a redesign. You are not supposed to disable and then enable a control while it is receiving focus.

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • I agree, it's not ideal. And sure there are workarounds. But I'm only curious on what's required for the caret and the focus to show. Something about disabling the activecontrol w/in the OnExit event that breaks the chain of windows messages. – Rick Sep 05 '11 at 22:56
0

Found an issue when OnActive for MainForm activates another form.

TMainForm.OnActivate;
begin
ChildForm.ShowModal;
end;

Control focus is set but does not work. The work around I found was sending PostMessage(Handle, WM_SETFOCUS, 0, 0); to the form handle.

procedure TChildForm.FocusControl(AWinControl: TWinControl);
begin
  try
    // http://stackoverflow.com/questions/7305296/tedit-focus-caret
    PostMessage(Handle, WM_SETFOCUS, 0, 0);
    PostMessage(AWinControl.Handle, WM_SETFOCUS, 0, 0); 
    if AWinControl.CanFocus then
       AWinControl.SetFocus;
  except
    on E: Exception do
    begin
      Error(Self, E);
    end;
  end;
end;
0

There's a bunch of codes between disabling and enabling edit2.

Having a lot of code in the OnExit event handler of the previous active control does not require to disable the next active control. That code will execute before the next active control shows up the caret and will be able to receive user input. Just make sure that it does nót pass execution over by something like starting a new thread or using Application.ProcessMessages.

Set Screen.Cursor to crHourGlass to make it clear for the user that the next active control is not ready yet.

NGLN
  • 43,011
  • 8
  • 105
  • 200