質問

XPでVBAを実行しているActivateKeyboardLayoutを呼び出して、入力言語を英語から別の言語に切り替えることができました。ただし、これはVista64では動作しなくなりました。

提案や回避策はありますか

XPで動作していたコードは次のようになりました:

Private Declare Function ActivateKeyboardLayout Lib "user32" ( _
    ByVal HKL As Long, ByVal flags As Integer) As Integer
Const aklPUNJABI As Long = &H4460446
ActivateKeyboardLayout aklPUNJABI, 0

試してみる提案がありました

Public Declare Function ActivateKeyboardLayout Lib "user32" ( _
    ByVal nkl As IntPtr, ByVal Flags As uint) As Integer

これを試みると、エラーメッセージが表示されます。

変数はVisual Basicでサポートされていないオートメーションタイプを使用します

役に立ちましたか?

解決

ActivateKeyboardLayoutの宣言は実際には正しくありません。 32ビットシステムの場合、コードは次のようになります。

Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, _
    ByVal flags As Long) As Long

Const aklPUNJABI As Long = &H4460446
Dim oldLayout as Long
oldLayout = ActivateKeyboardLayout(aklPUNJABI, 0)
If oldLayout = 0 Then
   'Oops an error'
Else
   'Save old layout for later restore?'
End If

この場合、オペレーティングシステムの64ビットはわずかに赤いニシンです。 VBAアプリを実行しているため、OSに関係なく32ビットアプリとして実行する必要があります。あなたの問題はあなたのVistaシステムであなたが望むパンジャブ語のキーボードレイアウトがロードされていないかもしれないと思う。 ActivateKeyboardLayoutは、既にロードされているキーボードレイアウトをアクティブにする場合にのみ機能します。何らかの理由で、このAPIの設計者は、キーボードレイアウトが存在しないために発生したエラーはエラーではなく、LastDllErrorが設定されていないと感じていました。このような状況でLoadKeyboardLayoutを使用することを検討してください。

編集:取得しようとしているキーボードレイアウトが実際に読み込まれていることを再確認するには、これを使用できます:

Private Declare Function GetKeyboardLayoutList Lib "user32" (ByVal size As Long, _
    ByRef layouts As Long) As Long

Dim numLayouts As Long
Dim i As Long
Dim layouts() As Long

numLayouts = GetKeyboardLayoutList(0, ByVal 0&)
ReDim layouts(numLayouts - 1)
GetKeyboardLayoutList numLayouts, layouts(0)

Dim msg As String
msg = "Loaded keyboard layouts: " & vbCrLf & vbCrLf

For i = 0 To numLayouts - 1
   msg = msg & Hex(layouts(i)) & vbCrLf
Next

MsgBox msg

他のヒント

これは盲目的な推測に過ぎませんが、昇格した管理者としてアプリを実行して、違いが生じるかどうかを確認しましたか? GetLastErrorのエラーコード/値は何ですか?

.Net行 VB.Netスクリプトまたはこれらのスニペット)のように:

InputLanguage.CurrentInputLanguage = 
    InputLanguage.FromCulture(New System.Globalization.CultureInfo("ar-EG"))

InputLanguage .Net3.5

でVista64をサポート

VB.Netコード:

Public Sub ChangeInputLanguage(ByVal InputLang As InputLanguage)
   If InputLanguage.InstalledInputLanguages.IndexOf(InputLang) = -1 Then
        Throw New ArgumentOutOfRangeException()
   End If
    InputLanguage.CurrentInputLanguage = InputLang
End Sub

64ビットの移植性のために、IntPtrを使用する必要がある場合があります。これを試してもらえますか

Public Declare Function ActivateKeyboardLayout Lib "user32" (ByVal nkl As IntPtr, ByVal Flags As uint) As Integer

64ビット版のOfficeアプリでは、VBAは実際には64ビットです。 Office 2010のドキュメントをご覧ください。変更の詳細。 Stephen Martinの回答、次のようにコードを変更してPtrSafe属性を追加し、Win32 APIのHKLタイプのパラメーターを修正する必要があります。

Private Declare PtrSafe Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As LongPtr, _
    ByVal flags As Long) As LongPtr

Const aklPUNJABI As LongPtr = &H4460446
Dim oldLayout as LongPtr
oldLayout = ActivateKeyboardLayout(aklPUNJABI, 0)
If oldLayout = 0 Then
   'Oops an error'
Else
   'Save old layout for later restore?'
End If

and

Private Declare PtrSafe Function GetKeyboardLayoutList Lib "user32" (ByVal size As Long, _
    ByRef layouts As LongPtr) As Long

Dim numLayouts As Long
Dim i As Long
Dim layouts() As LongPtr

numLayouts = GetKeyboardLayoutList(0, ByVal 0&)
ReDim layouts(numLayouts - 1)
GetKeyboardLayoutList numLayouts, layouts(0)

Dim msg As String
msg = "Loaded keyboard layouts: " & vbCrLf & vbCrLf

For i = 0 To numLayouts - 1
   msg = msg & Hex(layouts(i)) & vbCrLf
Next

MsgBox msg

ここで誰もが見落としているように見えるのは、.NETではなくVBAで作業しているということです。 IntPtrは、プラットフォーム固有の整数を表す.NET型です。 32ビットプラットフォームでは32ビット、64ビットプラットフォームでは64ビットです。

HKLはハンドルのtypedefであり、これはVOID *のtypedefであるPVOIDのtypedefであるため、.NETを使用している場合はまさにそれが必要です。

VBAには64ビットの数値に対するものがないため、別のアプローチをとる必要があります。

64ビットマシンでは、次のようにする必要があります。

Public Type HKL64
    High As Long
    Low As Long
End Type

Private Declare Function ActivateKeyboardLayout Lib "user32" ( _
    Byval HklHigh As Long, Byval HklLow As Long, _
    ByVal flags As Integer) As HKL64

この により、スタック上の64ビット値をAPI関数に渡すことができます(2つの変数にわたって)。ただし、64ビットと32ビットのマシンでこのコードを使用する場合は、APIを2回宣言してから、どちらを呼び出すかを決定する必要があります。

また、ポインターまたはハンドルを処理するAPIを呼び出すVBAの他のコードは、32ビットではなく64ビット入力を処理するために適切に変更する必要があります。

副次的に、ActivateKeyboardLayoutの元の宣言は間違っています。戻り値の型は16ビット値のIntegerでしたが、APIは32ビットまたは64ビットのHKLの型を返します。プラットフォーム上。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top