Applied keyboard detection reports error

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
MIRKOSOFT
Posts: 334
Joined: 23 Sep 2014, 14:29

Applied keyboard detection reports error

21 Sep 2017, 16:16

Hi!

One of user of this forum created for me script which can recognize keyboard when is pressed key, here's code:

Code: Select all

#NoEnv
SetBatchLines -1

OnMessage(0xFF, "InputHandler")
RegisterRawInputDevices(1, 6)
Esc::ExitApp

InputHandler(wParam, lParam) {
    static RID_INPUT        := 0x10000003
    static RIDI_DEVICENAME  := 0x20000007

    Critical

    DllCall("GetRawInputData"
        , "Ptr",    lParam
        , "UInt",   RID_INPUT
        , "Ptr",    0
        , "UIntP",  size
        , "UInt",   8 + A_PtrSize * 2)
    VarSetCapacity(buffer, size)
    DllCall("GetRawInputData"
        , "Ptr",    lParam
        , "UInt",   RID_INPUT
        , "Ptr",    &buffer
        , "UIntP",  size
        , "UInt",   8 + A_PtrSize * 2)

    devHandle := NumGet(buffer, 8)
    SetFormat, IntegerFast, hex
    vk := NumGet(buffer, 8 + 2 * A_PtrSize + 6, "UShort")
    sc := NumGet(buffer, 08+A_PtrSize*2, "UShort")
    flg := NumGet(buffer, 10+A_PtrSize*2, "UShort")
    vky := StrGet (vk)
    scy := StrGet (sc)
    SetFormat, Integer, d
    StringTrimLeft, vkx, vky, 2
    StringTrimLeft, scx, scy, 2
    if StrLen(scx) = 2
	{
	scx := "0" . scx
	}
    else if StrLen(scx) = 1
	{
	scx := "00" . scx
	}
    klaves := "vk" . vkx . "sc" . scx
    KeyLen := StrLen(klaves)

    DllCall("GetRawInputDeviceInfo"
        , "Ptr",    devHandle
        , "UInt",   RIDI_DEVICENAME
        , "Ptr",    0
        , "UIntP",  size)
    VarSetCapacity(info, size)
    DllCall("GetRawInputDeviceInfo"
        , "Ptr",    devHandle
        , "UInt",   RIDI_DEVICENAME
        , "Ptr",    &info
        , "UIntP",  size)
    GotInfo := StrGet(&info)
    StringMid, GotID, GotInfo, 13 , 3
    if GotID =1A2
	{
	KB =Inland
	}
     Else if GotID = 030
	{
	KB =Adesso
	}
     Else if GotID =05A
	{
	KB =Wireless DELL
	}
     Else if GotID =04F
	{
	KB =Japanese
	}
     Else if GotID =1C4
	{
	KB =Keypad
	}
     Else if GotID =E0F
	{
	KB =Genesis Mouse
	}
     Else
	{
	KB = %GotInfo%
	KBID = %GotID%
	}

ToolTip % "`keyboard:`t"   KB
	. "`ndevice ID:`t"     GotID
        . "`nscancode vk:`t"     vk
        . "`nscancode sc:`t"     sc
        . "`nflags:`t"       flg
        . "`nkeycode:`t`t"   klaves
        . "`nCodeLen:`t"     KeyLensdds
	. "`npressed:`t`t"   A_TickCount
klaves := ""
KeyLen := 0
vky := ""
vkx := ""
scy := ""
scx := ""
}

RegisterRawInputDevices(usagePage, usage) {
    static RIDEV_INPUTSINK := 0x00000100
    VarSetCapacity(rawDevice, 8 + A_PtrSize)
    NumPut(usagePage,       rawDevice, 0, "UShort")
    NumPut(usage,           rawDevice, 2, "UShort")
    NumPut(RIDEV_INPUTSINK, rawDevice, 4, "UInt")
    NumPut(A_ScriptHWND,    rawDevice, 8, "UPtr")

    if !DllCall("RegisterRawInputDevices"
        , "Ptr",  &rawDevice
        , "UInt", 1
        , "UInt", 8 + A_PtrSize)
    {
        throw "Fail"
    }
}
I tried to apply it to script by this way:

Code: Select all

#SingleInstance force

#NoEnv
SetBatchLines -1

OnMessage(0xFF, "InputHandler")
RegisterRawInputDevices(1, 6)
Esc::ExitApp

InputHandler(wParam, lParam) {
    static RID_INPUT        := 0x10000003
    static RIDI_DEVICENAME  := 0x20000007

    Critical

    DllCall("GetRawInputData"
        , "Ptr",    lParam
        , "UInt",   RID_INPUT
        , "Ptr",    0
        , "UIntP",  size
        , "UInt",   8 + A_PtrSize * 2)
    VarSetCapacity(buffer, size)
    DllCall("GetRawInputData"
        , "Ptr",    lParam
        , "UInt",   RID_INPUT
        , "Ptr",    &buffer
        , "UIntP",  size
        , "UInt",   8 + A_PtrSize * 2)

    devHandle := NumGet(buffer, 8)
    SetFormat, IntegerFast, hex
    vk := NumGet(buffer, 8 + 2 * A_PtrSize + 6, "UShort")
    sc := NumGet(buffer, 08+A_PtrSize*2, "UShort")
    flg := NumGet(buffer, 10+A_PtrSize*2, "UShort")
    vky := StrGet (vk)
    scy := StrGet (sc)
    SetFormat, Integer, d
    StringTrimLeft, vkx, vky, 2
    StringTrimLeft, scx, scy, 2
    if StrLen(scx) = 2
	{
	scx := "0" . scx
	}
    else if StrLen(scx) = 1
	{
	scx := "00" . scx
	}
    klaves := "vk" . vkx . "sc" . scx
    KeyLen := StrLen(klaves)

    DllCall("GetRawInputDeviceInfo"
        , "Ptr",    devHandle
        , "UInt",   RIDI_DEVICENAME
        , "Ptr",    0
        , "UIntP",  size)
    VarSetCapacity(info, size)
    DllCall("GetRawInputDeviceInfo"
        , "Ptr",    devHandle
        , "UInt",   RIDI_DEVICENAME
        , "Ptr",    &info
        , "UIntP",  size)
    GotInfo := StrGet(&info)
    StringMid, GotID, GotInfo, 13 , 3
    if GotID =1A2
	{
	KB =Inland
	}
     Else if GotID = 030	; 1C4 = used before
	{
	KB =Adesso
	}
     Else if GotID =05A
	{
	KB =Wireless
	}
     Else if GotID =04F
	{
	KB =Japanese
	}
     Else if GotID =13B
	{
	KB =Dell PS/2
	}
     Else if GotID =1C4
	{
	KB =Keypad
	}
     Else
	{
	KB = %GotInfo%
	KBID = %GotID%
	}

RegisterRawInputDevices(usagePage, usage) {
    static RIDEV_INPUTSINK := 0x00000100
    VarSetCapacity(rawDevice, 8 + A_PtrSize)
    NumPut(usagePage,       rawDevice, 0, "UShort")
    NumPut(usage,           rawDevice, 2, "UShort")
    NumPut(RIDEV_INPUTSINK, rawDevice, 4, "UInt")
    NumPut(A_ScriptHWND,    rawDevice, 8, "UPtr")

    if !DllCall("RegisterRawInputDevices"
        , "Ptr",  &rawDevice
        , "UInt", 1
        , "UInt", 8 + A_PtrSize)
    {
        throw "Fail"
    }
}

; ==== EXAMPLE ====
    If klaves=SC029		; compare to keys
    {
        Send, {Raw};
	return
    }
    else If klaves=SC002		; compare to keys
    {
        Send, {Raw}~
	return
    }
But at start of script it reports error:

Error at line 94.
Line text: RegisterRawInputDevices(usagePage, usage)
Error: Functions cannot contain functions.
The program will exit.

Really I did only one simple thing - pasted original code to script.
Modified scripts works not.

Can anybody help me why it works not?

Thank you for all.
Miro
User avatar
TLM
Posts: 1608
Joined: 01 Oct 2013, 07:52
Contact:

Re: Applied keyboard detection reports error

21 Sep 2017, 18:48

You have to close InputHandler() here:

Code: Select all

;......................
     Else
	{
	KB = %GotInfo%
	KBID = %GotID%
	}
} ; << add closed bracket here!

RegisterRawInputDevices(usagePage, usage) {
    static RIDEV_INPUTSINK := 0x00000100
;......................
Also remove the spaces from these functions

Code: Select all

; wrong
;    vky := StrGet (vk)
;    scy := StrGet (sc)

; correct
    vky := StrGet(vk)
    scy := StrGet(sc)
They won't throw an error the way you have them now, but they won't work correctly.
MIRKOSOFT
Posts: 334
Joined: 23 Sep 2014, 14:29

Re: Applied keyboard detection reports error

22 Sep 2017, 21:34

Ok, I fixed it and tried to test few keys.
Code is here:

Code: Select all

#SingleInstance force

#NoEnv
SetBatchLines -1

OnMessage(0xFF, "InputHandler")
RegisterRawInputDevices(1, 6)
Esc::ExitApp

InputHandler(wParam, lParam) {
    static RID_INPUT        := 0x10000003
    static RIDI_DEVICENAME  := 0x20000007

    Critical

    DllCall("GetRawInputData"
        , "Ptr",    lParam
        , "UInt",   RID_INPUT
        , "Ptr",    0
        , "UIntP",  size
        , "UInt",   8 + A_PtrSize * 2)
    VarSetCapacity(buffer, size)
    DllCall("GetRawInputData"
        , "Ptr",    lParam
        , "UInt",   RID_INPUT
        , "Ptr",    &buffer
        , "UIntP",  size
        , "UInt",   8 + A_PtrSize * 2)

    devHandle := NumGet(buffer, 8)
    SetFormat, IntegerFast, hex
    vk := NumGet(buffer, 8 + 2 * A_PtrSize + 6, "UShort")
    sc := NumGet(buffer, 08+A_PtrSize*2, "UShort")
    flg := NumGet(buffer, 10+A_PtrSize*2, "UShort")
    vky := StrGet(vk)
    scy := StrGet(sc)
    SetFormat, Integer, d
    StringTrimLeft, vkx, vky, 2
    StringTrimLeft, scx, scy, 2
    if StrLen(scx) = 2
	{
	scx := "0" . scx
	}
    else if StrLen(scx) = 1
	{
	scx := "00" . scx
	}
    klaves := "vk" . vkx . "sc" . scx
    KeyLen := StrLen(klaves)

    DllCall("GetRawInputDeviceInfo"
        , "Ptr",    devHandle
        , "UInt",   RIDI_DEVICENAME
        , "Ptr",    0
        , "UIntP",  size)
    VarSetCapacity(info, size)
    DllCall("GetRawInputDeviceInfo"
        , "Ptr",    devHandle
        , "UInt",   RIDI_DEVICENAME
        , "Ptr",    &info
        , "UIntP",  size)
    GotInfo := StrGet(&info)
    StringMid, GotID, GotInfo, 13 , 3
    if GotID =1A2
	{
	KB =Inland
	}
     Else if GotID = 030
	{
	KB =Adesso
	}
     Else if GotID =05A
	{
	KB =Wireless
	}
     Else if GotID =04F
	{
	KB =Japanese
	}
     Else if GotID =13B
	{
	KB =Dell PS/2
	}
     Else if GotID =1C4
	{
	KB =Keypad
	}
     Else
	{
	KB = %GotInfo%
	KBID = %GotID%
	}

/*
klaves = vk00sc000
all letters are lower case
*/

MsgBox, 0, Pressed key, Scancode: %klaves%

    If klaves=vkc0sc029 			; ;
    {
	Send, {Raw}Key Degree
	return
    }
    else If klaves=vk31sc002		; 1
    {
	Send, {Raw}Key 1
	return
    }
}

RegisterRawInputDevices(usagePage, usage) {
    static RIDEV_INPUTSINK := 0x00000100
    VarSetCapacity(rawDevice, 8 + A_PtrSize)
    NumPut(usagePage,       rawDevice, 0, "UShort")
    NumPut(usage,           rawDevice, 2, "UShort")
    NumPut(RIDEV_INPUTSINK, rawDevice, 4, "UInt")
    NumPut(A_ScriptHWND,    rawDevice, 8, "UPtr")

    if !DllCall("RegisterRawInputDevices"
        , "Ptr",  &rawDevice
        , "UInt", 1
        , "UInt", 8 + A_PtrSize)
    {
        throw "Fail"
    }
}
You can see in code this part:

Code: Select all

MsgBox, 0, Pressed key, Scancode: %klaves%
This part has to show pressed key scancode created in code above that line.
But message is only

Code: Select all

__________________
| Pressed key    |
|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|
| Scancode: vksc |
|                |
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
No any scancode, any value... even when is focused Notepad window it shows no any message...

Where is problem?

Thank you for help.
Miro
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Applied keyboard detection reports error

23 Sep 2017, 03:07

TLM wrote:Also remove the spaces from these functions ...They won't throw an error the way you have them now, but they won't work correctly.
'Not working correctly' is the reason why the original script actually works.

Both lines can be removed after the following change:

Code: Select all

    StringTrimLeft, vkx, vk, 2
    StringTrimLeft, scx, sc, 2
MIRKOSOFT
Posts: 334
Joined: 23 Sep 2014, 14:29

Re: Applied keyboard detection reports error

23 Sep 2017, 08:32

I did these changes:

Restored lines

Code: Select all

    vky := StrGet(vk)
    scy := StrGet(sc)
back to

Code: Select all

    vky := StrGet (vk)
    scy := StrGet (sc)
and added test if is VK only one number value - if then it adds on first place of string 0

Code: Select all

    if StrLen(vkx) = 1
	{
	vkx := "0" . vkx
	}
It works now!

But one problem still remains - when is focused Notepad window no any message shows.
Whee is this last problem?

Thank you for help.
Miro
User avatar
TLM
Posts: 1608
Joined: 01 Oct 2013, 07:52
Contact:

Re: Applied keyboard detection reports error

23 Sep 2017, 09:17

just me wrote:
TLM wrote:Also remove the spaces from these functions ...They won't throw an error the way you have them now, but they won't work correctly.
'Not working correctly' is the reason why the original script actually works.
:lol: got ya wasn't aware it was broken on purpose lol

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: dipahk and 245 guests