Что нового

[Мышь, клавиатура] Переназначение функций клавиш F1-F12 на ноутбуке

Крепыш

Новичок
Сообщения
105
Репутация
2
Версия AutoIt: 3.3.8.x

Описание: Есть ноутбук Lenovo IdeaPad Z400 Touch. По "гениальной" задумке какого-то инженера на этом ноутбуке при нажатии клавиш F1-F12 по умолчанию работают мультимедийные функции. Чтобы работали стандартные функции F1-F12 нужно зажимать Fn. Что не удобно, например, при работе в Total Commander: вместо комбинации Shift + F6 нужно нажимать Shift + Fn + F6 (и т.п.).
Можно ли написать скрипт, который будет висеть в памяти и перехватывать нажатия клавиш F1-F12 и переназначать на них стандартные функции, а при зажатой Fn - мультимедийные, как на нормальных ноутбуках?

Примечания: Возможности изменить нестандартное поведение клавиатуры штатными средствами нет.
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
Крепыш
Кнопочка Fn не управляеться програмно.
Откройте настроки ноутбука вбиосе и там ищите параметры этой кнопки.
Там будет и режимы её работы.
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Если клавиши генерируют код, то можно попробовать так
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <Misc.au3>

OnAutoItExitRegister("Cleanup")

$hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
$hmod = _WinAPI_GetModuleHandle(0)
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)

While 1
  Sleep(1000)
WEnd

Func _KeyProc($nCode, $wParam, $lParam)
  Local $tKEYHOOKS
  $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
  If $nCode < 0 Then
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
  EndIf
  If $wParam = $WM_KEYDOWN Then
    ConsoleWrite("vkCode - " & DllStructGetData($tKEYHOOKS, "vkCode") & @CRLF)
    Switch DllStructGetData($tKEYHOOKS, "vkCode")
      Case 173        ; <= клавиша Mute
        _Send("{F1}") ; <= вместо Mute отправляем F1
        Return -1
      Case 174        ; <= Vol-
        _Send("{F2}") ; <= F2
        Return -1
      Case 175        ; <= Vol+
        _Send("{F3}") ; <= F3
        Return -1
    EndSwitch
  EndIf
  Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func Cleanup()
  _WinAPI_UnhookWindowsHookEx($hHook)
  DllCallbackFree($hStub_KeyProc)
EndFunc   ;==>Cleanup

Func _Send($key)
  Local $mod = ""
  If _IsPressed("10") Then $mod &= "+"
  If _IsPressed("11") Then $mod &= "^"
  If _IsPressed("12") Then $mod &= "!"
  Send($mod & $key)
EndFunc   ;==>_Send

Запустите скрипт и нажимайте клавиши. В консоле будут отображаться коды клавиш. Те, которые отображаются можно доделать по аналогии (три клавиши я сделал).
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
InnI
Спасибо! Но теперь срабатывают сразу две функции. Мультимедийные можно отключить или никак?
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Крепыш
Попробуй заменить:
Код:
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)


На 'Return 0'
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Крепыш [?]
теперь срабатывают сразу две функции
Этого я и боялся :(

Z_Lenar [?]
Попробуй заменить:
Думаю, не поможет - там раньше выход идёт через возврат "-1". Т.е. клавиша в Windows не уходит. Вероятно на уровне железа обработка идёт...
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
А нет, отставить панику. Я скрипт случайно на паузу поставил, поэтому так получилось.
Сейчас перезапустил - работает (без внесения изменений).

А как теперь включить мультимедийные функции при зажатой клавише Fn?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я немного почитал про эти ноутбуки... На форумах пишут, что подобное поведение исправлено в последней версии BIOS.
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Крепыш [?]
А как теперь включить мультимедийные функции при зажатой клавише Fn?
Никак. В обратную сторону не работает.
Как вариант можно сделать переключение режима работы клавиш по нажатию, например, ScrollLock
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <Misc.au3>

Global $Media = False
OnAutoItExitRegister("Cleanup")

$hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
$hmod = _WinAPI_GetModuleHandle(0)
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)

While 1
  Sleep(1000)
WEnd

Func _KeyProc($nCode, $wParam, $lParam)
  Local $tKEYHOOKS
  $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
  If $nCode < 0 Then
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
  EndIf
  If $wParam = $WM_KEYDOWN Then
    ; ConsoleWrite("vkCode - " & DllStructGetData($tKEYHOOKS, "vkCode") & @CRLF)
    If DllStructGetData($tKEYHOOKS, "vkCode") = 145 Then $Media = Not $Media
    If Not $Media Then
      Switch DllStructGetData($tKEYHOOKS, "vkCode")
        Case 173        ; <= клавиша Mute
          _Send("{F1}") ; <= вместо Mute отправляем F1
          Return -1
        Case 174        ; <= Vol-
          _Send("{F2}") ; <= F2
          Return -1
        Case 175        ; <= Vol+
          _Send("{F3}") ; <= F3
          Return -1
      EndSwitch
    EndIf
  EndIf
  Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func Cleanup()
  _WinAPI_UnhookWindowsHookEx($hHook)
  DllCallbackFree($hStub_KeyProc)
EndFunc   ;==>Cleanup

Func _Send($key)
  Local $mod = ""
  If _IsPressed("10") Then $mod &= "+"
  If _IsPressed("11") Then $mod &= "^"
  If _IsPressed("12") Then $mod &= "!"
  Send($mod & $key)
EndFunc   ;==>_Send
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Yashied
Да, действительно, в последней версии BIOS эту "фичу" исправили. Спасибо!
Я и раньше хотел обновить BIOS, но на русскоязычном сайте не нашёл. К тому же, я звонил в техподдержку, там сказали, что на этом ноутбуке нельзя отключить данную функцию.
Сейчас скачал с англоязычного сайта новую версию BIOS, поставил - настройка переключения режима мультимедийных клавишей появилась.
Думаю, тему можно считать закрытой.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Крепыш сказал(а):
К тому же, я звонил в техподдержку, там сказали, что на этом ноутбуке нельзя отключить данную функцию.

В этом случае лучше сразу сдать эту поделку обратно в магазин, т.к. полный бред на лицо.
 

InnI

AutoIT Гуру
Сообщения
4,951
Репутация
1,446
Крепыш [?]
на этом ноутбуке нельзя отключить данную функцию
настройка переключения режима мультимедийных клавишей появилась
Я не понял, функционал можно переключить или нет? И как это работает - включает по умолчанию либо мультимедиа либо функциональные? (ну, нет у меня бука - хочу понять :smile: )
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
В старой версии BIOS возможности переназначения функций на клавишах F1-F12 не было. Т.е., по умолчанию работали мультимедийные функции, для вызова стандартных - надо зажимать Fn.
Я поискал новую версию на русскоязычном сайте Lenovo - не нашёл. Позвонил в техподдержку, поинтересовался возможностью отключения этой "фичи". "Специалист" попросил меня прочитать все пункты меню в BIOS, и выслушав, сказал, что "возможности отключения нет, так было задумано".
Сегодня я скачал и установил новую версию BIOS c англоязычного сайта Lenovo. В BIOS в разделе Configuration появился пункт меню HotKey Mode (Enable/Disable), который отвечает за поведение клавиш F1-F12: либо включены по-умолчанию мультимедийные функции, либо стандартные.
Вот как-то так.
 
Верх