Wie kann ich ActivateKeyBoardLayout von 64-Bit-Windows Vista mit VBA aufrufen
-
19-08-2019 - |
Frage
Ausführen von VBA unter XP konnte ich ActivateKeyBoardLayout nennt meine Eingabesprache von Englisch in einer anderen Sprache zu wechseln. Allerdings ist dies nicht mehr funktioniert unter Vista64.
Irgendwelche Vorschläge oder Abhilfen?
Der Code, der unter XP verwendet zu arbeiten, war ähnlich der folgenden:
Private Declare Function ActivateKeyboardLayout Lib "user32" ( _
ByVal HKL As Long, ByVal flags As Integer) As Integer
Const aklPUNJABI As Long = &H4460446
ActivateKeyboardLayout aklPUNJABI, 0
Es gab einen Vorschlag, um zu versuchen
Public Declare Function ActivateKeyboardLayout Lib "user32" ( _
ByVal nkl As IntPtr, ByVal Flags As uint) As Integer
Wenn ich das versuche ich erhalte die Fehlermeldung:
Variable verwendet einen Automatisierungstyp in Visual Basic nicht unterstützt
Lösung
Ihre Erklärung für die ActivateKeyBoardLayout ist eigentlich falsch. Für 32-Bit-Systeme Code in etwa so sein sollte:
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
Der 64-Bitness des Betriebssystems ist ein bisschen wie ein roter Hering in diesem Fall. Da Sie einen VBA-App ausgeführt werden muss als 32-Bit-Anwendung unabhängig von OS ausgeführt werden. Ich vermute, dass das Problem, dass auf Ihrem Vista-System sein kann, das Punjabi Tastaturlayout, die Sie wollen nicht geladen ist. ActivateKeyBoardLayout wird nur funktionieren, ein Tastaturlayout zu aktivieren, die bereits geladen ist. Aus irgendeinem Grund fühlte sich die Designer dieser API, dass ein Scheitern aufgrund der Tastaturlayout nicht vorhanden war kein Fehler, so wird die LastDllError nicht gesetzt. Sie können LoadKeyboardLayout in Verwendung für diese Art von Situation zu suchen.
EDIT: Um zu überprüfen, dass das Tastaturlayout Sie tatsächlich zu bekommen versuchen geladen Sie diese verwenden können:
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
Andere Tipps
Dies ist nur eine blinde Vermutung, aber haben Sie versucht, Ihre App als erhöhte Administrator ausführen, um zu sehen, ob es einen Unterschied macht? Was ist der Fehlercode / Wert von GetLastError?
Haben Sie versucht, eine .Net Linie (wie in VB.Net Skript oder diese Schnipsel ) wie:
InputLanguage.CurrentInputLanguage =
InputLanguage.FromCulture(New System.Globalization.CultureInfo("ar-EG"))
Inputlanguage sollte unterstützt für Vista64 mit einem NET3.5
VB.Net Code:
Public Sub ChangeInputLanguage(ByVal InputLang As InputLanguage)
If InputLanguage.InstalledInputLanguages.IndexOf(InputLang) = -1 Then
Throw New ArgumentOutOfRangeException()
End If
InputLanguage.CurrentInputLanguage = InputLang
End Sub
Für 64-Bit-Portabilität Sie müssen IntPtr verwenden. Können Sie diese ein Schuss?
Public Declare Function ActivateKeyboardLayout Lib "user32" (ByVal nkl As IntPtr, ByVal Flags As uint) As Integer
In 64-Bit-Editionen von Office-Anwendungen, VBA ist in der Tat 64-Bit. Siehe Office 2010 Dokumentation Einzelheiten zu den Änderungen. Für das Beispiel gegeben in Stephen Martin Antwort , müssen Sie den Code ändern als das PtrSafe
Attribut hinzufügen folgt und die Parameter fixup, die einen HKL
Typ in der Win32-API haben:
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
und
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
Die Sache, die jeder hier zu übersehen scheint, ist, dass Sie in VBA, nicht in .NET arbeiten. IntPtr ist ein .NET-Typ, die eine ganze Zahl darstellt, die an der Plattform heimisch ist. Auf einer 32-Bit-Plattform es 32 Bit, auf einer 64-Bit-Plattform, ist es 64 Bit.
Da ein HKL ein typedef für einen Handgriff ist, der ein typedef für PVOID ist, die ein typedef für VOID *, es ist genau das, was Sie brauchen, wenn Sie .NET verwendet haben.
VBA hat nichts für 64-Bit-Zahlen, so dass Sie einen anderen Ansatz nehmen.
Auf einer 64-Bit-Maschine, Sie haben etwas zu tun:
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
Das sollte können Sie einen 64-Bit-Wert auf dem Stapel auf die API-Funktion übergeben (über zwei Variablen). wenn Sie diesen Code jedoch werden auf 64 Bit verwenden, und 32-Bit-Maschinen, Sie gehen zu müssen, zwei Erklärungen der API machen und dann bestimmen, welche zu nennen.
Auch andere Code in VBA, die APIs, die mit Zeigern oder Griffen umgehen Anrufe müssen in geeigneter Weise Eingang zu handhaben 64 Bit geändert werden (nicht 32).
Auf einer Seite beachten, ist die ursprüngliche Erklärung ActivateKeyBoardLayout falsch, da sie einen Rückgabetyp Integer hatte, was ein 16-Bit-Wert ist, während die API eine Art von HKL zurückgibt, die 32 oder 64 Bits ist, je auf der Plattform.