Does anyone know why Labels and Frames (and possibly other controls) have a TabIndex property in VB6? Is there some use for it; some feature of GUI programming I ought to be incorporating in my applications (that I am blissfully unaware of)?
To confirm what Cody said in the comments. The VB6 manual entry for TabIndex says:
Controls that can't receive the focus (Frame and Label controls) remain in the tab order but are skipped during tabbing.
but
If you press the access key for a Frame or Label control, the focus moves to the next control in the tab order that can receive the focus.
TabIndex is the property used to determine the sequence of focused controls when user presses TAB key.
If control with TabIndex=5 is focused and user presses TAB, control with TabIndex=6 will take focus.
Related
I've noticed sometimes the keyboard tabbing for focus gets messed up. In this case I am using a Blueprint Dialog component which contains a form to be submitted. The form is built with Redux Form wrapped Blueprint input components. When the dialog first opens I can tab to the concentration field of the form. The next two tabs focus hidden elements (see first image below). Then the "x" to close the dialog is focused, then the concentration field is focused again, and finally I can tab and focus the remaining fields and buttons.
Any tips on how to improve this? Its not clear to me why the pt-overlay-backdrop nor the pt-overlay-content would ever want to be tabbed into. I see they both have tabindex="0".. maybe that should be -1?
Thanks!
Set Dialog's autoFocus to false can fix this issue.
I'm reading Charles Petzold Programming Windows 5th-ed, Chapter 11, "Tabs Stops and Groups" section. I have a big question now.
The book says, when some controls belong to the same group, you can use left/right arrow key to switch focus between them, and this feature is used most often with a group of radio boxes. But what about other type of controls?
I tried having 3 button controls grouped together(A,B,C, only A has WS_GROUP, B and C don't). Then, I can confirm left/right arrow can switch focus between A,B and C.
Observing it more carefully, I see difference between radio box and button [P1]:
For a radio box group, pressing left/right-arrow repeatedly will cycle focus among all radio boxes in that group.
For button group, pressing right-arrow repeatedly will have focus move and stop at button C, the same left-arrow has it stop at A, no cycle behavior.
The case for "edit" control [P2]: If I make 3 edit boxes in one group, pressing left/right-arrow will NEVER switch the focus, which is not the same behavior as a button group.
So, my question boils down to: Does windows internal dialog box mananger WndProc (just call it DefDlgProc) treats some type of controls specially(like "edit")? For example, if DefDlgProc finds that a WM_KEYDOWN message with VK_RIGHT is destined for a "edit" control, it will never take the focus-switch action but pass the message to "edit" control honestly.
Is that special treatment done in a hard-coded way or some generic, configurable way? I need to know it because, if I write my own custom editbox control, I need a way to have DefDlgProc treat arrow keys specially for my control, right?
Sample code: For the 3-edit experiment, I use .rc statement like this:
ABOUTBOX DIALOGEX 32, 32, 180, 100
STYLE DS_MODALFRAME | WS_POPUP
EXSTYLE WS_EX_STATICEDGE
FONT 8, "Tahoma"
BEGIN
EDITTEXT IDC_EDIT0,40,7,40,14, ES_AUTOHSCROLL| WS_GROUP ,WS_EX_CLIENTEDGE
EDITTEXT IDC_EDIT1,90,7,40,14, ES_AUTOHSCROLL ,WS_EX_CLIENTEDGE
EDITTEXT IDC_EDIT2,133,7,40,14,ES_AUTOHSCROLL
CONTROL "OOKK",IDOK,"EllipPush",WS_GROUP | WS_TABSTOP,7,63,166, 30
ICON "ABOUT3",IDC_STATIC,7,7,20,20
END
Doing my experiment on Windows 7.
Your question doesn't quite make sense. You wouldn't expect pressing the left or right cursor key in an edit control to shift the focus to another control, because the edit control itself consumes that keypress in order to move the cursor around.
Internally the dialog manager uses GetNextDlgGroupItem() to shift the focus to the next or previous control in the group. This doesn't distinguish between control types - it only looks at the WS_GROUP style. However, the dialog manager only calls this function if the control itself doesn't consume the key, and this is determined by the control's response to the WM_GETDLGCODE message.
My Table control uses windowless checkboxes (because there can be an arbitrary number of checkboxes here). Right now, I use TrackMouseEvent(TME_LEAVE) and manually checking if the mouse is in the checkbox rect during a WM_LBUTTONUP. I have TODOs marked in my code for the edge cases that this causes, such as a missing WM_LBUTTONUP when the mouse has left the client area.
Now I notice today's The Old New Thing says buttons use mouse captures. This got me thinking, and after looking into it, mouse captures would fit what I need more appropriately; if my assumptions are correct it would handle the various edge cases I mentioned above and be more correct in general.
In particular, the assumptions I make are: I should abandon any capture-related operations on a WM_CAPTURECHANGED even if every other condition is met. I will get a WM_CAPTURECHANGED after a ReleaseCapture(). After a SetCapture(), I will always end with either a WM_LBUTTONUP or a WM_CAPTURECHANGED, whichever comes first.
I've read both MSDN and a few articles I've found by Googling "setcapture correct use"; I just want to make sure I've got the right idea and will be implementing this correctly. Do I?
on WM_LBUTTONDOWN
if the button is in a checkbox
SetCapture()
mark that we're in checkbox clicking mode
on WM_MOUSEMOVE
if we are in checkbox clicking mode
draw the checkbox in the pressed state
on WM_LBUTTONUP
if we are in checkbox clicking mode
leave checkbox clicking mode
THEN call ReleaseCapture(), so we can ignore its WM_CAPTURECHANGED
if the mouse was released in the same checkbox
toggle it
on WM_CAPTURECHANGED
if we are in checkbox clicking mode
abandon checkbox clicking mode and leave the checkbox untoggled, even if the mouse is hovering over the checkbox
Do I have the right idea here? And in particular, is my order of operations for WM_LBUTTONDOWN correct? Thanks.
What you have said is basically right, although a real checkbox tracks WM_MOUSEMOVE while in "clicking mode" and displays the checkbox in its original state if the mouse moves off of it. So to emulate that you should have:
on WM_MOUSEMOVE
if we are in checkbox clicking mode
if mouse is over the checkbox
draw the checkbox in the pressed (toggled) state
else
draw the checkbox in the original state
For some fun and self-education, I'm tinkering with writing my own X11 toolkit. Here's something that's stumping me.
I have a traditional combo box display element, a typical combo box with a dropdown popup list, like all popular toolkits have.
For the dropdown popup list, I'm creating a new window, a child of the root window, appropriately positioned below the main combo-box display element.
The dropdown popup list is a window in its own full right, that implements keyboard-based navigation, to select the individual entries in the dropdown list.
So, I'm using SetInputFocus to set the input focus to the popup after it opens.
What I find is that when I do that, the window manager then redraws the frame of the main window to indicate that it no longer has input focus. Which is technically true, but I don't see the same results with the more mainstream toolkits, where, in the comparable situation, the main window's frame shows that it still has input focus.
For the pop-up window, in addition to setting override-redirect, I'm also doing everything I can think of, to tell the window manager what's going on: setting the window group leader ID in the popup window's WM_HINTS, setting WM_TRANSIENT_FOR, and setting _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_COMBO; none of that seems to work (I verified that the properties are approriately set, via xprop).
It seems like I have to keep the input focus in the combo box window, and forward keypress and keyrelease events to the display elements in the dropdown popup, which feels clunky. Am I overlooking some property that would tell the window manager that the popup's input focus is linked to the main window's (besides the ones that I've mentioned), that would keep the main window's frame drawn to show that it has input focus, when the input focus is actually in the popup?
Most X11 override-redirect exclusive popup windows (menus, combo boxes, ...) grab the keyboard and/or pointer with either passive or active grab.
See XGrabKey, XGrabKeyboard, XGrabButton, XGrabPointer in the X11 programming manual.
Or maybe don't, because the manual is totally unclear about what the heck these functions are and how they can be used. Search the interwebs for usage examples, probably in other widget libraries. Unfortunately I don't know of a simple informative example offhand.
It is not necessary to call XSetInputFocus at all because all keyboard and/or pointer events are reported to the grabbing clients.
Is there a method such that a user can click on the form itself, and in doing so remove focus from whatever object (textbox, combobox, etc) currently has it? Basically, can focus be uniformly removed from everything at once?
Setting the focus to the form itself does not work.
I thought about doing the old "hide a placeholder button behind another object" trick, but I'm really not a fan of that.
Thanks!
In VB6 a PictureBox can get focus, even if it does not contain any control.
In your case you can put a PictureBox with TabStop false, BorderStyle set to 0, TabIndex set to 0 behind every other control but not containing any focusable control and stretch it to ScaleWidth by ScaleHeight at run-time.
You have to put the labels and any windowless control in this background PictureBox too.
This way when the user clicks "on the form" the focus will "go away". With "no focus" Tab key will focus first control (the one with TabIndex set to 1).
When a form is active, something generally HAS to have focus. It sounds like you're just wanting to not "show" that a particular control has focus.
If that's the case, it's going to depend on the controls. Some have properties that control whether or not the specific control "indicates" its focus in some way.
But the built in Windows controls will always show their focus state unless you subclass them
Given this problem. I'd probably put a button on the form , then move it offscreen when the form loads. Make sure it's not a tab stop, but then when you want to hide focus, set focus specifically to the button, make sure the button is STILL in the tab order, even though it's not a tab stop, so the user can press tab while on the button and end up somewhere logical.
Don't have VB handy, but could you simply remove TabStop?
for x = 1 to me.Controls.count
me.Controls(x).TabStop = 0
next
I have a picturebox and a control on a form.
Private Sub cmdButton_Click
PictureBox.setFocus
Exit sub
End sub
The control doesn't change its appearance, nor does the picturebox.
Of course you'll need to add an If-Then clause if you want the control to respond normally sometimes.