Office VBA 64/32共用 osk.exe オンスクリーンキーボードの起動

#OSK.Exeの使い道
OSK.exeとはオンスクリーンキーボードの略です。短すぎてわかりづらいですが。タブレットのようなものでは表示させますが、デスクトップではあまり使い道がありません。
が、テンキーのオンオフ、CAPSLockのオンオフ、そしてスクロールのオンオフが視覚的にわかります。
スクロールロックってなぜあんなに忘れたころかかるのでしょう。謎です。
今のキーボードは押したか押していないかわかりにくいので、キーボードがおかしいとき、とりあえず起動するアイテムです。

#実はOSが32ビット版だとエラーになる
OSが32bit版だとオンスクリーンキーボードの起動がエラーになるそうです。
今回はOSが32bit版だと`%SystemRoot%\SysWow64\oks.exe`が存在しないため`%SystemRoot%\System32\oks.exe`とするとSysWow64にリダイレクトされてファイルが見つからないというエラーが起きるということです。
ちょっと信じられないようなエラーです。ふつうは両方置いてあるのに。
しかし、確かに64Bit版のSysWow64を見たのですがありません。

[フォームに作成したボタンを押して、ソフトキーボード(osk.exe)を表示したい](https://teratail.com/questions/244829)
[Calling On-Screen Keyboard from Excel VBA](https://stackoverflow.com/questions/49826995/calling-on-screen-keyboard-from-excel-vba)

しかし、これらは64bit版のOfficeを前提にしていません。
さらにサンプルは64ビットで動かしたときの視点がありません。
本来は64bit版Officeは不要というか、***絶対に使ってはいけない***バージョンのため、要注意です。
Microsoftもメディアも一切説明しないのは不誠実です。
なぜなら、条件付き編纂命令（Const　Directive）が必要になるためです。
64bit版は大して早くもないし、唯一使えるのはBigInt型がAccessで使えるくらいです。Jscriptも使えない。
何一つメリットがありません。

そこで、別に多分ここまでやらなくてもいいのかもしれませんが、StackOverFlowのサンプルをもとに、共用化しています。
##Point1 条件付き編纂命令
これを64bitと32Bitに分けます。しかしここはOSではなく、Excel、Officeの64bitかそうではないかです。
このコードは共用を目指すので考慮します。

##Point2 OSの64bit判定に環境変数を用いる
ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%")
この結果がAMD64であると64Bitです
これはVBSCRIPTでも64bitと32bitを判定するときに使います。大変重要なキーテクニックです。
ただしEMacsを使っているときは効かないそうです。[](https://nagayasu-shinya.com/msdos-processor-arch/)
[64bitと32bitの環境変数の値の違い WOW64 Implementation Details](https://docs.microsoft.com/ja-jp/windows/win32/winprog64/wow64-implementation-details?redirectedfrom=MSDN)
##Point3 32Bitのリダイレクトを一時的にオフにする
これがすごいと思いました。
勝手にリダイレクトしているのを一度止めてSystem32にアクセスするというのです。

```vb
' Point 1
#If VBA7 And Win64 Then
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
Private Declare PtrSafe Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" (ByVal Enable As Boolean) As Boolean
#Else
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
#End If


Private Sub RunOnScreenKeyBord6432()
Const SW_SHOWNORMAL = 1
On Error Resume Next
With CreateObject("WScript.Shell") 'Point 2
Debug.Print .ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%")
If .ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") <> "AMD64" Then
    Wow64EnableWow64FsRedirection False ' Point 3
    ShellExecute 0, "open", "osk.exe", "", "C:\windows\system32\osk.exe", SW_SHOWNORMAL
    Wow64EnableWow64FsRedirection True
Else
    ShellExecute 0, "open", "osk.exe", "", "C:\windows\system32\osk.exe", SW_SHOWNORMAL
End If
End With
If Err.Number <> 0 Then Debug.Print Err.Number , Err.Description : Err.Clear
End Sub
```

#参考
ShellExecuteの解説
http://tokovalue.jp/function/ShellExecute.htm
http://cya.sakura.ne.jp/vb/ShellExecute.htm
本来はエラーも定義しますね。
http://www.asahi-net.or.jp/~ef2o-inue/api/sub08_01_030.html
こちらも64Bit対応。しかし動かないのはおそらくデフォルトで64Bitでインストールするからでしょう。