2015-10-12 2 views
0

я поддерживаю приложение, которое отображает ключ состояния Caps Lock, Num Lock и Вставить ключи. Я использовал метод user32.dllGetKeyState() для достижения этой цели, как так:Как определить INS состояние клавиши

Public Declare Function GetKeyState Lib "user32" Alias "GetKeyState" (ByVal nVirtKey As Long) As Integer 

Public Sub CheckKeys() 
    lblCaps.ForeColor = CType(IIf(GetKeyState(Keys.CapsLock) <> 0, Color.Black, Color.Gray), System.Drawing.Color) 
    lblIns.ForeColor = CType(IIf(GetKeyState(Keys.Insert) <> 0, Color.Black, Color.Gray), System.Drawing.Color) 
    lblNum.ForeColor = CType(IIf(GetKeyState(Keys.NumLock) <> 0, Color.Black, Color.Gray), System.Drawing.Color) 
End Sub 

Это работало отлично, но теперь после обновления целевой базы для .NET 4.0, я получаю сообщение об ошибке от Managed Debugging Assistant:

Вызов функции PInvoke '[application] :: GetKeyState' имеет несбалансированный стек. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой сигнатуре. Убедитесь, что соглашение о вызове и параметры сигнатуры PInvoke соответствуют целевой неуправляемой подписи.

Я знаю, что я могу получить статус Caps Lock и Num Lock ключей с помощью My.Computer.Keyboard.CapsLock и My.Computer.Keyboard.NumLock булевых значений, соответственно, но есть подобный способ получить состояние ключа Вставки ?

+1

Декларация неверна, аргумент должен быть целым, возвращаемое значение - короткое. Код тоже не так, вы должны проверить бит # 0, чтобы отличить текущее состояние от нажатого состояния. Используйте GetKeyState (Keys.CapsLock) и 1. –

ответ

1

Ваш P/Invoke подпись неправильно:

Public Declare Function GetKeyState Lib "user32" Alias "GetKeyState" (ByVal nVirtKey As Long) As Short 

MSDN statesGetKeyState «s nVirtKey параметр типа int и тип возвращаемого значения short, то есть 32-разрядное знаковое и 16-битное целое число соответственно. В VB.NET тип Long равен Int64, поэтому вы переписываете стек.

В VB6, Long был 32-разрядное знаковое и Integer был 16-разрядное знаковое значение и Short не было ключевое слово, так что изменения VB.NET были нарушения.

Измените свой параметр на ByVal nVirtKey As Integer и тип возврата до As Short.

Отмечу, что ключ Вставка, в отличие от Caps-Lock и Num-Lock, не имеет системного состояния и варьируется для каждого приложения или даже для управления. Я считаю (хотя и не уверен), что сохранение состояния ключа Insert является вашей ответственностью и что GetKeyState не будет работать так, как вы намереваетесь с помощью клавиши Insert в частности.

+0

И возвращаемое значение - это SHORT – Steve

+0

Это была именно проблема. Я использовал эту подпись в течение по крайней мере нескольких лет и не имел никаких проблем до обновления целевой платформы до .NET 4.0. Может быть, старый фреймворк не был таким разборчивым или, может быть, не использовал помощника по управлению отладки. Благодаря! –