argumentum Posted 4 hours ago Posted 4 hours ago Spoiler expandcollapse popup#NoTrayIcon #AutoIt3Wrapper_UseX64=y #include <Date.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiMenu.au3> #include <sqlite.au3> #include <Debug.au3> DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", -2) Opt("TrayIconHide", 1) Opt("TrayMenuMode", 3) ;~ Global Const $WM_APP = 0x8000 ;~ Global Const $TRAY_CALLBACK_MSG = $WM_APP + 1 Global Const $TRAY_CALLBACK_MSG = 0x8000 + 1 Global $g_hDummyGUI = GUICreate("TrayHelper") Global $g_iLogToFile = 0 Exit main() Func main() If WinExists('STUB-' & @ScriptName) Then Exit 5 AutoItWinSetTitle('STUB-' & @ScriptName) If $g_iLogToFile Then FileWriteLine(StringTrimRight(@ScriptFullPath, 4) & ".log", @CRLF & _Now() & @CRLF & "Loaded - PID:" & @AutoItPID & @CRLF) Local $iBGColor = 0xFF005500, $iBorderColor = 0xFF349eeb Local $iFGColor = 0xFFE6A800 ; 0xFFFFFFFF ; Default to White text _CreateNumberIcon("X", $iBGColor, $iFGColor, $iBorderColor, "..loading.." & @LF & " ") main_updateTrayWithInfo() AdlibRegister(main_updateTrayWithInfo, 600000) ; 10 min. While 1 Sleep(100) WEnd EndFunc ;==>main Func main_updateTrayWithInfo() Local $hTimer = TimerInit(), $aBluetoothInventory = _Bluetooth_Get_Device_Inventory() Local $sArray = _SQLite_Display2DResult($aBluetoothInventory, 0, True) ConsoleWrite($sArray) If $g_iLogToFile Then FileWriteLine(StringTrimRight(@ScriptFullPath, 4) & ".log", @CRLF & _Now() & @CRLF & $sArray) Local $sText = "?", $iLevel = "?", $iBGColor, $iBorderColor = 0xFF349eeb Local $iFGColor = 0xFFFFFFFF ; Default to White text If UBound($aBluetoothInventory) > 1 Then $iLevel = Int($aBluetoothInventory[1][6]) $sText = $aBluetoothInventory[1][0] & ': ' & $aBluetoothInventory[1][6] & @LF & '(' & $aBluetoothInventory[1][1] & ')' & @LF & ' ' EndIf ; Determine the background color based on the current number If $iLevel >= 50 Then $iBGColor = 0xFF004488 ; BLUE ElseIf $iLevel >= 20 Then $iBGColor = 0xFFE6A800 ; YELLOW $iFGColor = 0xFF000000 ; BLACK text Else $iBGColor = 0xFFD32F2F ; RED EndIf _CreateNumberIcon($iLevel, $iBGColor, $iFGColor, $iBorderColor, $sText) EndFunc ;==>main_updateTrayWithInfo Func _TrayMouseEvents($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local Const $WM_LBUTTONUP = 0x0202 Local Const $WM_LBUTTONDBLCLK = 0x0203 Local Const $WM_RBUTTONUP = 0x0205 Switch $lParam Case $WM_LBUTTONUP ConsoleWrite("--> Primary Click Single!" & @CRLF) Return 0 Case $WM_LBUTTONDBLCLK ConsoleWrite("--> Primary Double Click Action!" & @CRLF) ConsoleWrite("Action: You Double-Clicked the custom tray icon!" & @CRLF) Return 0 Case $WM_RBUTTONUP ; This handles Secondary Click automatically (Righty OR Lefty!) ConsoleWrite("--> Secondary Click! (Show Context Menu)" & @CRLF) Local $hMenu = _GUICtrlMenu_CreatePopup() ;~ _GUICtrlMenu_InsertMenuItem($hMenu, 0, "Show Status...", 1001) _GUICtrlMenu_InsertMenuItem($hMenu, 1, "Reload script", 1002) _GUICtrlMenu_InsertMenuItem($hMenu, 2, "", 0) _GUICtrlMenu_InsertMenuItem($hMenu, 3, "Exit script", 1009) Local $tPoint = DllStructCreate("long X;long Y") DllCall("user32.dll", "bool", "GetCursorPos", "struct*", $tPoint) DllCall("user32.dll", "bool", "SetForegroundWindow", "hwnd", $hWnd) Local $aRet = DllCall("user32.dll", "int", "TrackPopupMenu", "handle", $hMenu, "uint", 0x0100, "int", DllStructGetData($tPoint, "X"), "int", DllStructGetData($tPoint, "Y"), "int", 0, "hwnd", $hWnd, "ptr", 0) Local $iSelectedID = $aRet[0] _GUICtrlMenu_DestroyMenu($hMenu) Switch $iSelectedID Case 1001 ConsoleWrite("Status: TODO" & @CRLF) Case 1002 ConsoleWrite("ReloadScript..." & @CRLF) AdlibRegister(OnTrayMenu_ReloadScript, 10) Case 1009 AdlibRegister(OnTrayMenu_ExitScript, 10) EndSwitch Return 0 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_TrayMouseEvents Func OnTrayMenu_ExitScript() AdlibUnRegister(OnTrayMenu_ExitScript) AutoItWinSetTitle('EXIT-' & @ScriptName) Exit EndFunc ;==>OnTrayMenu_ExitScript Func OnTrayMenu_ReloadScript() AdlibUnRegister(OnTrayMenu_ReloadScript) AutoItWinSetTitle('RELOAD-' & @ScriptName) ShellExecute(@AutoItExe, '"' & @ScriptFullPath & '"') Exit EndFunc ;==>OnTrayMenu_ReloadScript Func _CreateNumberIcon($iNumber, $iBGColor = 0xFF004488, $iFGColor = 0xFFFFFFFF, $iBorderColor = 0xFF34eb58, $sStr = "") Local Static $iInitGDIPlus = _UpdateTray("StartUp") Local $hBitmap = _GDIPlus_BitmapCreateFromScan0(16, 16) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, 4) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2) _GDIPlus_GraphicsClear($hGraphics, $iBorderColor) Local $hBrushBG = _GDIPlus_BrushCreateSolid($iBGColor) Local $iFillWidth = 1 Local $iFillOtherSide = 13 _GDIPlus_GraphicsFillRect($hGraphics, $iFillWidth, $iFillWidth, $iFillOtherSide, $iFillOtherSide, $hBrushBG) Local $hBrushText = _GDIPlus_BrushCreateSolid($iFGColor) Local $hFamily = _GDIPlus_FontFamilyCreate("Arial") ; Get the current DPI for the primary monitor Local $hDC = _WinAPI_GetDC(0) Local $iDPI_X = _WinAPI_GetDeviceCaps($hDC, 88) ; 88 = LOGPIXELSX _WinAPI_ReleaseDC(0, $hDC) ; Calculate the scaling ratio (96 is the standard 100% DPI) Local $fScale = $iDPI_X / 96 ; Use the scale to adjust your font size dynamically Local $iFontSize = 8 / $fScale Local $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize, 1) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) Local $tLayout = _GDIPlus_RectFCreate(0, 0, 16, 16) _GDIPlus_GraphicsDrawStringEx($hGraphics, String($iNumber), $hFont, $tLayout, $hFormat, $hBrushText) Local $hGDI_Bitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) Local $aMask = DllCall("gdi32.dll", "handle", "CreateBitmap", "int", 16, "int", 16, "uint", 1, "uint", 1, "ptr", 0) Local $hMask = $aMask[0] Local $tICONINFO = DllStructCreate("int fIcon; dword xHotspot; dword yHotspot; handle hbmMask; handle hbmColor") DllStructSetData($tICONINFO, "fIcon", 1) DllStructSetData($tICONINFO, "hbmMask", $hMask) DllStructSetData($tICONINFO, "hbmColor", $hGDI_Bitmap) Local $aIcon = DllCall("user32.dll", "handle", "CreateIconIndirect", "struct*", $tICONINFO) Local $hIcon = $aIcon[0] DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hMask) DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hGDI_Bitmap) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrushText) _GDIPlus_BrushDispose($hBrushBG) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _UpdateTray($hIcon, $sStr) DllCall("user32.dll", "bool", "DestroyIcon", "handle", $hIcon) Return 0 EndFunc ;==>_CreateNumberIcon Func _UpdateTray_OnShutdown() _UpdateTray("ShutDown", "") GUIRegisterMsg($TRAY_CALLBACK_MSG, "") If IsHWnd($g_hDummyGUI) Then GUIDelete($g_hDummyGUI) _GDIPlus_Shutdown() EndFunc ;==>_UpdateTray_OnShutdown Func _UpdateTray($hIcon, $sStr = "") Local Static $iStartup = "StartUp", $_bTrayCreated = False, $_tNID = DllStructCreate("dword Size;hwnd Wnd;uint ID;uint Flags;uint CallbackMessage;handle Icon;wchar Tip[128]") If $iStartup = "StartUp" Then DllStructSetData($_tNID, "Size", DllStructGetSize($_tNID)) DllStructSetData($_tNID, "Wnd", $g_hDummyGUI) DllStructSetData($_tNID, "ID", 999) DllStructSetData($_tNID, "Flags", 0x07) DllStructSetData($_tNID, "CallbackMessage", $TRAY_CALLBACK_MSG) GUIRegisterMsg($TRAY_CALLBACK_MSG, "_TrayMouseEvents") _GDIPlus_Startup() OnAutoItExitRegister(_UpdateTray_OnShutdown) $iStartup = "Running" If $hIcon = "StartUp" Then Return 1 ElseIf $hIcon = "ShutDown" Then DllCall("shell32.dll", "bool", "Shell_NotifyIconW", "dword", 0x02, "struct*", $_tNID) ; NIM_DELETE _GDIPlus_Shutdown() Return 2 EndIf DllStructSetData($_tNID, "Icon", $hIcon) DllStructSetData($_tNID, "Tip", String($sStr)) If Not $_bTrayCreated Then DllCall("shell32.dll", "bool", "Shell_NotifyIconW", "dword", 0x00, "struct*", $_tNID) $_bTrayCreated = True Else DllCall("shell32.dll", "bool", "Shell_NotifyIconW", "dword", 0x01, "struct*", $_tNID) EndIf EndFunc ;==>_UpdateTray ; ====================================================================================== Func _Bluetooth_Get_Device_Inventory() Local $a_GetBluetoothDeviceInfo = _GetBluetoothDeviceInfo() Local $aError[1][1] = [["No Bluetooth Radio found or Bluetooth is turned off."]] ; Initialize Radio Local $tFindRadioParams = DllStructCreate("dword dwSize") DllStructSetData($tFindRadioParams, "dwSize", DllStructGetSize($tFindRadioParams)) Local $hRadioOut = 0 Local $aRadioCall = DllCall("Bthprops.cpl", "hwnd", "BluetoothFindFirstRadio", "ptr", DllStructGetPtr($tFindRadioParams), "hwnd*", $hRadioOut) If @error Or $aRadioCall[0] = 0 Then SetError(1) Return $aError EndIf Local $hRadio = $aRadioCall[2] Local $hRadioFindHandle = $aRadioCall[0] ; Search Parameters Local $sSearchParams = "dword dwSize; bool fReturnAuthenticated; bool fReturnRemembered; bool fReturnUnknown; bool fReturnConnected; bool fIssueInquiry; byte cTimeoutMultiplier; hwnd hRadio;" Local $tSearchParams = DllStructCreate($sSearchParams) DllStructSetData($tSearchParams, "dwSize", DllStructGetSize($tSearchParams)) DllStructSetData($tSearchParams, "fReturnAuthenticated", 1) DllStructSetData($tSearchParams, "fReturnRemembered", 1) DllStructSetData($tSearchParams, "fReturnUnknown", 1) DllStructSetData($tSearchParams, "fReturnConnected", 1) DllStructSetData($tSearchParams, "fIssueInquiry", 1) DllStructSetData($tSearchParams, "cTimeoutMultiplier", 4) DllStructSetData($tSearchParams, "hRadio", $hRadio) ; Device Struct Definition Local $sDeviceInfo = "dword dwSize; int64 Address; dword ulClassofDevice; bool fConnected; bool fRemembered; bool fAuthenticated; " & _ "ushort LastSeenYear; ushort LastSeenMonth; ushort LastSeenDayOfWeek; ushort LastSeenDay; ushort LastSeenHour; ushort LastSeenMinute; ushort LastSeenSecond; ushort LastSeenMS; " & _ "ushort LastUsedYear; ushort LastUsedMonth; ushort LastUsedDayOfWeek; ushort LastUsedDay; ushort LastUsedHour; ushort LastUsedMinute; ushort LastUsedSecond; ushort LastUsedMS; " & _ "wchar szName[248];" Local $tDeviceInfo = DllStructCreate($sDeviceInfo) DllStructSetData($tDeviceInfo, "dwSize", DllStructGetSize($tDeviceInfo)) ; Prepare Output Array Structure (Columns: 0 to 7) Local $aResult[1][7] = [["Device Name", "MAC Address (Hex)", "Device Class", "Connected", "Remembered", "Last Used", "Battery Level"]] Local $iDeviceCount = 0 ; Start Device Loop Local $aDeviceCall = DllCall("Bthprops.cpl", "hwnd", "BluetoothFindFirstDevice", "ptr", DllStructGetPtr($tSearchParams), "ptr", DllStructGetPtr($tDeviceInfo)) If @error Or $aDeviceCall[0] = 0 Then DllCall("Bthprops.cpl", "bool", "BluetoothFindRadioClose", "hwnd", $hRadioFindHandle) DllCall("kernel32.dll", "bool", "CloseHandle", "hwnd", $hRadio) Return $aResult Else Local $hDeviceFindHandle = $aDeviceCall[0] Local $sName, $iAddress, $iClass, $bConnected, $bRemembered, $sHexMac, $sFormattedHexMac, $sLastUsed, $sBatteryVal, $iMajorClass While 1 ; Get Data from API $sName = DllStructGetData($tDeviceInfo, "szName") $iAddress = DllStructGetData($tDeviceInfo, "Address") $iClass = DllStructGetData($tDeviceInfo, "ulClassofDevice") $bConnected = DllStructGetData($tDeviceInfo, "fConnected") $bRemembered = DllStructGetData($tDeviceInfo, "fRemembered") $sHexMac = StringLower(Hex($iAddress, 12)) $sFormattedHexMac = StringRegExpReplace($sHexMac, "(.{2})(?=.)", "$1:") ; Parse Timestamp $sLastUsed = "Never" If DllStructGetData($tDeviceInfo, "LastUsedYear") > 0 Then $sLastUsed = DllStructGetData($tDeviceInfo, "LastUsedMonth") & "/" & DllStructGetData($tDeviceInfo, "LastUsedDay") & "/" & DllStructGetData($tDeviceInfo, "LastUsedYear") & _ " " & StringRight("00" & DllStructGetData($tDeviceInfo, "LastUsedHour"), 2) & ":" & StringRight("00" & DllStructGetData($tDeviceInfo, "LastUsedMinute"), 2) EndIf ; Fetch Live Battery if connected $sBatteryVal = "N/A" ; (Offline)" For $iEntry = 0 To UBound($a_GetBluetoothDeviceInfo) - 1 If $a_GetBluetoothDeviceInfo[$iEntry][6] = $sFormattedHexMac Then $sBatteryVal = $a_GetBluetoothDeviceInfo[$iEntry][1] Next ; Major Device Class occupies bits 8 to 12 $iMajorClass = BitShift(BitAND($iClass, 0x1F00), 8) ;~ If $iMajorClass = 4 And $bRemembered Then If $iMajorClass = 4 And $bConnected Then $iDeviceCount += 1 ReDim $aResult[$iDeviceCount + 1][UBound($aResult, 2)] $aResult[$iDeviceCount][0] = $sName $aResult[$iDeviceCount][1] = StringUpper($sFormattedHexMac) $aResult[$iDeviceCount][2] = "0x" & Hex($iClass, 6) $aResult[$iDeviceCount][3] = ($bConnected ? "True" : "False") $aResult[$iDeviceCount][4] = ($bRemembered ? "True" : "False") $aResult[$iDeviceCount][5] = $sLastUsed $aResult[$iDeviceCount][6] = $sBatteryVal ; << don't work here EndIf ; Next Device Local $aNextCall = DllCall("Bthprops.cpl", "bool", "BluetoothFindNextDevice", "hwnd", $hDeviceFindHandle, "ptr", DllStructGetPtr($tDeviceInfo)) If @error Or $aNextCall[0] = 0 Then ExitLoop WEnd DllCall("Bthprops.cpl", "bool", "BluetoothFindDeviceClose", "hwnd", $hDeviceFindHandle) EndIf ; Cleanup DllCall("Bthprops.cpl", "bool", "BluetoothFindRadioClose", "hwnd", $hRadioFindHandle) DllCall("kernel32.dll", "bool", "CloseHandle", "hwnd", $hRadio) Return $aResult EndFunc ;==>_Bluetooth_Get_Device_Inventory Func _GetBluetoothDeviceInfo() Local Const $DIGCF_PRESENT = 0x00000002 Local Const $DIGCF_DEVICEINTERFACE = 0x00000010 ; Define properties to query: {GUID}, Property ID Local $aKeys[5][2] = [ _ ["{a45c254e-df1c-4efd-8020-67d146a850e0}", 14], _ ; Friendly Name ["{104EA319-6EE2-4701-BD47-8DDBF425BBE5}", 2], _ ; Battery Level ["{a45c254e-df1c-4efd-8020-67d146a850e0}", 13], _ ; Manufacturer (May still be blank for Generic BT devices!) ["{a45c254e-df1c-4efd-8020-67d146a850e0}", 3], _ ; Hardware ID ["{78c34fc8-104a-4aca-9ea4-524d52996e57}", 256] _ ; Instance ID ] Local $iNumProps = UBound($aKeys) ; Bluetooth Device Interface Class GUID Local $tGUID = DllStructCreate("ulong;ushort;ushort;byte[8]") DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", "{0000111e-0000-1000-8000-00805f9b34fb}", "ptr", DllStructGetPtr($tGUID)) ; Handle to active Bluetooth objects Local $aHdev = DllCall("setupapi.dll", "handle", "SetupDiGetClassDevsW", _ "ptr", DllStructGetPtr($tGUID), "ptr", 0, "hwnd", 0, "dword", BitOR($DIGCF_PRESENT, $DIGCF_DEVICEINTERFACE)) If @error Or $aHdev[0] = -1 Then Return SetError(1, 0, 0) Local $hDevInfo = $aHdev[0] ; Explicit structural memory boundaries for 64-bit portability Local $sInterfaceDataDef = "dword cbSize;ulong;ushort;ushort;byte[8];ulong_ptr Reserved" Local $tDeviceInterfaceData = DllStructCreate($sInterfaceDataDef) DllStructSetData($tDeviceInterfaceData, "cbSize", DllStructGetSize($tDeviceInterfaceData)) Local $sDevInfoDataDef = "dword cbSize;ulong;ushort;ushort;byte[8];ulong_ptr DevInst" Local $tDeviceInfoData = DllStructCreate($sDevInfoDataDef) DllStructSetData($tDeviceInfoData, "cbSize", DllStructGetSize($tDeviceInfoData)) Local $iIndex = 0 Local $aResults[50][$iNumProps] Local $iCount = 0 While True Local $aEnum = DllCall("setupapi.dll", "bool", "SetupDiEnumDeviceInterfaces", _ "handle", $hDevInfo, "ptr", 0, "ptr", DllStructGetPtr($tGUID), "dword", $iIndex, "ptr", DllStructGetPtr($tDeviceInterfaceData)) If @error Or Not $aEnum[0] Then ExitLoop ; Match interface to specific hardware instance block DllCall("setupapi.dll", "bool", "SetupDiGetDeviceInterfaceDetailW", _ "handle", $hDevInfo, "ptr", DllStructGetPtr($tDeviceInterfaceData), "ptr", 0, "dword", 0, "dword*", 0, "ptr", DllStructGetPtr($tDeviceInfoData)) Local $bHasData = False ; Loop through our mapped DEVPROPKEYs For $i = 0 To $iNumProps - 1 Local $tPropKey = DllStructCreate("ulong;ushort;ushort;byte[8];ulong") DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", $aKeys[$i][0], "ptr", DllStructGetPtr($tPropKey)) DllStructSetData($tPropKey, 5, $aKeys[$i][1]) ; Use a generic byte buffer large enough for any standard type Local $tBuffer = DllStructCreate("byte[1024]") Local $iPropType = 0 Local $iReqSize = 0 ; Extract Property Local $aProp = DllCall("setupapi.dll", "bool", "SetupDiGetDevicePropertyW", _ "handle", $hDevInfo, "ptr", DllStructGetPtr($tDeviceInfoData), "ptr", DllStructGetPtr($tPropKey), _ "ulong*", $iPropType, "ptr", DllStructGetPtr($tBuffer), "dword", 1024, "dword*", $iReqSize, "dword", 0) Local $sValue = "" ; If extraction succeeded, cast the memory dynamically based on the returned PropertyType If Not @error And $aProp[0] Then $iPropType = $aProp[4] ; $aProp[4] holds the type of data Windows returned If $iPropType = 0x00000012 Or $iPropType = 0x00002012 Then ; DEVPROP_TYPE_STRING or DEVPROP_TYPE_STRING_LIST Local $tString = DllStructCreate("wchar[512]", DllStructGetPtr($tBuffer)) $sValue = DllStructGetData($tString, 1) ElseIf $iPropType = 0x00000003 Then ; DEVPROP_TYPE_BYTE (Used for Battery Levels) $sValue = DllStructGetData($tBuffer, 1, 1) If $sValue >= 0 And $sValue <= 100 Then $sValue &= "%" ElseIf $iPropType = 0x00000007 Then ; DEVPROP_TYPE_UINT32 Local $tInt = DllStructCreate("dword", DllStructGetPtr($tBuffer)) $sValue = DllStructGetData($tInt, 1) EndIf If $sValue <> "" Then $bHasData = True EndIf $aResults[$iCount][$i] = (StringLen($sValue) < 2 ? "N/A" : $sValue) Next ; Only move to the next row if the device actually had populated metadata If $bHasData Then $iCount += 1 ; Dynamically resize array if you have more than 50 Bluetooth components If $iCount >= UBound($aResults) Then ReDim $aResults[UBound($aResults) + 20][$iNumProps] $iIndex += 1 WEnd DllCall("setupapi.dll", "bool", "SetupDiDestroyDeviceInfoList", "handle", $hDevInfo) If $iCount = 0 Then Return SetError(2, 0, 0) ReDim $aResults[$iCount][$iNumProps + 2] Local $aMatch, $sFormattedMAC ; get MAC from InstanceID For $n = 0 To UBound($aResults) - 1 $aMatch = StringRegExp($aResults[$n][$iNumProps - 1], "&([0-9A-Fa-f]{12})_", 1) If @error Then ContinueLoop $sFormattedMAC = StringRegExpReplace($aMatch[0], "(.{2})(?!$)", "$1:") If @error Then ContinueLoop $aResults[$n][$iNumProps + 1] = $sFormattedMAC Next Return $aResults EndFunc ;==>_GetBluetoothDeviceInfo ; ====================================================================================== ;~ ConsoleWrite("DeviceClass desc.: " & _DecodeDeviceClass(0x240404) & @CRLF) Func _DecodeDeviceClass($iCoD) ;~ Local $iCoD = 0x240404 ;~ ; Major Service Classes (Bits 13 to 23) ;~ Local $iServiceClass = BitAND($iCoD, 0xFFE000) ;~ ; Major Device Class (Bits 8 to 12) ;~ Local $iMajorClass = BitShift(BitAND($iCoD, 0x1F00), 8) ; Will return 4 for Audio/Video ;~ ; Minor Device Class (Bits 2 to 7) ;~ Local $iMinorClass = BitShift(BitAND($iCoD, 0xFC), 2) ; Will return 1 for Headset, 6 for Headphones Local $iMajorClass = BitShift(BitAND($iCoD, 0x1F00), 8) Local $iMinorClass = BitShift(BitAND($iCoD, 0x00FC), 2) Local $sMajorText = "Unknown" Local $sMinorText = "Generic" ; Look-up for Major Device Class Switch $iMajorClass Case 1 $sMajorText = "Computer" Case 2 $sMajorText = "Phone" Case 3 $sMajorText = "Network Access Point" Case 4 $sMajorText = "Audio/Video" Case 5 $sMajorText = "Peripheral (Mouse/Keyboard)" Case 6 $sMajorText = "Imaging (Printer/Scanner)" Case 7 $sMajorText = "Wearable" EndSwitch ; Look-up for Minor Device Class ( for Audio/Video family ) If $iMajorClass = 4 Then Switch $iMinorClass Case 1 $sMinorText = "Wearable Headset" Case 2 $sMinorText = "Hands-free Device" Case 4 $sMinorText = "Microphone" Case 5 $sMinorText = "Loudspeaker" Case 6 $sMinorText = "Headphones" Case 7 $sMinorText = "Portable Audio" Case 11 $sMinorText = "Set-top Box" Case 12 $sMinorText = "HiFi Audio Device" Case 13 $sMinorText = "VCR/DVD/BlueRay" Case 14 $sMinorText = "Video Camera" Case 15 $sMinorText = "Display/Monitor and Loudspeaker" EndSwitch EndIf Return $sMajorText & " -> " & $sMinorText EndFunc ;==>_DecodeDeviceClass ; ====================================================================================== I use earbuds ( these cheaper ones because they don't bother my ears** ) and the internal batteries of each side are different. Meaning that one always dies hours before the other and I wanted a "tray indicator" because the build-in on windows one takes clicking, and the "battery low" announcement annoys me when am not close to the PC. Now if I happen to see the battery at 40% or less I know that might as well swap them with my other set of earbuds if I feel like it. ** since I don't inset them in my ear canal ( just let them loose ), I also have a sound equalizer ( FxSound ) to make them sound better. Code wise here are examples of a fake tray icon with clicking and Bluetooth radio, and other Bluetooth things if you scrape them out of the script. It checks every 10 min. P.S.: Was thinking of adding a "on new devise connected" thing, and if I ever do, I'll update the example. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now