VBA를 사용하여 64 비트 Windows Vista에서 activeKeyboardLayout을 호출하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/449207

문제

XP에서 VBA를 실행하면 ActiveKeyboardLayout을 호출하여 입력 언어를 영어에서 다른 언어로 전환 할 수있었습니다. 그러나 이것은 더 이상 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 시스템에서 당신이 원하는 펀잡 키보드 레이아웃이로드되지 않았다는 것입니다. ActiveKeyboardLayout은 이미로드 된 키보드 레이아웃 만 활성화하기 위해 작동합니다. 어떤 이유로이 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"))

입력 a .NET3.5

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 비트입니다. 보다 사무실 2010 문서 변경 사항에 대한 자세한 내용. 주어진 예제 스티븐 마틴의 대답, 추가하려면 다음과 같이 코드를 변경해야합니다. PtrSafe 속성 및 고정 a HKL Win32 API를 입력하십시오.

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

모두가 여기에서 간과하는 것처럼 보이는 것은 .net이 아닌 VBA에서 일하고 있다는 것입니다. intptr은 플랫폼에 기초한 정수를 나타내는 .NET 유형입니다. 32 비트 플랫폼에서는 64 비트 플랫폼에서 32 비트이며 64 비트입니다.

HKL이 핸들을위한 typedef, 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 함수 (두 변수에 걸쳐)로 전달할 수 있습니다. 그러나이 코드를 64 비트 및 32 비트 머신에서 사용하려면 API를 두 번 선언 한 다음 전화 할 것을 결정해야합니다.

또한 포인터 또는 핸들을 처리하는 API를 호출하는 VBA의 다른 코드는 64 비트 입력을 처리하려면 적절하게 변경해야합니다 (32).

참고로, ActiveKeyboardLayout의 원래 선언은 16 비트 값의 반환 정수 유형이 있었기 때문에 잘못된 반면 API는 플랫폼에 따라 32 또는 64 비트의 HKL 유형을 반환합니다. .

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top