Shift-tab issue - vb6

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

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.

How to delay the LostFocus Event in 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.

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.

Powerpoint VBA App_SlideShowBegin

In order to use the SlideShowBegin event in Powerpoint, you have to have a Class Module configured the following way:
Public WithEvents App As Application
Private Sub App_SlideShowBegin(ByVal Wn As SlideShowWindow)
MsgBox "SlideShowBegin"
End Sub
Then, inside of a non-class module, you have to create an object of that type and set the App to Application.
Dim X As New Class1
Sub InitializeApp()
Set X.App = Application
End Sub
Now, the only issue I have is, if you don't manually called InitializeApp with the Macro Menu in Powerpoint, the events don't work. You have to call this sub before anything can called at the beginning of a slideshow INCLUDING this sub.
How can I go about calling this sub before running my powerpoint? Is there a better way to do this?
EDIT:
I've tried using Class_Initialize but it only gets called once it is first used or you make a statement like Dim X as Class1; X = new Class1
Usually event handlers are installed as part of an add-in, where you'd initialize the class in the Auto_Open subroutine, which always runs when the add-in loads. If you want to include an event handler in a single presentation, one way to cause it to init is to include a shape that, when moused over or clicked fires a macro, which inits your event handler and goes to the next slide.
Answering to an old question, but I hope my solution might helpt somebody ending up at this question.
The general advice for this issue is using a plug-in or placing some element on the slide and when that is clicked or hovered perform the initialization. Both are not always desired so I have the following approach:
In some module:
Dim slideShowRunning As Boolean
-----------------------------
Sub SlideShowBegin(ByVal Wn As SlideShowWindow)
' Your code for start-up
End Sub
-----------------------------
Public Sub OnSlideShowPageChange(ByVal Wn As SlideShowWindow)
If TypeName(slideShowRunning) = "Empty" Or slideShowRunning = False Then
slideShowRunning = True
SlideShowBegin Wn
End If
End Sub
----------------------------
Public Sub OnSlideShowTerminate(ByVal Wn As SlideShowWindow)
slideShowRunning = False
End Sub
For me this works perfectly. NOTE I am by no means a vba expert, actually I might have less than 50 hours of vba programming (maybe only 8 in powerpoint). So this might be an horrible solution. I don't know, but for me it works so I liked to share.
In fact, OnSlideShowPageChange runs when slideshow begins. Just make sure it doesn't work in the subsequent page changes if not needed using a global variable. See answer from C. Binair for details.

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

Resources