TheGood wrote:
Hope this helps!
That helped tons. I knew I had seen a function reference before... somehow I lost track of where it was =)
Here's what I'm running now (I'd love to take your advice most fully, but I'm still feeling a bit limited by my lack of comfort in this scripting language so far... so I'm sticking with some of the easier methods I'm comfortable with at this point):
Code:
/*!
Generally, 0 = OFF and 1 = ON
VALUE WITH ALL SWITCHES IN 0 (OFF/DOWN) POSITION = 0x00002008 or 8200 in decimal
ENSURE THAT ALL SWITCHES ARE IN THE OFF/DOWN POSITION PRIOR TO STARTING THE SCRIPT!
KNOB0 (OFF) -8192 +FFFFE000 (from KNOB1)
KNOB1 (L) +8192 or -16384 +00002000 (from KNOB0) or +FFFFC000 (from KNOB2)
KNOB2 (R) +16384 or +32767 +00004000 (from KNOB1) or +00007FFF (from KNOB3)
KNOB3 (BOTH/ALL) -32767 or -1 +FFFF8001 (from KNOB2) or +FFFFFFFF (from KNOB4)
KNOB4 (START) +1 +00000001 (from KNOB3)
BAT0 -65536 +FFFF0000
BAT1 +65536 +00010000
ALT0 -131072 +FFFE0000
ALT1 +131072 +00020000
AVIONICS MASTER0 -262144 +FFFC0000
AVIONICS MASTER1 +262144 +00040000
FUEL PUMP0 -524288 +FFF80000
FUEL PUMP1 +524288 +00080000
DE-ICE0 -1048576 +FFF00000
DE-ICE1 +1048576 +00100000
PITOT HEAT0 -2097152 +FFE00000
PITOT HEAT1 +2097152 +00200000
COWL0 -4194304 +FFC00000
COWL1 +4194304 +00400000
PANEL0 -8388608 +FF800000
PANEL1 +8388608 +00800000
BEACON0 -256 +FFFFFF00
BEACON1 +256 +00000100
NAV0 -512 +FFFFFE00
NAV1 +512 +00000200
STROBE0 -1024 +FFFFFC00
STROBE1 +1024 +00000400
TAXI0 -2048 +FFFFF800
TAXI1 +2048 +00000800
LANDING0 -4096 +FFFFF000
LANDING1 +4096 +00001000
LANDING GEAR0 (DOWN) +4 +00000004
LANDING GEAR1 (UP) -4 +FFFFFFFC
*/
;Must be in auto-execute section if I want to use the constants
#Include %A_ScriptDir%\AHKHID.ahk
;Create GUI to receive messages
Gui, +LastFound
hGui := WinExist()
;Intercept WM_INPUT messages
WM_INPUT := 0xFF
OnMessage(WM_INPUT, "InputMsg")
;Initialize the default running value with all switches in 0 position (must be manually enforced on the hardware).
rValue := 8200
MsgBox rValue first is %rValue%.
;Register Saitek Switch Panel (along with other devices) with RIDEV_PAGEONLY and RIDEV_INPUTSINK (so that data is received even in the background)
HID_Register(1, 0, GuiHandle, RIDEV_PAGEONLY | RIDEV_INPUTSINK)
;exclude all extraneous devices listed from example 1 (joystick/mouse/keyboard etc)
HID_Register(1, 2, GuiHandle, RIDEV_EXCLUDE)
HID_Register(1, 4, GuiHandle, RIDEV_EXCLUDE)
HID_Register(1, 6, GuiHandle, RIDEV_EXCLUDE)
HID_Register(1, 7, GuiHandle, RIDEV_EXCLUDE)
;Prefix loop
Loop {
Sleep 1000
If WinActive("DCS: Black Shark")
sPrefix := "DCSBS"
Else sPrefix := "Default"
}
Return
InputMsg(wParam, lParam) {
Local devh, iKey, sLabel
Critical
;Get handle of device
devh := HID_GetInputInfo(lParam, II_DEVHANDLE)
;Check for error
If (devh <> -1) ;Check that it is my Saitek Pro Flight Switch Panel
And (HID_GetDevInfo(devh, DI_DEVTYPE, True) = RIM_TYPEHID)
And (HID_GetDevInfo(devh, DI_HID_VENDORID, True) = 1699)
And (HID_GetDevInfo(devh, DI_HID_PRODUCTID, True) = 3431)
And (HID_GetDevInfo(devh, DI_HID_VERSIONNUMBER, True) = 272) {
;Get data
iKey := HID_GetInputData(lParam, uData)
MsgBox rValue is %rValue%.
MsgBox iKey from HID_GetInputData is %iKey%.
;Check for error
If (iKey <> -1) {
;Get keycode (located at the 6th byte)
iKey := NumGet(uData, 0, "Int")
MsgBox iKey from NumGet is %iKey%.
iDiff := iKey - rValue ;Ascertain the the difference in the running value given by the last keystroke. This difference is unique for each button's position.
MsgBox iDiff is %iDiff%.
rValue := iKey ;replace the running value with the last value given by the device
MsgBox new rValue is %rValue%.
;Call the appropriate sub if it exists
sLabel := sPrefix "_" iDiff
MsgBox sLabel is %sLabel%.
If IsLabel(sLabel)
Gosub, %sLabel%
}
}
}
Default_-8192: ;KNOB0 from KNOB1
SendInput 1
Return
Default_8192: ;KNOB1 from KNOB0
SendInput 2
Return
Default_-16384: ;KNOB1 from KNOB2
SendInput 3
Return
Default_16384: ;KNOB2 from KNOB1
SendInput 4
Return
Default_32767: ;KNOB2 from KNOB3
SendInput 5
Return
Default_-32767: ;KNOB3 from KNOB2
SendInput 6
Return
Default_-1: ;KNOB3 from KNOB4
SendInput 7
Return
Default_1: ;KNOB4 from KNOB3
SendInput 8
Return
Default_-65536: ;BAT0
SendInput 9
Return
Default_65536: ;BAT1
SendInput 10
Return
Default_-131072: ;ALT0
SendInput 11
Return
Default_131072: ;ALT1
SendInput 12
Return
;etc...
The very first msgbox succeeds and spits out the simple rValue just below where I assigned it in the beginning. None of the other msgboxes pop up, though, so it's failing to get any input at that point.
And now here's what pops up in the AHK script window when I go to run this (partial capture in relevant area). I believe it's failing to register the devices in the first call to HID_Register =((( Not sure why this would work in example 2 but not here....
(I wrapped the following in code tags for lack of anything better-- obviously it's not actually code)
Code:
062: Gui,+LastFound
063: hGui := WinExist()
066: WM_INPUT := 0xFF
067: OnMessage(WM_INPUT, "InputMsg")
070: rValue := 8200
072: MsgBox,rValue first is %rValue%. (1.56)
075: HID_Register(1, 0, GuiHandle, RIDEV_PAGEONLY | RIDEV_INPUTSINK)
405: RIDEV_REMOVE := 0x00000001, RIDEV_EXCLUDE := 0x00000010
408: if Not (UsagePage || Usage || Handle || Flags)
423: VarSetCapacity(uDev, 12)
426: bNull := (Flags & RIDEV_REMOVE) || (Flags & RIDEV_EXCLUDE)
428: NumPut(UsagePage, uDev, 0, "UShort")
429: NumPut(Usage, uDev, 2, "UShort")
430: NumPut(Flags, uDev, 4)
431: NumPut(bNull ? 0 : Handle, uDev, 8)
434: r := DllCall("RegisterRawInputDevices", "UInt", &uDev, "UInt", 1, "UInt", 12)
437: if Not r
438: ErrorLevel = RegisterRawInputDevices call failed.
Return value: %r%
ErrorLevel: %ErrorLevel%
Line: %A_LineNumber%
Last Error: %A_LastError%
439: Return,-1
078: HID_Register(1, 2, GuiHandle, RIDEV_EXCLUDE)
405: RIDEV_REMOVE := 0x00000001, RIDEV_EXCLUDE := 0x00000010
408: if Not (UsagePage || Usage || Handle || Flags)
423: VarSetCapacity(uDev, 12)
426: bNull := (Flags & RIDEV_REMOVE) || (Flags & RIDEV_EXCLUDE)
428: NumPut(UsagePage, uDev, 0, "UShort")
429: NumPut(Usage, uDev, 2, "UShort")
430: NumPut(Flags, uDev, 4)
431: NumPut(bNull ? 0 : Handle, uDev, 8)
434: r := DllCall("RegisterRawInputDevices", "UInt", &uDev, "UInt", 1, "UInt", 12)
437: if Not r
441: }
443: Return,0
edit: I looked at the log a bit more and did a capture on the ErrorLevel and here's what I got (also I finally figured out how to use DebugView properly =)
[5912] ErrorLevel is RegisterRawInputDevices call failed.
[5912] Return value: 0
[5912] ErrorLevel: 0
[5912] Line: 438
[5912] Last Error: 87.
Not sure if that helps at all...
edit 2: On a hunch, I decided to test the code using decimal 288 value as the flags parameter for HID_Register. That didn't work. I also tried using the hex value 0x00000120. Then I tried removing RIDEV_INPUTSINK (since RIDEV_PAGEONLY is more important to get anything working) and indeed it did register correctly. Only downside is I could only see my debugs when the script window was in the foreground. I can use this to debug my logic for interpreting the keystrokes, but I'm still at a loss as to how I can use the RIDEV_INPUTSINK flag in conjunction. I tried using + instead of the | and that didn't help either. On a sidenote, the working registration with only RIDEV_PAGEONLY takes a good 15 seconds or so to happen. Not sure why that's so slow. Any ideas?