Страницы: 1
RSS
Особенности декларирования WinApi функций для 32-бит и 64-бит ОС и Офиса, конкретно функции смены раскладки клавиатуры - ActivateKeyboardLayout
 
Добрый день, уважаемые форумчане
столкнулся с проблемой выполнения макроса для смены раскладки клавиатуры, декларация функции WinAPI делалась под 32-битный Офис:
Код
 Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal flags As Long) As Long
 
В процесе работы этот же файл нужно использовать на компютерах и 32 и 64 битной разрядностью
Пробовал пойти вот таким путем:
Код
 #If Win64 Then Private Declare PtrSafe Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As LongLong, ByVal flags As LongLong) As LongLong #Else Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal flags As Long) As Long #End If

в процесе исполнения 4 строка выделяется красным, а макрос не отрабатывает (в 64 бит Офисе при этом в 32 битном проблем нет) .
Прошу помочь разобраться
 
вроде как #If VB7
F1 творит чудеса
 
Здрасьте.
Код
#If Win64 Then
Private Declare PtrSafe Function LoadKeyboardLayoutA Lib "user32" (ByVal pwszKLID As String, ByVal flags As Long) As LongPtr
Private Declare PtrSafe Function ActivateKeyboardLayoutA Lib "user32" Alias "ActivateKeyboardLayout" (ByVal HKL As LongPtr, ByVal flags As Long) As LongPtr
Private Declare PtrSafe Function UnloadKeyboardLayoutA Lib "user32" Alias "UnloadKeyboardLayout" (ByVal HKL As LongPtr) As Long
Private Declare PtrSafe Function GetKeyboardLayoutNameA Lib "user32" (ByVal pwszKLID As String) As Long
#Else
Private Declare Function LoadKeyboardLayoutA Lib "user32" (ByVal pwszKLID As String, ByVal flags As Long) As Long
Private Declare Function ActivateKeyboardLayoutA Lib "user32" Alias "ActivateKeyboardLayout" (ByVal HKL As Long, ByVal flags As Long) As Long
Private Declare Function UnloadKeyboardLayoutA Lib "user32" Alias "UnloadKeyboardLayout" (ByVal HKL As Long) As Long
Private Declare Function GetKeyboardLayoutNameA Lib "user32" (ByVal pwszKLID As String) As Long
#End If
Итутмоно глянуть
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
Здесь почитайте.
There is no knowledge that is not power
 
или здесь
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Спасибо всем кто отписался, перечитал информацию за ссылками
многое ужевидел до того как создал тему, но проблема осталась:
не получается корректно задекларировать функцию под 64-бит версию Офиса и Екселя
(как вариант подозреваю что проблема может быть в константах (или их типах) с которыми она используеться )
подскажите кто знает где "собака зарыта" ? :(
прилагаю файл и изображение с ошибкой и версиями Excel и Office
 
Зачем вы добавили & в вызов функции ActivateKeyboardLayout? Это ведь не Long, а LongPtr. Уберите, все заработает
F1 творит чудеса
 
Максим Зеленский, я убрал символ теперь не выдает ошибки, но и не отрабатывает
У Вас макрос из примера работает?  
 
Код
Public Const kb_lay_ua As Long = 69338146
Public Const kb_lay_en As Long = 67699721
надо
Код
Public Const kb_lay_ua As LongPtr = 69338146
Public Const kb_lay_en As LongPtr = 67699721
либо
Код
Public Const kb_lay_ua = 69338146
Public Const kb_lay_en = 67699721

Тип передаваемых в функции параметров должен соответствовать типам, объявленным в самой функции.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
The_Prist, первый предложеный Вами вариант пробовал накануне так как логика подсказывала  :) ,
второй вариант попробовал только что - не работает
Еще
Цитата
Зачем вы добавили & в вызов функции ActivateKeyboardLayout? Это ведь не Long, а LongPtr. Уберите, все заработает
такой вариант работает для станции с 32-бит Офисом
П.С. эта функция вообще рабочая для 64 бит ?
 
Цитата
Vitallic пишет: но и не отрабатывает
ну у меня нет раскладки украинской, может, поэтому
F1 творит чудеса
 
это ж не принципиально,
меняет ли макрос раскладку с англ. на рос. ?
Код
Public Const kb_lay_ru As Long = 68748313
Изменено: Vitallic - 21.01.2015 23:23:56
 
да
Цитата
Vitallic пишет: П.С. эта функция вообще рабочая для 64 бит ?
скачайте Office2010 Win32API PtrSafe, там все 64-разр. функции и их декларации
Изменено: Максим Зеленский - 21.01.2015 23:24:07
F1 творит чудеса
 
Вообще можете еще попробовать LongLong вместо LongPtr (заменить везде). Если у Вас 2010 и 64-бита - дело может быть в этом. Т.к. там 8-битные указатели.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
Максим Зеленский пишет: скачайте Office2010 Win32API PtrSafe
в сообщении №6 у меня ссылка на этот же материал, то есть я пересмотрел
апдейт функций для 64-бит и (как можно увидеть) с примера -  функция задекларирована
правильно, я предполагаю что проблема с аргументами (или их типами).

The_Prist, пробовал такой вариант еще до написания этой темы, так как нашел
Ваше обьяснение от 2012г. но непонятно сработало ли оно у того пользователя,
потом переключился на тип LongPtr согласно  коментариям уважаемого EducatedFool
 
методом "научного тыка" удалось выяснить что для моей 32 розрядной машини (Excel 2010 32bit под ОС XP32bit)
любой из нижеизложеных вариантов рабочий:
Код
Option Explicit
Private Declare PtrSafe Function ActivateKeyboardLayout Lib "user32" _
                                        (ByVal HKL As LongPtr, ByVal flags As Long) As LongPtr
                                        
Dim X As LongPtr
Public Const kb_lay_ua As LongPtr 
'Dim kb_lay_en As LongPtr
Public Sub SetLayout()
    X = ActivateKeyboardLayout(kb_lay_ua, 0)  
 End Sub

а также если в качестве аргумента:
Код
  X = ActivateKeyboardLayout(69338146, 0)   
или
Код
    X = ActivateKeyboardLayout(&H4220422, 0)
 
раскладка меняется на укр.
В то же время тестируя изложеные варианты на машине с Excel2010 64bit Win7 64bit
получил полуположительный результат только при варианте
Код
 X = ActivateKeyboardLayout(kb_lay_ua, 0) 
при этом, как понимаете, назва аргумента значения не имеет, а результат  "полуположительный" потому как
при отработке макроса происходит пошаговое измениение языка вывода с клавиатуры (у меня это: с анг. на рус. потом укр.)
что показательно если зделать вот такую запись:
Код
 X = ActivateKeyboardLayout(kb_lay_ua+1, 0)  
то перескакивает сразу на укр. раскладку (то есть аргумент принимается как отправная точка)
таким образом (если я не ошибаюсь) проблема сузилась до определения значения аргумента под названием HKL
которое в 32bit было (для рус. раскладки):
для десятеричной системы - 68748313
для шестнадцатиричной системы - &H4190419
Уважаемые форумчане подскажите откуда взялись эти цифри???
и как они должны выглядить для 64bit приложения
 
ЕСТЬ РЕШЕНИЕ:

Код
Option Explicit
Private Declare PtrSafe Function ActivateKeyboardLayout Lib "user32" _
                                        (ByVal HKL As LongPtr, ByVal flags As Long) As LongPtr
                                        
Dim X As LongPtr
#If Win64 Then
Const kb_lay_ua As LongPtr = -257424350
#Else
Const kb_lay_ua As LongPtr = 69338146
#End If
Public Sub SetLayout()
    X = ActivateKeyboardLayout(kb_lay_ua, 0)
    Debug.Print X
End Sub
 
таким образом для 64bit параметр HKL
ua - 257424350 (первый знак минус)
ru 68748313
en 67699721
может это только частный случай на моем комп., но тем не менее макрос рабочий

П.С. для 32bit параметр HKL есть в интернете по поиску.  
 
Цитата
Vitallic пишет: подскажите откуда взялись эти цифри ???
покопайте сюда
Код
Declare PtrSafe Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As LongPtr
'The return value is the input locale identifier for the thread. 
'The low word contains a Language Identifier for the input language
' and the high word contains a device handle to the physical layout of the keyboard.
Sub fff()
   Debug.Print GetKeyboardLayout(0) ' 67699721 English US
   Debug.Print Hex(GetKeyboardLayout(0)) ' 4090409
   Debug.Print Val(GetKeyboardLayout(0) & Chr(0)) '67699721
End Sub 

Language Identifier
F1 творит чудеса
Страницы: 1
Наверх