Control focus and tabindex

Im looking for a way to determine which control has focus at any given point. Input fields are obviously quite easy, but others which have no visual cue ? I have put together a simple form with listbox, textfields, labels, popupmenu, a few lines and some buttons. I can cycle through the input fields easy enough and know they have focus, but after I tab out of the last one, I have to press tab a few times before it returns to the first one at the top of the form. So I’d like to identify which one has focus each time I press the tab key.

Secondly regarding tabindex; Im not sure if Im doing this right or not. All controls that dont NEED focus, I have set the tabindex value to zero. This is pretty much any control that does not require user interaction. The rest I have set from 1 upwards, numbering them in what I thought was a logical sequence. It does work tabbing through the textfields, but the popupmenu seems to be ignored for starters, and after I have populated a listbox with rows from a database or populated some of the textfields with fields from the database, the focus seems to switch to one of the textfields in the middle of the form. The textfields that have been populated are all filled in the same order as they appear on the form.

Im assuming tabindex should be the order in which the focus control moves around a window,so, have I taken the correct approach and is there a way to see which control is active, maybe by temporarily adding in some MsgBox code to the GotFocus / LostFocus events ?

For starters, Stephen, I would ALWAYS use the Tab Order Editor (accessible via the icon at the top) … it allows you to set the tab order of all controls at one time from one place. I’ve never had good results trying it by individually setting tab order in each control using the inspector.

I did try using that but with limited success. It would be a far more useful tool if it showed the actual tabindex value assigned to each control; that way you see any possible duplicates for a start.

I’m currently trying something else to see if it might work. That is to go through every control that has a tabindex and setting its value to 999, except for the ones I’m interested in which are numbered starting at zero and incrementing by one.

popupmenu control does not appear to get a tab stop either, even with tabstop on and a valid tabindex.

window class has a focus property so you can see which control has focus.

Is there a way to set a handler in any of the window events that will report whenever a focus changes ?

I’ve tried using MsgBox attached to the gotfocus events of the individual controls, but that doesnt do the job very well.

If you set a control tabindex to zero, it means that is the one getting the focus as default. So instead of ignoring them, it will put the focus on one of the controls you want to skip.

Better put a high number in each of the controls you do not want to focus on, like 100, and in the last of the desired focusable ones (i.e.10), put in the keydown event

if key = chr(9) whatvercontrolwithtabindexzero.setfocus return true end if

[quote=125645:@Stephen Thomas]Is there a way to set a handler in any of the window events that will report whenever a focus changes ?
[/quote]

In the window Paint event :

static lastfocus as RectControl = self.focus if self.focus <> nil then if self.focus <> lastfocus then beep //do whatever is needed when focus changes end if lastfocus = self.focus end if

Thankyou Michael, I looked at the events several times but didnt realise it would be the paint event i needed.

I’ll try that!

Paint is convenient : it fires regularly, and every time its display changes. Perfect to spot the change in focus ring. The alternative is to place the code in the Action event of a timer.

Ive resized the window and added a temporary listbox(lbFocusControl) with 2 columns and changed the code like so :

  static lastfocus as RectControl = self.focus
  if self.focus <> nil then
    if self.focus <> lastfocus then
      lbFocusControl.AddRow(Str(lastfocus),Str(self.focus))
    end if
    lastfocus = self.focus
  end if

This throws a TypeMismatchException. Any ideas ?

I thought by adding entries to a listbox this way, I can see the order in which the focus changes and to which controls.

[quote=125677:@Stephen Thomas]Ive resized the window and added a temporary listbox(lbFocusControl) with 2 columns and changed the code like so :
I thought by adding entries to a listbox this way, I can see the order in which the focus changes and to which controls.[/quote]

Focus is not a numeric value, it is a RectControl (parent class of all controls). Here is what you can do :

lbFocusControl.AddRow(lastfocus.name,self.focus.name)

Well lastfocus.name throws a nil exception, but using the following seems to work better :

lbFocusControl.AddRow(self.focus.name,Str(self.focus.tabindex))

And since the previous one is already in the listbox I dont think it would achieve much more anyway. Thankyou guys.

Depends on the OS
On Windows any control can get the focus
On OS X thats not the case (ie popup menus dont)

[quote=125695:@Norman Palardy]Depends on the OS
On Windows any control can get the focus
On OS X thats not the case (ie popup menus dont)[/quote]

Yep, Im on a mac. I did wonder about that. Thanks for confirming.

Is there a complete list of the differences or do I need to look into each control individually ?

No list exists that I know of

Ok. Thankyou all for the replies.

I had a form I produced the other day that went to a specific field every time no matter what I set for tabindex, tabstops etc, but I deleted it and started over. If i can reproduce it again I will post the details and link.

static lastfocus as RectControl = self.focus if lastfocus <>nil then if self.focus <> nil then if self.focus <> lastfocus then lbFocusControl.AddRow(lastfocus.name+" "+self.focus.name) end if end if end if lastfocus = self.focus

If a control cannot get the focus, it will never show up that way, so you probably do not need to worry too much about the list…

Michael, apologies for the delay in replying and thankyou for the amended code. That does work as expected and I’ve added the tabindex value to the end of each one too.

:slight_smile: