Тема действительно интересная, мне она помогла узнать кое-что новое (спасибо cadhelp'у) и вспомнить кое-что забытое старое. В итоге, обсуждение стало перерастать поднятый вопрос. Как и положено в хороших домах.
Проблема с разночтениями возвращаемых функцией GetKeyState значений кроется в том, что она возвращает, собственно говоря, не число, а 16-разрядное битовое поле, в котором смысловую нагрузку несут только значения отдельных битов - для рассматриваемой функции это могут быть нулевой и 15-й бит. Однако VB не понимает двоичных слов и автоматически переводит их в десятичные числа не имеющие никакого смысла, причем значение 15-го бита воспринимается и интерпретируется как знак числа (отсюда -127).
Чтобы прояснить картину я предлагаю небольшую утитлиту, читающую бинарные выражения:
'Программа VB_BINARY преназначена для чтения средствами VB бинарых выражений,
'(по-битово)
Option Explicit
'в качестве бинарного выражения используем значение, возвращаемое функцией GetKeyState,
'которое представляет собой информацию
'о состоянии заданной виртуальной клавиши nVirtKey:
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Sub Binary_Read()
Dim nVirtKey As Integer
nVirtKey = vbKeyControl 'получаем, например, состояние клавиши Ctrl
Dim Bit_ValueArray(15) As Byte 'массив значений битов
Dim i As Integer
Dim Bit_ValueString As String
For i = 0 To 15
Bit_ValueArray(i) = Bit_Value(nVirtKey, i)
Bit_ValueString = Bit_ValueString & Bit_ValueArray(i) & Space(1)
Next i
MsgBox Bit_ValueString
End Sub
Private Function Bit_Value(ByVal nVirtKey As Long, ByVal iMask As Integer) As Integer
'для определения значения битов используем поразрядную конъюнкцию с логическим 1 по принципу:
'0 And 1 =0
'1 And 1 =1
'iMask - номер определямого бита (маска)
Bit_Value = IIf((GetKeyState(nVirtKey) And 2 ^ iMask) = 0, 0, 1)
End Function
Возвращаясь к вопросу о распознавании состояния клавиши, можно сказать, что надежнее задавать "чисто конкретно" условие в виде: Bit_Value = IIf((GetKeyState(nVirtKey) And 2 ^ iMask) = 0, 0, 1), где iMask=15 для определения нажатой клавиши, и iMask=0 для определения положения клавишей-переключателей.