* Using Win32 Functions in Visual FoxPro * example=571 * Enumerating raw input devices attached to the system (keyboard, mouse, human interface device) LOCAL oDevices As RawInputDevices,; oDevice As RawInputDevice oDevices = CREATEOBJECT("RawInputDevices") CREATE CURSOR csInputDevices (; devhandle I, devtype C(5),; devdescr C(100), devname C(100)) FOR EACH oDevice IN oDevices WITH oDevice INSERT INTO csInputDevices (; devhandle, devtype,; devdescr, devname) VALUES (; .devicehandle,; .devicetypename,; .DeviceDescription(),; .devicename; ) ENDWITH NEXT GO TOP IN csInputDevices BROWSE NORMAL NOWAIT * end of main DEFINE CLASS RawInputDevices As Collection #DEFINE RIDI_DEVICENAME 0x20000007 #DEFINE RIDI_DEVICEINFO 0x2000000b #DEFINE RIM_TYPEMOUSE 0 #DEFINE RIM_TYPEKEYBOARD 1 #DEFINE RIM_TYPEHID 2 #DEFINE RAWINPUTDEVICELIST_SIZE 8 PROCEDURE Init WITH THIS .declare .EnumDevices ENDWITH PROCEDURE EnumDevices DO WHILE THIS.Count > 0 THIS.Remove(1) ENDDO LOCAL cBuffer, nDeviceCount, nDeviceIndex,; hDevice, nDeviceType, oDevice As RawInputDevice nDeviceCount=0 = GetRawInputDeviceList(NULL, @nDeviceCount,; RAWINPUTDEVICELIST_SIZE) cBuffer = REPLICATE(CHR(0),; RAWINPUTDEVICELIST_SIZE * nDeviceCount) = GetRawInputDeviceList(@cBuffer, @nDeviceCount,; RAWINPUTDEVICELIST_SIZE) FOR nDeviceIndex=0 TO nDeviceCount-1 hDevice = buf2dword(SUBSTR(m.cBuffer,; nDeviceIndex*RAWINPUTDEVICELIST_SIZE+1,4)) nDeviceType = buf2dword(SUBSTR(m.cBuffer,; nDeviceIndex*RAWINPUTDEVICELIST_SIZE+5,4)) DO CASE CASE nDeviceType = RIM_TYPEMOUSE oDevice = CREATEOBJECT("MouseDevice", m.hDevice) CASE nDeviceType = RIM_TYPEKEYBOARD oDevice = CREATEOBJECT("KeyboardDevice", m.hDevice) CASE nDeviceType = RIM_TYPEHID oDevice = CREATEOBJECT("HIDDevice", m.hDevice) OTHERWISE LOOP ENDCASE THIS.Add( m.oDevice ) oDevice=NULL NEXT PROCEDURE declare DECLARE INTEGER GetRawInputDeviceList IN user32; STRING @pRawInputDeviceList, LONG @puiNumDevices,; LONG cbSize DECLARE INTEGER GetRawInputDeviceInfo IN user32; INTEGER hDevice, LONG uiCommand,; STRING @pData, LONG @pcbSize ENDDEFINE DEFINE CLASS RawInputDevice As Relation devicehandle=0 devicename="" devicetype=-1 deviceinfo="" devicetypename="undefined" PROCEDURE Init(hDevice As Number) LOCAL nBufsize, cBuffer, nDeviceType WITH THIS .devicehandle = m.hDevice .devicetype = nDeviceType * retrieving device name nBufsize=0 = GetRawInputDeviceInfo(.devicehandle,; RIDI_DEVICENAME, NULL, @nBufsize) cBuffer = REPLICATE(CHR(0), m.nBufsize) = GetRawInputDeviceInfo(.devicehandle,; RIDI_DEVICENAME, @cBuffer, @nBufsize) .devicename = ALLTRIM(STRTRAN(m.cBuffer, CHR(0), "")) * retrieving device info nBufsize=0 = GetRawInputDeviceInfo(.devicehandle,; RIDI_DEVICEINFO, NULL, @nBufsize) cBuffer = REPLICATE(CHR(0), m.nBufsize) = GetRawInputDeviceInfo(.devicehandle,; RIDI_DEVICEINFO, @cBuffer, @nBufsize) .deviceinfo = m.cBuffer .devicetype = buf2dword(SUBSTR(m.cBuffer,5,4)) ENDWITH FUNCTION DeviceDescription() As String RETURN "" &&THIS.devicetypename + " : " ENDDEFINE DEFINE CLASS MouseDevice As RawInputDevice devicetypename="MOUSE" * RID_DEVICE_INFO_MOUSE Structure Mse_Id=0 Mse_ButtonCount=0 Mse_SampleRate=0 Mse_HasHorizontalWheel=0 PROCEDURE Init(hDevice As Number) RawInputDevice::Init( m.hDevice) WITH THIS .Mse_Id = buf2dword(SUBSTR(.deviceinfo,9,4)) .Mse_ButtonCount = buf2dword(SUBSTR(.deviceinfo,13,4)) .Mse_SampleRate = buf2dword(SUBSTR(.deviceinfo,17,4)) .Mse_HasHorizontalWheel = buf2dword(SUBSTR(.deviceinfo,21,4)) ENDWITH FUNCTION DeviceDescription() As String LOCAL cDescription WITH THIS cDescription =; "Id=" + TRANSFORM(.Mse_Id) + ", " +; "Buttons=" + TRANSFORM(.Mse_ButtonCount) + ", " +; "Smp.Rate=" + TRANSFORM(.Mse_SampleRate) + ", " +; "Hor.Wheel=" + TRANSFORM(.Mse_HasHorizontalWheel) ENDWITH RETURN RawInputDevice::DeviceDescription() + m.cDescription ENDDEFINE DEFINE CLASS KeyboardDevice As RawInputDevice devicetypename="KBD" * RID_DEVICE_INFO_KEYBOARD Structure Kbd_Type=0 Kbd_SubType=0 Kbd_Mode=0 Kbd_FunctionKeyCount=0 Kbd_IndicatorCount=0 Kbd_KeyCount=0 PROCEDURE Init(hDevice As Number) RawInputDevice::Init( m.hDevice ) WITH THIS .Kbd_Type = buf2dword(SUBSTR(.deviceinfo,9,4)) .Kbd_SubType = buf2dword(SUBSTR(.deviceinfo,13,4)) .Kbd_Mode = buf2dword(SUBSTR(.deviceinfo,17,4)) .Kbd_FunctionKeyCount = buf2dword(SUBSTR(.deviceinfo,21,4)) .Kbd_IndicatorCount = buf2dword(SUBSTR(.deviceinfo,25,4)) .Kbd_KeyCount = buf2dword(SUBSTR(.deviceinfo,29,4)) ENDWITH FUNCTION DeviceDescription() As String LOCAL cDescription WITH THIS cDescription =; "Type=" + TRANSFORM(.Kbd_Type) + ", " +; "Subtype=" + TRANSFORM(.Kbd_SubType) + ", " +; "Mode=" + TRANSFORM(.Kbd_Mode) + ", " +; "Fn.Keys=" + TRANSFORM(.Kbd_FunctionKeyCount) + ", " +; "Indic.=" + TRANSFORM(.Kbd_IndicatorCount) + ", " +; "Keys=" + TRANSFORM(.Kbd_KeyCount) ENDWITH RETURN RawInputDevice::DeviceDescription() + m.cDescription ENDDEFINE DEFINE CLASS HIDDevice As RawInputDevice devicetypename="HID" * RID_DEVICE_INFO_HID Structure Hid_VendorId=0 Hid_ProductId=0 Hid_VersionNumber=0 Hid_UsagePage=0 Hid_Usage=0 PROCEDURE Init(hDevice As Number) RawInputDevice::Init( m.hDevice ) WITH THIS .Hid_VendorId = buf2dword(SUBSTR(.deviceinfo,9,4)) .Hid_ProductId = buf2dword(SUBSTR(.deviceinfo,13,4)) .Hid_VersionNumber = buf2dword(SUBSTR(.deviceinfo,17,4)) .Hid_UsagePage = buf2word(SUBSTR(.deviceinfo,21,2)) .Hid_Usage = buf2word(SUBSTR(.deviceinfo,23,2)) ENDWITH FUNCTION DeviceDescription() As String LOCAL cDescription WITH THIS cDescription =; "Vendor=" + TRANSFORM(.Hid_VendorId) + ", " +; "Product=" + TRANSFORM(.Hid_ProductId) + ", " +; "Version=" + TRANSFORM(.Hid_VersionNumber) + ", " +; "Usage Page=" + TRANSFORM(.Hid_UsagePage) + ", " +; "Usage=" + TRANSFORM(.Hid_Usage) ENDWITH RETURN RawInputDevice::DeviceDescription() + m.cDescription ENDDEFINE FUNCTION buf2dword(cBuffer) RETURN Asc(SUBSTR(cBuffer, 1,1)) + ; BitLShift(Asc(SUBSTR(cBuffer, 2,1)), 8) +; BitLShift(Asc(SUBSTR(cBuffer, 3,1)), 16) +; BitLShift(Asc(SUBSTR(cBuffer, 4,1)), 24) FUNCTION buf2word(lcBuffer) RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ; Asc(SUBSTR(lcBuffer, 2,1)) * 256