1

I am trying to open the osk.exe from VBA within Excel 64 bit on Windows 10 64 bit.

I have pieced together the following code that works for 32bit Excel on 64bit Windows 10, but I don't know how to modify it to get it working again with 64bit Excel:

Option Explicit

Type SHELLEXECUTEINFO
    cbSize As LongPtr
    fMask As Long
    hwnd As LongPtr
    lpVerb As String
    lpFile As String
    lpParameters As String
    lpDirectory As String
    nShow As Long
    hInstApp As Long
    lpIDList As Long
    lpClass As String
    hkeyClass As Long
    dwHotKey As Long
    hIcon As LongPtr
    hProcess As Long
End Type

Public Declare PtrSafe Function ShellExecuteEx Lib "shell32.dll" _
                                       (lpExecInfo As SHELLEXECUTEINFO) As LongPtr


Declare PtrSafe Function Wow64DisableWow64FsRedirection Lib "kernel32.dll" (ByRef ptr As LongPtr) As Boolean
Declare PtrSafe Function Wow64RevertWow64FsRedirection Lib "kernel32.dll" (ByRef ptr As LongPtr) As Boolean

Public Function KeyboardOpen()
  Dim shInfo As SHELLEXECUTEINFO
  Dim lngPtr As LongPtr

   With shInfo
      .cbSize = Len(shInfo)
      .lpFile = "C:\Windows\Sysnative\cmd.exe" 'best to use Known folders here
      .lpParameters = "/c start osk.exe"
      .lpDirectory = "C:\windows\system32" 'best to use Known folders here
      .lpVerb = "open"
      .nShow = 0
   End With
   Call Wow64DisableWow64FsRedirection(lngPtr)
   Call ShellExecuteEx(shInfo)
   Call Wow64RevertWow64FsRedirection(lngPtr)
End Function

Sub OpenKeyboard()
Call KeyboardOpen
End Sub
  • I'm on 64-Bit Windows 7 and my VBA didn't like the keyword `PtrSafe` in your Declare statements. I had to remove them for the compiler to stop giving me error messages on those lines. VBA version 6.5.1020. In Excel 2007 v12.0.4518.1014 – Toddleson Aug 19 '21 at 14:19
  • It also gave me "User defined type not defined" error on every `As LongPtr` variable type definition. After I changed them all to `As Long`, the code worked and the On-Screen Keyboard opened! – Toddleson Aug 19 '21 at 14:22
  • @Toddleson The bitness of Windows has no relation to this, only the Office bitness. You have a 32-bit old unsupported Office that does not have VBA7, LongPtr and PtrSafe. That is not a reason to tell other people to remove these correct and necessary keywords. Like the OP has mentioned, this code already works on 32-bit. – GSerg Aug 19 '21 at 14:46
  • 1
    You appear to have randomly replaced some `Long`s with `LongPtr` which you [should have not done](https://stackoverflow.com/a/63801528/11683). Please consult the [documentation](https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-shellexecuteinfoa) and use correct types. You must also provide the [64-bit padding](https://stackoverflow.com/a/66736433/11683) manually where required, and the `Declare`s are also all wrong. You are getting away with it on 32-bit because `LongPtr` equals `Long` there. You are *not* getting away with the incorrect call to RevertRedirection. – GSerg Aug 19 '21 at 14:53
  • On a second thought, this code could have never worked because `ShellExecuteEx` is not a function that exists in shell32.dll. Is there a reason why you cannot simply do `Shell "C:\windows\system32\osk.exe"`, or a version thereof that "uses Known folders"? – GSerg Aug 19 '21 at 15:31
  • Hi GSerg, thank you for you detailed responses. I did not write the code, but it does work without problem (on 32bit Excel on 64bit Windows). I am not a trained coder (I can only hack together bits and pieces of other code). Ultimately all I want to do is show an onscreen keyboard via a button on a userform in 64bit office. If you know of a way to do this I would be most appreciative – Jonathan Walker Aug 24 '21 at 10:16

1 Answers1

0

I have found a solution. To get the 64bit Windows 10 On screen keyboard (osk.exe) to run, add the following code to a module to a 64bit Excel, then you can call OpenKeyboardSub from within your application:

Private Declare PtrSafe 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

Sub OpenKeyboardSub()
    ShellExecute 0, vbNullString, "osk.exe", vbNullString, "C:\", 1
    End Sub