How to delay the LostFocus Event in VB6 - vb6

I'm having an issue with a process that involves the LostFocus event.
When the cursor loses focus from a particular textbox, I'm simply putting the focus back into that box.
My issue is removing focus long enough for the user to click a log out button. Is there a way to intercept the LostFocus event long enough to allow the user to click the log out button?

Obviously I don't know the big picture here. But keeping only with what you said, the following does the trick. Effectively the event is delayed briefly, allowing the button to be clicked:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Text1_LostFocus()
Sleep 100
DoEvents
Text1.SetFocus
End Sub

With a combination of a Timer and another control that is outside of the borders of your form, you can achieve this.
Private Sub Text1_LostFocus()
Combo1.SetFocus
ReturnFocusTimer.Enabled = True
End Sub
Private Sub ReturnFocusTimer_Timer()
ReturnFocusTimer.Enabled = False
Text1.SetFocus
End Sub
In this example Combo1 is positioned beyond the bottom of the form. You can control the ReturnFocusTimer interval to however long you need.

Related

VB6: How do I force the cursor into a textbox but release for button press

I asked a similar question here: How to delay the LostFocus Event in VB6. It was suggested to use DoEvents, which didn't work for me because it was reloading all my forms.
What I need to do is to force the cursor into a textbox for a barcode read. However, I need to allow the user the ability to click 1 of 3 buttons on the form. So, what needs to happen is, possibly on hover over one of these buttons, release the cursor long enough to click a button.
Can this be done?
Here is a way of accomplishing what you need. In the button Click events, do the needed work and then SetFocus back to the textbox. You will not respond to the LostFocus event as in the previous post.
Option Explicit
Private Sub Text1_LostFocus()
'do nothing
End Sub
Private Sub Command1_Click()
'do your work
Text1.SetFocus
End Sub
Private Sub Command2_Click()
'do your work
Text1.SetFocus
End Sub
Private Sub Command3_Click()
'do your work
Text1.SetFocus
End Sub
Keep in mind that the textbox won't gain focus until the work is complete.

Shift-tab issue

I am new to VB but working on a VB project now.
I ran into a strange problem about Shift-Tab.
The tabbing order is correct where it will go through all the textboxes, checkboxes, etc to the Accept and Cancel button at the end of the form, then cycle back to the beginning of the form.
However, if you Shift-Tab, it will skip the Accept and Cancel button. It works correctly for all other controls though.
The Tab Indices seem correct to me.
Does anyone have any idea what might be the cause? I'm at my wits end so any help would be greatly appreciated.
Check for Shift+Tab on EnterFocus event of the UserControl like this
Option Explicit
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal VKey As Long) As Integer
Public Function IsKeyPressed(ByVal lVirtKey As KeyCodeConstants) As Boolean
IsKeyPressed = ((GetAsyncKeyState(lVirtKey) And &H8000) = &H8000)
End Function
Private Sub UserControl_EnterFocus()
If IsKeyPressed(vbKeyTab) And IsKeyPressed(vbKeyShift) Then
cmdCancel.SetFocus
End If
End Sub

How can I capture key ups/downs no matter what control on my form is the target?

I want to capture ctrl/alt/etc key ups and downs, no matter which control on my form gets the keyup or keydown event. Since I have about 100 controls on my form, it would be really ugly if I were to add code to each individual control. How can I accomplish this without having to do that?
PS: What's the difference between SetWindowsHook and SetWindowsHookEx?
You need to set the KeyPreview property of each Form to True. Subsequently, you can catch the keyboard events at the form level, in addition to the individual control level:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Debug.Print "Form_KeyDown"
End Sub
Private Sub Form_KeyPress(KeyAscii As Integer)
Debug.Print "Form_KeyPress"
End Sub
Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
Debug.Print "Form_KeyUp"
End Sub
Essentially, the form gets a "preview" of each keyboard event before the control, e.g.
Form_KeyDown
Control_KeyDown
Form_KeyUp
Control_KeyUp
As for SetWindowsHook & SetWindowsHookEx, the former is the original Win16 API call, and the latter is the Win32 and Win64 API call. SetWindowsHook is deprecated, and isn't in the current MSDN library, as far as I know.

Visual Basic 6: how to make application visible in taskbar?

I've set property ShowInTaskBar to true, but my application is not visible in taskbar.
Form has minimize, maximize and close buttons. When I click minimize, form minimizes to a small form in the bottom left corner on the screen, but doesn't show up in the taskbar.
Is your form modal?
MyForm.Show vbModal
If so then you'll have to do something like this to make it show in the taskbar.
This question is old but I still work with VB6 on a daily basis. I found this work around to make a form shown by MyForm.Show vbModal appear on the taskbar.
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Sub Form_Activate()
Call ShowWindow(Me.hWnd, vbHide)
Me.Caption = Me.Caption
Call ShowWindow(Me.hWnd, vbNormalFocus)
End Sub

Prevent a TreeView from firing events in VB6?

In some VB6 code, I have a handler for a TreeView's Collapse event:
Private Sub MyTree_Collapse(ByVal Node as MSComCtlLib.Node)
This is called whenever a node in the tree is collapsed, whether by the user or programmatically. As it turns out, through some roundabout execution, it may happen that this handler will wind up telling a node to collapse, leading to infinite recursion.
I can think of multiple ways to skin this cat, but what seems simplest to me is to tell the TreeView not to raise events for some period of time. I can't find a simple call to let me do this, though. Has anyone successfully done this, or do I need to keep track of state in some other manner so I can respond appropriately when recursive events come along?
#Phil - I came to the same conclusion. My implementation of MyTree_Collapse now looks something like this (where m_bHandlingCallback is a member variable):
Private Sub MyTree_Collapse(ByVal Node as MSComCtlLib.Node)
If m_bHandlingCallback Then Exit Sub
m_bHandlingCallback = True
DoSomeStuff
m_bHandlingCallback = False
End Sub
Another way in VB6 is to have an alternate WithEvents reference to the control:
Private WithEvents alt as TreeView
and in Form_Load:
Private Sub Form_Load()
Set alt = MyTree
End Sub
Now alt will receive lots of events like this:
Private Sub alt_Collapse(ByVal Node as MSComCtlLib.Node)
Set alt = Nothing
'DoSomeStuff'
Set alt = MyTree
End Sub
But, during the DoSomeStuff, the events are unhooked - which also applies to all other event Subs for alt without the need for them to have intrusive changes.
I think that like many events in VB, it can't be switched off.
Just set a boolean flag as you've suggested.
I would declare the flag variable as STATIC in the Sub. This avoids making the variable global and makes it keep its value between calls.

Resources