5

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 でサポートされていない Automation 型を使用しています

4

6 に答える 6

5

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 の使用を検討することをお勧めします。

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

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
于 2009-02-16T18:21:11.813 に答える
0

Office アプリの 64 ビット エディションでは、VBA は実際には 64 ビットです。変更の詳細については、 Office 2010 のドキュメントを参照してください。Stephen Martin の answerに示されている例では、次のようにコードを変更して、属性を追加し、Win32 APIPtrSafeの型を持つパラメーターを修正する必要があります。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

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
于 2016-12-03T00:33:09.257 に答える
0

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

Public Declare Function ActivateKeyboardLayout Lib "user32" (ByVal nkl As IntPtr, ByVal Flags As uint) As Integer
于 2009-02-14T17:49:15.287 に答える
0

次のような.Net行VB.Netスクリプトまたはそれらのスニペットのように)を試しましたか?

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

.Net3.5を使用する Vista64 では、 InputLanguageをサポートする必要があります。

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
于 2009-02-13T08:01:53.960 に答える
0

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

于 2009-01-16T03:07:35.650 に答える
-1

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

HKL が VOID * の typedef である PVOID の typedef であるハンドルの 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 のその他のコードは、64 ビット入力 (32 ではなく) を処理するように適切に変更する必要があります。

余談ですが、ActivateKeyboardLayout の元の宣言は間違っています。戻り値の型が 16 ビット値の Integer であるのに対し、API はプラットフォームに応じて 32 ビットまたは 64 ビットの HKL 型を返します。 .

于 2009-02-19T01:12:48.327 に答える