PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2 3 ... 10
 1 
 on: Today at 01:07:13 PM 
Started by Petrus Vorster - Last post by Petrus Vorster
Hi Ray

Luckily i am not the thread leader over there. Its people all over the planet that is participating.
I was curious over the controls, but it seems the Aussie bloke is far ahead of us and has working models already.
still is very interesting how to control all this external equipment.

-regards Peter

 2 
 on: Today at 06:57:38 AM 
Started by raymw - Last post by raymw
Thanks Pierre, for taking an interest. I'll pick over what you have written, see if I can get it to something like it in freebasic. I really appreciate your help.
Best wishes,

Ray

 3 
 on: Today at 12:31:22 AM 
Started by raymw - Last post by Pierre Bellisle
Part two
Code: [Select]
FUNCTION GetDeviceInfo(Device AS STRING) AS LONG
 LOCAL zClassName     AS ASCIIZ * %MAX_CLASS_NAME_LEN '=128
 LOCAL DeviceInfoData AS SP_DEVINFO_DATA
 LOCAL hDeviceInfoSet AS DWORD
 LOCAL RequiredSize   AS DWORD
 LOCAL DevCount       AS LONG
 LOCAL Retval         AS LONG

 zClassName = Device
 DevCount   = 0

 'The SetupDiClassGuidsFromName function retrieves the GUID(s) associated with the specified class name.
 'This list is built based on the classes currently installed on the system.
 Retval = SetupDiClassGuidsFromName(zClassName, BYVAL 0, BYVAL 0, RequiredSize) 'Ask for array size
 TextAdd(hEdit, "SetupDi devices" & $TAB) 'DeviceCount

 REDIM GuidArray(1 TO RequiredSize) AS GUIDAPI
 Retval = SetupDiClassGuidsFromName(zClassName, GuidArray(1), _ 'Ask for GUID associated with the class name
                                    SIZEOF(GUIDAPI) * RequiredSize, RequiredSize)

 'SetupDiGetClassDevs retrieves a device information set that contains all devices of a specified class.
 'Get info by ClassGUID, like GUID$("{4D36E978E325-11CE-BFC1-08002BE10318})" for "Ports"
 hDeviceInfoSet = SetupDiGetClassDevs(GuidArray(1), BYVAL %NULL, BYVAL %NULL, %DIGCF_PRESENT)
 IF hDeviceInfoSet <> %INVALID_HANDLE_VALUE THEN
   DeviceInfoData.cbSize = SIZEOF(DeviceInfoData)
   DO 'Loop to get all devices of a class
     'Get a device based on DevCount, exit if no more
     IF SetupDiEnumDeviceInfo(hDeviceInfoSet, DevCount, DeviceInfoData) THEN 'Return True if success
       TextAdd(hEdit, $Line)
       TextAdd(hEdit, "Device no.: " & $TAB & FORMAT$(DevCount))
       TextAdd(hEdit, "ClassName: " & zClassName)
       TextAdd(hEdit, "GUID: " & GUIDTXT$(GuidArray(1)))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_FRIENDLYNAME, "FriendlyName: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_DEVICEDESC, "Desc: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_DRIVER, "Driver: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_HARDWAREID, "HardId: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_ENUMERATOR_NAME, "Enum: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_MFG, "MFG: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_SERVICE, "Servcice: "))
       TextAdd(hEdit, SetupDiGetDeviceRegistryPropertyCall(hDeviceInfoSet, DeviceInfoData, %SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, "PhyObj: "))
     ELSE
       EXIT DO
     END IF
     INCR DevCount
   LOOP
   SetupDiDestroyDeviceInfoList(hDeviceInfoSet) ': hDeviceInfoSet = 0
 END IF

 TextAdd(hEdit, $Line)

END FUNCTION
'______________________________________________________________________________

CALLBACK FUNCTION DlgProc
 LOCAL  CurPos            AS POINTAPI
 LOCAL  index             AS LONG
 LOCAL  RidDeviceInfo     AS RID_DEVICE_INFO
 LOCAL  RawInputDevCount  AS LONG
 LOCAL  MouseCount        AS LONG
 LOCAL  DataSize          AS LONG
 LOCAL  ByteCount         AS LONG
 LOCAL  RidDeviceInfoSize AS DWORD 'RID_DEVICE_INFO

 SELECT CASE CBMSG

   CASE %WM_INITDIALOG
     'Edit -------------------------------------------------------------------
     hEdit = GetDlgItem(CBHNDL, %Edit)
     SendMessage(hEdit, %EM_LIMITTEXT, 0, 0)
     PostMessage(hEdit, %EM_SETSEL, -1, -1)
     PostMessage(CBHNDL, %WM_APP, 0, 0)

   CASE %WM_APP

     'SetupDi ----------------------------------------------------------------
     GetDeviceInfo("Mouse")

     'Raw --------------------------------------------------------------------
     GetRawInputDeviceList(BYVAL %NULL, RawInputDevCount, SIZEOF(RAWINPUTDEVICELIST))         'Get hid count
     DIM RawInputDevList(0 TO RawInputDevCount - 1) AS RAWINPUTDEVICELIST                     'Prepare hid array
     GetRawInputDeviceList(RawInputDevList(0), RawInputDevCount, SIZEOF(RAWINPUTDEVICELIST))  'Get array
     TextAdd(hEdit, "All RawInputDevCount" & $TAB & STR$(RawInputDevCount))
     TextAdd(hEdit, $Line)
     DIM RawInputDev(0 TO RawInputDevCount) AS RAWINPUTDEVICE                                      'Prepare hid register array
     TextAdd(hEdit, "RawInputDevice Mouse" & $TAB)
     TextAdd(hEdit, $Line)
     RidDeviceInfoSize = SIZEOF(RID_DEVICE_INFO)
     FOR index = 0 TO RawInputDevCount - 1                                                  'Loop
       GetRawInputDeviceInfo(RawInputDevList(index).hDevice, %RIDI_DEVICEINFO, RidDeviceInfo, SIZEOF(RID_DEVICE_INFO)) 'Get hid info
       SELECT CASE RidDeviceInfo.dwtype                                                  'Poll hid type
         CASE %RIM_TYPEMOUSE                                                             'Mouse
           LOCAL zDeviceName AS ASCIIZ * 128
           GetRawInputDeviceInfo(RawInputDevList(index).hDevice, %RIDI_DEVICENAME, BYVAL VARPTR(zDeviceName), SIZEOF(zDeviceName))
           GetRawInputDeviceInfo(RawInputDevList(index).hDevice, %RIDI_DEVICEINFO, RidDeviceInfo, RidDeviceInfoSize)
           TextAdd(hEdit, "DeviceName: " & $TAB & zDeviceName)
           TextAdd(hEdit, "Type: "       & $TAB & "Mouse")
           TextAdd(hEdit, "index: "      & $TAB & STR$(MouseCount))
           TextAdd(hEdit, "hDevice: "    & $TAB & HEX$(RawInputDevList(index).hDevice))
           TextAdd(hEdit, "Moude id:"    & $TAB & STR$(RidDeviceInfo.mouse.dwId))
           TextAdd(hEdit, "Button count:" & $TAB & STR$(RidDeviceInfo.mouse.dwNumberOfButtons))
           TextAdd(hEdit, "Sample rate data points per second:" & $TAB & STR$(RidDeviceInfo.mouse.dwSampleRate))
           TextAdd(hEdit, "Horizontal wheel scrolling:"         & $TAB & STR$(RidDeviceInfo.mouse.fHasHorizontalWheel))

           DataSize = GetRawInputDeviceInfo(RawInputDevList(index).hDevice, %RIDI_PREPARSEDDATA, BYVAL %NULL, VARPTR(DataSize))
           TextAdd(hEdit, "Preparsed data byte count  " & $TAB & STR$(DataSize))

           '    1 - generic desktop controls // we use this
           '    2 - simulation controls
           '    3 - vr
           '    4 - sport
           '    5 - game
           '    6 - generic device
           '    7 - keyboard
           '    8 - LEDs
           '    9 - button
           RawInputDev(MouseCount).usUsagePage = 1

           'usUsage values when usUsagePage is 1:
           '    0 - undefined
           '    1 - pointer
           '    2 - mouse
           '    3 - reserved
           '    4 - joystick
           '    5 - game pad
           '    6 - keyboard // we use this
           '    7 - keypad
           '    8 - multi-axis controller
           '    9 - Tablet PC controls
           RawInputDev(MouseCount).usUsage     = 2

           RawInputDev(MouseCount).dwFlags     = %RIDEV_EXINPUTSINK 'Always capture nofreezw
           'RawInputDev(MouseCount).dwFlags    = %RIDEV_NOLEGACY 'Add mouse and ignores legacy mouse messages freeze
           'RawInputDev(MouseCount).dwFlags    = %RIDEV_CAPTUREMOUSE 'nofreeze
           RawInputDev(MouseCount).hwndTarget  = hDlg

           TextAdd(hEdit, $Line)
           INCR MouseCount

         CASE %RIM_TYPEKEYBOARD 'Keyboard, the presenter shows up as a keyboard too

         CASE %RIM_TYPEHID 'Other devices                                                               'Other raw input device, game controllers, joysticks, etc.

       END SELECT
     NEXT

     TextAdd(hEdit, $Line)
     RegisterRawInputDevices(RawInputDev(0), MouseCount, SIZEOF(RAWINPUTDEVICE)) 'Register hids

   CASE %WM_INPUT 'Sent to the window that is getting raw input. By default, no application receives raw input.
                  'The first step is therefore to register the input devices that will be providing the
                  'desired raw data, and associate them with the window that will be handling this data.
                  'wParam = The input code. This parameter can be one of the following values.
                  '         RIM_INPUT     0 Input occurred while the application was in the foreground.
                  '                       The application must call DefWindowProc so the system can perform cleanup.
                  '         RIM_INPUTSINK 1 Input occurred while the application was not in the foreground.
                  '                       The application must call DefWindowProc so the system can perform the cleanup.
                  'lParam   A handle to the RAWINPUT for GetRawInputData that contains the raw input from the device.

     STATIC zRawInput  AS STRING * 4096 'Faster than building a ~40 bytes string every time
     LOCAL  pRawInput  AS RAWINPUT POINTER
     LOCAL  ByteCountF AS LONG
     pRawInput  = VARPTR(zRawInput)
     ByteCount  = LEN(zRawInput)
     ByteCountF = GetRawInputData(CBLPARAM, %RID_INPUT, BYVAL pRawInput, ByteCount, SIZEOF(RAWINPUTHEADER))'Get hid input
     IF @pRawInput.data.mouse.usButtonFlags THEN
       TextAdd(hEdit, "RawInput.Header.hDevice = "                & HEX$(@pRawInput.header.hDevice, 8))
       TextAdd(hEdit, "RawInput.Header.dwType = "                 & CHOOSE$(@pRawInput.header.dwType + 1, _  '0 for mouse, 1 key, 2 hid
                                                                            "RIM_TYPEMOUSE", "RIM_TYPEKEYBOARD", "RIM_TYPEHID")) '0 for mouse, 1 key, 2 hid
       TextAdd(hEdit, "RawInput.Header.wParam = "                 & HEX$(@pRawInput.header.wParam, 8)) 'The value passed in the wParam parameter of the WM_INPUT message.
       TextAdd(hEdit, "RawInput.data.mouse.usFlags = "            & MouseStateGet(@pRawInput.data.mouse.usFlags)) '
       TextAdd(hEdit, "RawInput.data.mouse.usButtonFlags = "      & MouseTransitionStateGet(@pRawInput.data.mouse.usButtonFlags)) '
       TextAdd(hEdit, "RawInput.data.mouse.usButtonData = "       & HEX$(@pRawInput.data.mouse.usButtonData, 4)) '
       TextAdd(hEdit, "RawInput.data.mouse.ulRawButtons = "       & FORMAT$(@pRawInput.data.mouse.ulRawButtons)) 'Reserved
       TextAdd(hEdit, "RawInput.data.mouse.lLastX = "             & FORMAT$(@pRawInput.data.mouse.lLastX)) 'The motion in the X direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
       TextAdd(hEdit, "RawInput.data.mouse.lLastY = "             & FORMAT$(@pRawInput.data.mouse.lLastY)) 'The motion in the Y direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
       TextAdd(hEdit, "RawInput.data.mouse.ulExtraInformation = " & HEX$(@pRawInput.data.mouse.ulExtraInformation)) '
       GetCursorPos(CurPos)
       TextAdd(hEdit, "Cursor: " & FORMAT$(CurPos.x) & " x "      & FORMAT$(CurPos.x))
       TextAdd(hEdit, $Line)
     END IF

     DefWindowProc(hDlg, CBMSG, CBWPARAM, CBLPARAM)
     FUNCTION = 0 : EXIT FUNCTION

   CASE %WM_INPUT_DEVICE_CHANGE 'RIDEV_DEVNOTIFY Sent to the window that registered to receive raw input.
     'wParam This parameter can be one of the following values.
     '  GIDC_ARRIVAL 1 A new device has been added to the system.
     '  GIDC_REMOVAL 2 A device has been removed from the system.
     'lParam The handle to the raw input device. Call GetRawInputDeviceInfo to get more information regarding the device.

   CASE %WM_COMMAND
     SELECT CASE LOWRD(CBWPARAM)
       CASE %ButtonAdd
         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
         END IF

       CASE %ButtonDel
         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
           TextDel(hEdit)
         END IF

       CASE %IDCANCEL, %IDOK
         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
           DIALOG END CBHNDL, 0
         END IF
     END SELECT

   CASE %WM_SETCURSOR
     'hwnd = (HWND) wParam;       // handle of window with cursor
     'nHittest = LOWORD(lParam);  // hit-test code
     'wMouseMsg = HIWORD(lParam); // mouse-message identifier
      GetCursorPos(CurPos)
      CONTROL SET TEXT hDlg, %StaticCurPos, FORMAT$(CurPos.x) & " x " & FORMAT$(Curpos.y)

   CASE %WM_SIZE 'Dialog size have changed
     'CBWPARAM = Resizing requested: SIZE_MAXHIDE SIZE_MAXIMIZED SIZE_MAXSHOW SIZE_MINIMIZED SIZE_RESTORED
     'LO(WORD, CBLPARAM) is client area width  in pixels.
     'HI(WORD, CBLPARAM) is client area height in pixels.
     LOCAL ClientSizeX AS LONG
     LOCAL ClientSizeY AS LONG
     IF CBWPARAM <> %SIZE_MINIMIZED THEN
       ClientSizeX = LO(WORD, CBLPARAM)
       ClientSizeY = HI(WORD, CBLPARAM)
       MoveWindow(hEdit, 3, 3, ClientSizeX - 8, ClientSizeY - 40 - 00, %TRUE)
       MoveWindow(GetDlgItem(hDlg, %ButtonAdd), 10, ClientSizeY - 30, 180, 25, %TRUE)
       MoveWindow(GetDlgItem(hDlg, %ButtonDel), 200, ClientSizeY - 30, 80, 25, %TRUE)
       MoveWindow(GetDlgItem(hDlg, %StaticCurPos), 320, ClientSizeY - 25, 80, 25, %TRUE)
     END IF

 END SELECT
END FUNCTION
'______________________________________________________________________________

FUNCTION PBMAIN
 LOCAL hIcon  AS DWORD

 DIALOG NEW %HWND_DESKTOP, $AppNmae, , , 450, 600, _
 %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_SYSMENU OR %WS_THICKFRAME, 0 TO hDlg
 hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294)
 SetClassLong(hDlg, %GCL_HICON,hIcon)

 CONTROL ADD TEXTBOX, hDlg, %Edit, "", 2, 2, 196, 96, %WS_CHILD OR %WS_VISIBLE OR _
 %WS_TABSTOP OR %WS_HSCROLL OR %WS_VSCROLL OR %ES_LEFT OR %ES_MULTILINE OR _
 %ES_NOHIDESEL OR %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR %ES_WANTRETURN, _
 %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR

 CONTROL ADD BUTTON, hDlg, %ButtonAdd, "&Add string at the end and scrool", 10, 86, 130, 15

 CONTROL ADD BUTTON, hDlg, %ButtonDel, "&Delete text", 150, 86, 55, 15

 CONTROL ADD LABEL, hDlg, %StaticCurPos, "CurPos", 230, 86, 55, 15

 DIALOG SHOW MODAL hDlg CALL DlgProc
 DestroyIcon(hIcon)

END FUNCTION
'______________________________________________________________________________
'

 4 
 on: Today at 12:30:44 AM 
Started by raymw - Last post by Pierre Bellisle
From the code, I see that EitherMouse use RawInput functions.

From program I had, Id did a quick test code under PowerBASIC using Josť's API.
I use some SetupDi functions to get connected mice info.
This is done via GetDeviceInfo("Mouse") function.

Compare HardId to MID$(DeviceName, 5, LEN(HardId)) (Convert # to _) to get the corresponding RawDevice if needed.

Then I call some RawInput functions to get mouse's stuff.
I'm sure you'll get the idea.
Code work mainly on mouse click.

I do not have time for now to translate to FB, plus, a lot of cleanup is needed but maybe in a week or so, maybe...

Code: [Select]
#COMPILE EXE
#DIM ALL
#REGISTER NONE
#INCLUDE "Win32Api.Inc"
#INCLUDE "WinUser.inc"
#INCLUDE "SetupAPI.inc"

%MAX_CLASS_NAME_LEN = 128

GLOBAL hDlg  AS DWORD
GLOBAL hEdit AS DWORD

$AppNmae      = "Mice"
%Edit         = 101
%ButtonAdd    = 201
%ButtonDel    = 202
%StaticCurPos = 301
$Line         = STRING$(75, 45)
'______________________________________________________________________________

SUB TextDel(BYVAL hEdit AS DWORD)

 'Erase all, Microsoft recommended way
  SendMessage(hEdit, %WM_SETTEXT, 0, BYVAL 0)

END SUB
'_____________________________________________________________________________

SUB TextAdd(BYVAL hEdit AS DWORD, BYVAL sText AS STRING)

 'Move the caret to the end of text.
 SendMessage(hEdit, %EM_SETSEL, -1, -1)

 sText = sText & $CRLF 'Add a CRLF if needed

 'Insert the string at caret position.
 SendMessage(hEdit, %EM_REPLACESEL, %TRUE, BYVAL STRPTR(sText))

END SUB
'_____________________________________________________________________________

FUNCTION MouseStateGet(usFlags AS WORD) AS STRING
 LOCAL sState AS STRING

 'usFlags Type: USHORT The mouse state. This member can be any reasonable combination of the following.
 IF (usFlags AND %MOUSE_MOVE_ABSOLUTE)      THEN
   sState &= "MOUSE_MOVE_ABSOLUTE, "      '1  Mouse movement data is based on absolute position.
 ELSE
   sState  = "MOUSE_MOVE_RELATIVE, "      '0    Mouse movement data is relative to the last mouse position.
 END IF
 IF (usFlags AND %MOUSE_VIRTUAL_DESKTOP)    THEN sState &= "MOUSE_VIRTUAL_DESKTOP, "    '0x02 Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system).
 IF (usFlags AND %MOUSE_ATTRIBUTES_CHANGED) THEN sState &= "MOUSE_ATTRIBUTES_CHANGED, " '0x04 Mouse attributes changed; application needs to query the mouse attributes.
 FUNCTION = LEFT$(sState, -2) & " (0x" & HEX$(usFlags, 4) & ")"

END FUNCTION
'______________________________________________________________________________

FUNCTION MouseTransitionStateGet(usButtonFlags AS WORD) AS STRING
 LOCAL sState AS STRING

 'usButtonFlags The transition state of the mouse buttons. This member can be one or more of the following values.
 'The transition state of the mouse buttons. This member can be one or more of the following values.
 IF (usButtonFlags AND %RI_MOUSE_LEFT_BUTTON_DOWN)   THEN sState  = "RI_MOUSE_LEFT_BUTTON_DOWN, "   '0x0001 Left button changed to down.
 IF (usButtonFlags AND %RI_MOUSE_LEFT_BUTTON_UP)     THEN sState &= "RI_MOUSE_LEFT_BUTTON_UP, "     '0x0002 Left button changed to up.
 IF (usButtonFlags AND %RI_MOUSE_MIDDLE_BUTTON_DOWN) THEN sState &= "RI_MOUSE_MIDDLE_BUTTON_DOWN, " '0x0010 Middle button changed to down.
 IF (usButtonFlags AND %RI_MOUSE_MIDDLE_BUTTON_UP)   THEN sState &= "RI_MOUSE_MIDDLE_BUTTON_UP, "   '0x0020 Middle button changed to up.
 IF (usButtonFlags AND %RI_MOUSE_RIGHT_BUTTON_DOWN)  THEN sState &= "RI_MOUSE_RIGHT_BUTTON_DOWN, "  '0x0004 Right button changed to down.
 IF (usButtonFlags AND %RI_MOUSE_RIGHT_BUTTON_UP)    THEN sState &= "RI_MOUSE_RIGHT_BUTTON_UP, "    '0x0008 Right button changed to up.
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_1_DOWN)      THEN sState &= "RI_MOUSE_BUTTON_1_DOWN, "      '0x0001 RI_MOUSE_LEFT_BUTTON_DOWN
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_1_UP)        THEN sState &= "RI_MOUSE_BUTTON_1_UP, "        '0x0002 RI_MOUSE_LEFT_BUTTON_UP
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_2_DOWN)      THEN sState &= "RI_MOUSE_BUTTON_2_DOWN, "      '0x0004 RI_MOUSE_RIGHT_BUTTON_DOWN
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_2_UP)        THEN sState &= "RI_MOUSE_BUTTON_2_UP, "        '0x0008 RI_MOUSE_RIGHT_BUTTON_UP
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_3_DOWN)      THEN sState &= "RI_MOUSE_BUTTON_3_DOWN, "      '0x0010 RI_MOUSE_MIDDLE_BUTTON_DOWN
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_3_UP)        THEN sState &= "RI_MOUSE_BUTTON_3_UP, "        '0x0020 RI_MOUSE_MIDDLE_BUTTON_UP
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_4_DOWN)      THEN sState &= "RI_MOUSE_BUTTON_4_DOWN, "      '0x0040 XBUTTON1 changed to down.
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_4_UP)        THEN sState &= "RI_MOUSE_BUTTON_4_UP, "        '0x0080 XBUTTON1 changed to up.
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_5_DOWN)      THEN sState &= "RI_MOUSE_BUTTON_5_DOWN, "      '0x100  XBUTTON2 changed to down.
 IF (usButtonFlags AND %RI_MOUSE_BUTTON_5_UP)        THEN sState &= "RI_MOUSE_BUTTON_5_UP, "        '0x0200 XBUTTON2 changed to up.
 IF (usButtonFlags AND %RI_MOUSE_WHEEL)              THEN sState &= "RI_MOUSE_WHEEL, "              '0x0400 Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData.
 FUNCTION = LEFT$(sState, -2) & " (0x" & HEX$(usButtonFlags, 4) & ")"

END FUNCTION
'______________________________________________________________________________

FUNCTION WinErrMsg2(BYVAL ErrNum AS DWORD)AS STRING
 LOCAL hLib      AS DWORD
 LOCAL errorFlag AS DWORD
 LOCAL os        AS OSVERSIONINFO
 LOCAL zError    AS ASCIIZ * 1024

 'Load error message module if available & necessary
 SELECT CASE AS LONG ErrNum

   CASE 2100 TO 2999 'NT, Network, thank Greg Turgeon
   'CASE %NETWORK_ERROR_FIRST TO %NETWORK_ERROR_LAST
     os.dwOSVersionInfoSize = SIZEOF(os)
     GetVersionEx os
     IF os.dwPlatformId = %VER_PLATFORM_WIN32_NT THEN _
       hLib = LoadLibraryEx("NETMSG.DLL", BYVAL 0, %LOAD_LIBRARY_AS_DATAFILE)

   CASE 12000 TO 12171 'Internet
   'CASE %INTERNET_ERROR_FIRST TO %NTERNET_ERROR_LAST
     hLib = LoadLibraryEx("WININET.DLL", BYVAL 0, %LOAD_LIBRARY_AS_DATAFILE)

 END SELECT

 errorFlag = %FORMAT_MESSAGE_FROM_SYSTEM OR %FORMAT_MESSAGE_IGNORE_INSERTS OR _
             %FORMAT_MESSAGE_MAX_WIDTH_MASK
 IF hLib THEN errorFlag = errorFlag OR %FORMAT_MESSAGE_FROM_HMODULE

 IF FormatMessage(errorFlag, BYVAL hLib, ErrNum, MakeLangID(%LANG_NEUTRAL, %SUBLANG_DEFAULT), _
                  zError, SIZEOF(zError), BYVAL 0) THEN
   FUNCTION = "Error" & STR$(ErrNum) & ":" & $SPC & zError
 ELSE
   'IF Unknown THEN
     FUNCTION = "Error" & STR$(ErrNum) & ", unknown."
   'END IF
 END IF
 IF hLib THEN FreeLibrary hLib

END FUNCTION
'______________________________________________________________________________

FUNCTION SetupDiGetDeviceRegistryPropertyCall(BYVAL hDeviceInfoSet AS DWORD, DeviceInfoData AS SP_DEVINFO_DATA, BYVAL PropertyVal AS DWORD, BYVAL sDef AS STRING) AS STRING
 LOCAL zPropertyBuffer     AS ASCIIZ * 2048
 LOCAL pz                  AS ASCIIZ POINTER
 LOCAL sBuf                AS STRING
 LOCAL RequiredSize        AS DWORD
 LOCAL PropertyRegDataType AS DWORD
 LOCAL index               AS LONG
 LOCAL LastError           AS LONG

 DeviceInfoData.cbSize       = SIZEOF(SP_DEVINFO_DATA)
 IF SetupDiGetDeviceRegistryProperty(hDeviceInfoSet, _       'Return True if success
                                     DeviceInfoData, _       'SP_DEVINFO_DATA var
                                     PropertyVal, _          'Aka SPDRP_BUSNUMBER, %SPDRP_FRIENDLYNAME
                                     PropertyRegDataType, _  'Reg type of data received
                                     zPropertyBuffer, _      'Data received
                                     SIZEOF(zPropertyBuffer), _
                                     RequiredSize) THEN      'Required size for the PropertyBuffer buffer

   'REG_NONE                        =  0   No value type
   'REG_SZ                          =  1   Unicode nul terminated string
   'REG_EXPAND_SZ                   =  2   Unicode nul terminated string
   'REG_BINARY                      =  3   Free form binary
   'REG_DWORD                       =  4   32-bit number
   'REG_DWORD_LITTLE_ENDIAN         =  4   32-bit number (same as MACRO REG_DWORD)
   'REG_DWORD_BIG_ENDIAN            =  5   32-bit number
   'REG_LINK                        =  6   Symbolic Link (unicode)
   'REG_MULTI_SZ                    =  7   Multiple Unicode strings
   'REG_RESOURCE_LIST               =  8   Resource list in the resource map
   'REG_FULL_RESOURCE_DESCRIPTOR    =  9   Resource list in the hardware description
   'REG_RESOURCE_REQUIREMENTS_LIST  = 10
   'REG_QWORD                       = 11   64-bit number
   'REG_QWORD_LITTLE_ENDIAN         = 11   64-bit number (same as MACRO REG_QWORD)

   SELECT CASE PropertyRegDataType

     CASE %REG_SZ '1
       'Nothing to do            'pz = VARPTR(zPropertyBuffer) 'zPropertyBuffer = @pz

     CASE %REG_DWORD '4
       zPropertyBuffer = "0x" & HEX$(CVDWD(zPropertyBuffer), 8) 'Convert from DWORD

     CASE %REG_BINARY '3
       FOR index = 1 TO RequiredSize
         sBuf = sBuf & HEX$(ASC(zPropertyBuffer, index), 2) & $SPC
       NEXT : zPropertyBuffer = sBuf

     CASE %REG_MULTI_SZ '7
       pz = VARPTR(zPropertyBuffer) : sBuf = ""
       WHILE LEN(@pz)
         sBuf = sBuf & "[" & @pz & "]" : pz = pz + LEN(@pz)
       WEND : zPropertyBuffer = sBuf

     CASE ELSE
       zPropertyBuffer = "0x" & HEX$(CVDWD(zPropertyBuffer)) 'Convert from DWORD

   END SELECT

   zPropertyBuffer = sDef & $TAB & zPropertyBuffer '& "   (" & REMed ValueDataTypeGet(PropertyRegDataType) & ")"
 ELSE
   LastError = GetLastError()
   zPropertyBuffer = WinErrMsg2(LastError)
   'Returns ERROR_INVALID_DATA if the property does not exist or if the property data is not valid. 0x8007000D
   IF LastError = %ERROR_INVALID_DATA THEN zPropertyBuffer = sDef & $TAB & "[none] Property might not exist : " & zPropertyBuffer
 END IF

 FUNCTION = zPropertyBuffer

END FUNCTION
'______________________________________________________________________________

 5 
 on: September 23, 2018, 03:00:25 PM 
Started by Petrus Vorster - Last post by raymw
Hi Petrus,
You are concerned with producing an alternative to a commercial product, for 'resale'? I expect there are patents etc. on existing techniques, and as its a medical device it most likely needs to get some type approvals/whatever. The Chinese version has most likely been devised by reverse engineering an existing design, and they are probably not concerned with licensing in various countries. Anyway, pull your Chinese unit apart, write down a list of components, see where you can get them, at what price, find a suitable case, etc., then think of the microprocessor and software and interfacing and then time to build 'em, and I would be surprised if you got much change from the price of the Chinese version.
It will be relatively easy to get the flow detectors, humidity sensors, whatever, but unless they are items from the usual electronic distributors, e.g. RS, Rapid, Farnel, etc., then you will probably have to pay over the odds for individual components from the original manufacturer. The mechanics of the system will most likely stump you, finding a suitable case, lightweight flexible tube of an appropriate size, flap valves, connectors and so on. Once you've got the bits, and decided on what you want to control, the actual microprocessor software will be simple, if you've any experience in programming them. Personally, I would tend to use one of the PIC (microchip family) processors, on a bespoke pcb.

I'm not being negative, but I have an understanding of why some items seem expensive, when you enter the internals, but you have to account for the cost of the original development, and I guess liability insurance, type approvals, advertising, etc, etc. The actual component cost, as you've assessed, is trivial.

I would suggest you try and write a check list of what you need to do, components required, software, pcb, etc., and allocate a ballpark price to each item. First of all, where are you getting the air pump? Will a couple of pc cooling fans create sufficient pressure/air flow? How you going to test? etc. Do you need positive displacement e.g. like the aquarium pump I mentioned? Are there small oil free and quiet vane, screw or piston pumps available. How many days will they last, say 10hr a day continuous, or what is the duty cycle? Maybe some bellows could be designed? How much noise is tolerable, can you quieten it? If in a sound deadening enclosure, will it overheat, be too bulky/heavy/expensive. You're gonna have some headaches, but

Best wishes,

Ray

 6 
 on: September 23, 2018, 11:29:16 AM 
Started by Petrus Vorster - Last post by Petrus Vorster
Hi Ray

The machine functions are quite complicated.
So many guys are using it worldwide and the cost is insane.
It was amazing to see how many guys are tired of paying up thousands of dollars worldwide that many guys would like to see another option.
Perhaps a basis machine with the Airblower and so forth connected to either your Laptop or an Android device.
An Open source device will cost $100 if it can work, compared to up to $2500!!!

The real deal measures oxygen levels, breathing patterns, adapt to sleeping patterns, measured co2 levels etc, etc, air humidity and create reports for sleep-labs and so much more. It also adapts air pressure to and from a person based on this info and is not constant.
And then all this must be done quietly without noise, since everyone is sleeping! (And it does all that by reading the air goming back and forth from a person)
The open source device must be able to do basic sensory readings, measure back and forth Airflow and adapt to sudden air flow changes.

The idea for the blower and internal components were created by opening up some of the machines. (They don't last more than 5 years)

O well, there are other guys over there who had done some work already.
This is a BILLION dollar industry worldwide, anyone who could make a cheap alternative would surely be financially rewarded.

 7 
 on: September 22, 2018, 09:35:04 PM 
Started by Petrus Vorster - Last post by raymw
I had to look up what cpap is - If it is the small compressor to aid breathing, and you intend making one for your own use, then that is different then making it for others. Not sure why you need usb or other interface. I'd start with an aquarium diaphragm pump, and a simple spring loaded safety valve in the air tube to regulate the pressure (bleeding off excess to atmosphere). Now, you could tart it up with electronic pressure sensors and the like, regulate the compressor speed/whatever, but that is merely more things to go wrong.

 8 
 on: September 22, 2018, 09:12:27 PM 
Started by raymw - Last post by raymw
eithermouse  software is written in a scripting language - auto hot key- which until now I've not heard of, but the author includes the source, and encourages? folk to edit it. (another turn off the rabbit hole  for me ;)

Still, if it was easy, everyone would be doing it.

 9 
 on: September 22, 2018, 07:23:06 AM 
Started by Petrus Vorster - Last post by Petrus Vorster
Hi Pierre
Very cool. The guys there seem to agree with this.
Turns out some bloke in Australia created freeware for a CPAP on Linux.
HackADay is very interesting indeed.

 10 
 on: September 22, 2018, 04:46:08 AM 
Started by Petrus Vorster - Last post by Pierre Bellisle
Go on eBay and do a search for "Arduino" or "Arduino compatible"
Buy Chinese version they are as good as original, sometime better and cost much less.
They work with "Arduino software" witch is now separate from "Arduino hardware".
If you know how to program in FB, you will find it kind of easy to code for Arduino.

$7.14us for a UNO R3 PLUS Sensor I/O Shield Arduino Compatible Atmega328P 16U2 Expansion Board

There are tons of Chinese "Arduino shields" or "Add on" starting at 99 cents us.
Memory board, sensor, converter, USB, Serial, AD converter, WiFi, BlueTooth,
Clock, Relay, InfraRed, PushButton, MethaneSensor, StepperMotor, Terminal adapter, JoyStick, etc...

Pages: [1] 2 3 ... 10