My combobox has no cursor when I close the on-screen keyboard

MistakesWereMade

Board Regular
Joined
May 22, 2019
Messages
103
I use osk.exe on my tablet when using a combobox. If I close the on-screen keyboard application in the midst of typing in the combobox, the combobox gets buggy. I can open the on-screen keyboard again but it will not show what I am typing in the combobox. I open the osk.exe application by clicking on an invisible label over my combobox. I also use combobox1.SetFocus after the osk is opened, but this setfocus doesn't work more than once. Any ideas on how I can possibly make it so that each time I click on the label, the combobox will reaffirm its focus?

Code:
Option Explicit


Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpszOp As String, ByVal lpszFile As String, ByVal lpszParams As String, ByVal LpszDir As String, ByVal FsShowCmd As Long) As Long
Private Declare PtrSafe Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" (ByVal Enable As Boolean) As Boolean
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare PtrSafe Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare PtrSafe Function IsWow64Process Lib "kernel32" (ByVal hProc As Long, bWow64Process As Long) As Long

Public Function Is64bit() As Long
   If GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process") > 0 Then
      IsWow64Process GetCurrentProcess(), Is64bit
   End If
End Function

Private Sub Label1_Click()
    ComboBox1.SetFocus
    If Is64bit Then
        Wow64EnableWow64FsRedirection False
        ShellExecute 0, "open", "osk.exe", "", "", vbNormalFocus
        Wow64EnableWow64FsRedirection True
        ComboBox1.SetFocus
    Else
        ShellExecute 0, "open", "osk.exe", "", "", vbNormalFocus
        ComboBox1.SetFocus
    End If
    ComboBox1.SetFocus
End Sub
 

Excel Facts

How to total the visible cells?
From the first blank cell below a filtered data set, press Alt+=. Instead of SUM, you will get SUBTOTAL(9,)
Are the activeX controls on a userform or on a worksheet ?

Also, is there any particular reason you are using a transparent label ? why don't you use the combobox click event to bring up the osk when clicking inside the combobox itself?
 
Upvote 0
I have just given this a try by placing a transparent label over the combobox and the combobox always gets the focus back even after closing the osk. but one cannot select items from the combo dropdown because of the label.

How about removing the label and using the mouse_up event of the combobox to open the osk upon clicking on it ?

Something along these lines :
Code:
Private Sub ComboBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Is64bit Then
        Wow64EnableWow64FsRedirection False
        ShellExecute 0, "open", "osk.exe", "", "", vbNormalFocus
        Wow64EnableWow64FsRedirection True
    Else
        ShellExecute 0, "open", "osk.exe", "", "", vbNormalFocus
    End If
    ComboBox1.SetFocus
End Sub

I am assuming this is on a userform.
 
Last edited:
Upvote 0
Wow that works great! Is there a way to speed up the code? It works a little slow. I'm also wondering if there is a way to skip that sub if the osk is already open. In other words, if I click on the combobox when the osk keyboard is already open, it kinda freezes for a sec. You helped me in another post determine if osk keyboard is already open. Is there a method with that perhaps? Just wondering.
 
Upvote 0
I realized that if I choose to close osk before picking a selection from the combo box drop down list, the keyboard will show up if I tap the drop down list. I would rather the osk not show up due to the drop down list.
 
Upvote 0
Ok- I suspected that the main reason the userform loses the focus was because it is modeless... I have been able to reproduce the issue you are experiencing.

Here is a workaround :

1- Get rid of the transparent label.

2- Instead of using the click or mouseup event to bring up the OSK, we are going to use the combobox DBL_Click event... ie: the user will now need to double-click the combobox in order to launch the OSK...This step among other things should stop the OSK showing up when working with the dropdown list and is more user friendly in my opinion... The DblClick event also takes care of checking if the osk is already open in which case it won't try to open it again... This should stop the freezing you mentioned.

Notice that I am using the commandbars OnUpdate event to detect when the osk is being closed.. This event should take care of putting the focus back into the combobox and should keep the blinking cursor visible inside the combobox... This is un un-orthodox way of doing things but IMHO, it is a much better way than using a timer or a loop.


Use the following code :
Code:
Option Explicit

Private WithEvents cbrs As CommandBars


[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  VBA7 Then
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
    Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
    Private Declare PtrSafe Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" (ByVal Enable As Boolean) As Boolean
    Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, ByVal lpProcName As String) As LongPtr
    Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr
    Private Declare PtrSafe Function GetCurrentProcess Lib "kernel32" () As LongPtr
    Private Declare PtrSafe Function IsWow64Process Lib "kernel32" (ByVal hProc As LongPtr, bWow64Process As Long) As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL] 
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetActiveWindow Lib "user32" () As Long
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    Private Declare Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" (ByVal Enable As Boolean) As Boolean
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProc As Long, bWow64Process As Long) As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If


Private Sub UserForm_Initialize()
    Set cbrs = Application.CommandBars
End Sub

Private Sub ComboBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

    If Get_OSK_Hwnd = 0 Then
        If Is64bit Then
            Wow64EnableWow64FsRedirection False
            ShellExecute 0, "open", "osk.exe", "", "", vbNormalFocus
            Wow64EnableWow64FsRedirection True
        Else
            ShellExecute 0, "open", "osk.exe", "", "", vbNormalFocus
        End If
    End If
    
End Sub


[B][COLOR=#008000]'HELPER ROUTINES:[/COLOR][/B]
[B][COLOR=#008000]'===============[/COLOR][/B]
Private Sub cbrs_OnUpdate()
    If GetActiveWindow <> Application.hwnd Then
        If Get_OSK_Hwnd Then
            With ComboBox1
                .Visible = False
                .Visible = True
                .SetFocus
            End With
        End If
    End If
End Sub

Private Function Is64bit() As Long
   If GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process") > 0 Then
      IsWow64Process GetCurrentProcess(), Is64bit
   End If
End Function

[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  VBA7 Then
    Private Function Get_OSK_Hwnd() As LongPtr
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL] 
   Private Function Get_OSK_Hwnd() As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If
        Get_OSK_Hwnd = FindWindow("OSKMainClass", vbNullString)
End Function

I hope this works for you.
 
Last edited:
Upvote 0
I commend you for your expertise. This works extravagantly well! Thank you kind soul. I am forever grateful.
 
Last edited:
Upvote 0

Forum statistics

Threads
1,213,546
Messages
6,114,256
Members
448,557
Latest member
richa mishra

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top