
Main.pb
Code: Select all
; By Thunder93
; Released to PureBasic Community on March 27th, 2016
;
; Requirements: setupapi_h.pbi, cfg_h.pbi files~
; - available on ' SetupAPI, Cfg+ headers (for PureBasic Community) '
; http://www.purebasic.fr/english/viewtopic.php?f=5&t=65230
; Last Updated: March 28th, 2016 (#4)
Global hImageList
Global MergedIcons
IncludeFile "GetHardwareList_Func.pbi"
#ICON_DEV_PROBLEM = 80
#ICON_DEV_DISABLED = 81
#ICON_DEV_INFO = 82
#ICON_DEV_UNKNOWN = 103
Structure GetFont
Fontsize.b
FontName.s
EndStructure : Global GetFont.GetFont
Global Dim Hd.HardwareInfo(200)
Declare.b SortALLTreeviewItemsbyNameAscending(GadgetID)
Declare.s GetComputerName()
Declare.b GetFontINFO()
Declare.b AddItem2Tree(ItemName.s, Pos.l)
Declare.b Main_Win()
If GetHardwareList(Hd(), 0, 1) = #True
Main_Win()
EndIf
End
Procedure.b Main_Win()
Protected i
If OpenWindow(0, 0, 0, 700, 600, "Device Manager", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
If CreateStatusBar(0, WindowID(0))
AddStatusBarField(420)
EndIf
GetFontINFO()
If LoadFont(2, GetFont\FontName, GetFont\Fontsize)
SetGadgetFont(#PB_Default, FontID(2))
EndIf
TreeGadget(1, 5, 5, WindowWidth(0)-10, WindowHeight(0)-StatusBarHeight(0)-10, #PB_Tree_NoLines)
AddGadgetItem(1, -1, GetComputerName(), ImageList_GetIcon_(hImageList, 34, #ILD_NORMAL), 1)
SortStructuredArray(Hd(), 0, OffsetOf(HardwareInfo\ClassDescription), TypeOf(HardwareInfo\ClassDescription))
For i=0 To ArraySize(Hd())
If Hd(i)\Class <> Class$
Class$ = Hd(i)\Class
AddGadgetItem(1, -1, Hd(i)\ClassDescription, ImageList_GetIcon_(hImageList, Hd(i)\ClassImgIndex, #ILD_NORMAL), 1)
EndIf
AddItem2Tree(Hd(i)\Name, i)
Next
SetGadgetItemState(1, 0, #PB_Tree_Expanded)
StatusBarText(0, 0, Str(i)+" Items Found!")
SortALLTreeviewItemsbyNameAscending(1)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
If hImageList
ImageList_Destroy_(hImageList)
EndIf
For i = 0 To ArraySize(Hd())
DestroyIcon_(Hd(i)\hIcon)
Next
EndIf
EndProcedure
Structure ICONINFOEX Align #PB_Structure_AlignC
cbSize.l
fIcon.l
xHotspot.l
yHotspot.l
hbmMask.i
hbmColor.i
wResID.w
szModName.c[#MAX_PATH]
szResName.c[#MAX_PATH]
EndStructure
#hBITMAP = 0
#hICON = 1
Procedure CreateFadedImage(hImage, Intensity.l = 100, TypeImg.l = #hICON)
Protected ImageID = hImage, FadedImage, IB.BITMAP
If TypeImg
Protected Image_Bitmap.BITMAP, IconInfo.ICONINFOEX
IconInfo\cbSize = SizeOf(ICONINFOEX)
GetIconInfoEx(hImage, @IconInfo)
DestroyIcon_(hImage)
ImageID = CopyImage_(IconInfo\hbmColor, #IMAGE_BITMAP, 0, 0, #LR_CREATEDIBSECTION)
EndIf
If GetObject_(ImageID, SizeOf(BITMAP), @IB)
FadedImage = CreateImage(#PB_Any, IB\bmWidth, IB\bmHeight, 32, #PB_Image_Transparent)
StartDrawing(ImageOutput(FadedImage))
DrawAlphaImage(ImageID, 0, 0, Intensity)
StopDrawing()
DeleteObject_(ImageID)
ProcedureReturn ImageID(FadedImage)
EndIf
EndProcedure
Procedure MergeImages(hICON, Mode.b)
Protected Image_Bitmap.BITMAP, IconInfo.ICONINFOEX
Protected hICON2, MergedIcons, ImageID, ImageID1, ImageID2
hICON2 = ImageList_GetIcon_(hImageList, Mode, #ILD_NORMAL)
IconInfo\cbSize = SizeOf(ICONINFOEX)
GetIconInfoEx(hICON2, @IconInfo)
DestroyIcon_(hICON2)
ImageID1 = CopyImage_(IconInfo\hbmColor, #IMAGE_BITMAP, 0, 0, #LR_CREATEDIBSECTION)
GetIconInfoEx(hICON, @IconInfo)
ImageID2 = CopyImage_(IconInfo\hbmColor, #IMAGE_BITMAP, 0, 0, #LR_CREATEDIBSECTION)
MergedIcons = CreateImage(#PB_Any, 16, 16, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(MergedIcons))
DrawAlphaImage(ImageID2, 0, 0, 255)
DrawAlphaImage(ImageID1, 0, 0, 255)
StopDrawing()
EndIf
DeleteObject_(ImageID1)
DeleteObject_(ImageID2)
ProcedureReturn ImageID(MergedIcons)
EndProcedure
Procedure.b AddItem2Tree(ItemName.s, Pos.l)
Protected.l CM_Status, CM_Problem
CM_Status = Hd(Pos)\CM_Status : CM_Problem = Hd(Pos)\CM_Problem
If #DN_STARTED & (CM_Status + CM_Problem) Or (CM_Problem = 0 And CM_Status)
AddGadgetItem(1, -1, ItemName, Hd(Pos)\hICON, 2)
ElseIf CM_Problem = #CM_PROB_DISABLED
AddGadgetItem(1, -1, ItemName, MergeImages(Hd(Pos)\hICON, #ICON_DEV_DISABLED), 2)
ElseIf 0 = (CM_Status + CM_Problem)
AddGadgetItem(1, -1, ItemName, CreateFadedImage(Hd(Pos)\hICON), 2)
Else
AddGadgetItem(1, -1, ItemName, MergeImages(Hd(Pos)\hICON, #ICON_DEV_UNKNOWN), 2)
EndIf
EndProcedure
Procedure.b SortALLTreeViewItemsbyNameAscending(GadgetID)
Protected i.l
For i=0 To CountGadgetItems(GadgetID)-1
If SendMessage_(GadgetID(GadgetID), #TVM_GETNEXTITEM, #TVGN_CHILD, GadgetItemID(GadgetID, i))
SendMessage_(GadgetID(GadgetID), #TVM_SORTCHILDREN, 0, GadgetItemID(GadgetID, i))
EndIf
Next
SendMessage_(GadgetID(GadgetID), #TVM_SORTCHILDREN, 0, 0)
EndProcedure
Procedure.s GetComputerName()
Protected buffer.s=Space(64), bufsize.l=64
GetComputerName_(@buffer, @bufsize)
ProcedureReturn buffer
EndProcedure
Procedure.b GetFontINFO()
Protected hGDIOBJ = GetStockObject_(#DEFAULT_GUI_FONT)
If hGDIOBJ
Protected fINFO.LOGFONT
GetObject_(hGDIOBJ,SizeOf(LOGFONT),@fINFO)
GetFont\Fontsize-fINFO\lfHeight
GetFont\FontName = PeekS(@fINFO\lfFaceName[0])
DeleteObject_(hGDIOBJ)
Else
GetFont\FontName = "System"
GetFont\Fontsize = 12
EndIf
ProcedureReturn GetFont\Fontsize
EndProcedure
Code: Select all
XIncludeFile "\[Headers]\setupapi_h.pbi"
XIncludeFile "\[Headers]\cfg_h.pbi"
;Constant from CFGMGR32_H
#MAX_CLASS_NAME_LEN = 32
;________________________
#MAX_IT = #MAX_PATH+64
;________________________
Global hImageList
Structure HardwareInfo
Name.s{#MAX_IT}
Class.s{#MAX_CLASS_NAME_LEN}
ClassDescription.s
ClassGUID.s
ClassImgIndex.l
*hIcon
CM_Status.l
CM_Problem.l
EndStructure
Prototype GetIconInfoEx(*hICON, PICONINFOEX)
Global GetIconInfoEx.GetIconInfoEx
Declare.b User32_Init()
Declare.b User32_End()
Declare.s GetGUID(guid)
Procedure.b GetHardwareList(Array Hd.HardwareInfo(1), Max.l = 200, GetImage.b = 0)
If setupapi_Init() = #False : ProcedureReturn -1 : EndIf
If User32_Init() = #False : setupapi_End() : ProcedureReturn -3 : EndIf
Protected hDevInfo
hDevInfo = SetupDiGetClassDevs_(#Null, #Null, #Null, #DIGCF_ALLCLASSES)
If hDevInfo = #INVALID_HANDLE_VALUE
ProcedureReturn 0
EndIf
Protected ClassImageListData.SP_CLASSIMAGELIST_DATA
Protected DeviceInfoData.SP_DEVINFO_DATA
Protected.l Property, reqSize, iIdx, ArrayPos, ClassImgIndex
Protected.l CM_Status, CM_Problem
Protected ClassDescription.s
DeviceInfoData\cbSize = SizeOf(SP_DEVINFO_DATA)
ClassImageListData\cbSize = SizeOf(ClassImageListData)
If SetupDiGetClassImageList_(ClassImageListData) = #False
GetImage = 0
EndIf
While SetupDiEnumDeviceInfo_(hDevInfo, iIdx, @DeviceInfoData)
If GetLastError_() = #ERROR_NO_MORE_ITEMS : Break : EndIf
Property = #SPDRP_FRIENDLYNAME
If Not SetupDiGetDeviceRegistryProperty_(hDevInfo, @DeviceInfoData, #SPDRP_FRIENDLYNAME, #Null, #Null, 0, @reqSize)
If GetLastError_() = #ERROR_INVALID_DATA
SetupDiGetDeviceRegistryProperty_(hDevInfo, @DeviceInfoData, #SPDRP_DEVICEDESC, #Null, #Null, 0, @reqSize)
If GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
Property = #SPDRP_DEVICEDESC
Else
ArrayPos = iIdx
Goto PhaseWrap:
EndIf
EndIf
EndIf
Hd(ArrayPos)\ClassGUID = GetGuid(DeviceInfoData\ClassGuid)
CM_Retr = CM_Get_DevNode_Status(@CM_Status, @CM_Problem, DeviceInfoData\DevInst, 0)
Hd(ArrayPos)\CM_Status = CM_Status
Hd(ArrayPos)\CM_Problem = CM_Problem
SetupDiGetDeviceRegistryProperty_(hDevInfo, @DeviceInfoData, Property, #Null, @Hd(ArrayPos)\Name, #MAX_IT, #Null)
SetupDiGetDeviceRegistryProperty_(hDevInfo, @DeviceInfoData, #SPDRP_CLASS, #Null, @Hd(ArrayPos)\Class, #MAX_CLASS_NAME_LEN, #Null)
ClassDescription.s = Space(#MAX_PATH)
If SetupDiGetClassDescription(DeviceInfoData\ClassGuid, @ClassDescription, #MAX_PATH, 0)
Hd(ArrayPos)\ClassDescription = ClassDescription
EndIf
If GetImage
SetupDiLoadDeviceIcon(hDevInfo, @DeviceInfoData, 16, 16, 0, @Hd(ArrayPos)\hIcon)
EndIf
If SetupDiGetClassImageIndex_(ClassImageListData, DeviceInfoData\ClassGuid, @ClassImgIndex) = #True
Hd(ArrayPos)\ClassImgIndex = ClassImgIndex
EndIf
ArrayPos+1
PhaseWrap:
CM_Status = 0 : CM_Problem = 0
iIdx+1
If iIdx > Max : Max = iIdx+20 : ReDim Hd(Max) : EndIf
Wend
If GetImage
hImageList = ImageList_Duplicate_(ClassImageListData\ImageList)
EndIf
ReDim Hd.HardwareInfo(ArrayPos-1)
SetupDiDestroyClassImageList_(ClassImageListData)
SetupDiDestroyDeviceInfoList_(hDevInfo)
User32_End() : setupapi_End()
If *pBuf : FreeMemory(*pBuf) : EndIf
ProcedureReturn 1
EndProcedure
Procedure.s GetGUID(Guid)
Protected lpsz.s{78}
ProcedureReturn PeekS(@lpsz, StringFromGUID2_(Guid, @lpsz, 78), #PB_Unicode)
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
MaxArray_Size.l = 200 : GetImage.b = 0
Dim Hd.HardwareInfo(MaxArray_Size)
GetHardwareList(Hd.HardwareInfo(), MaxArray_Size)
Debug "(((( Array Size: "+ArraySize(Hd())+" ))))"+#LF$
For i = 0 To ArraySize(Hd())
Debug "Item: "+Str(i+1)
Debug " Device Name: "+Hd(i)\Name
Debug " Class: "+Hd(i)\Class
Debug " Class Description: "+Hd(i)\ClassDescription
Debug " Class GUID: "+Hd(i)\ClassGUID
Debug " Class Image Index: "+Hd(i)\ClassImgIndex
Debug " CM_Status: "+Hd(i)\CM_Status
Debug " CM_Problem: "+Hd(i)\CM_Problem+#CRLF$
If Hd(i)\CM_Status
Debug " Device Status flags...:"
If Hd(i)\CM_Status & #DN_ROOT_ENUMERATED : Debug " DN_ROOT_ENUMERATED" : EndIf
If Hd(i)\CM_Status & #DN_DRIVER_LOADED : Debug " DN_DRIVER_LOADED" : EndIf
If Hd(i)\CM_Status & #DN_ENUM_LOADED : Debug " DN_ENUM_LOADED" : EndIf
If Hd(i)\CM_Status & #DN_STARTED : Debug " DN_STARTED" : EndIf
If Hd(i)\CM_Status & #DN_MANUAL : Debug " DN_MANUAL" : EndIf
If Hd(i)\CM_Status & #DN_NEED_TO_ENUM : Debug " DN_NEED_TO_ENUM" : EndIf
If Hd(i)\CM_Status & #DN_DRIVER_BLOCKED : Debug " DN_DRIVER_BLOCKED" : EndIf
If Hd(i)\CM_Status & #DN_HARDWARE_ENUM : Debug " DN_HARDWARE_ENUM" : EndIf
If Hd(i)\CM_Status & #DN_NEED_RESTART : Debug " DN_NEED_RESTART" : EndIf
If Hd(i)\CM_Status & #DN_CHILD_WITH_INVALID_ID : Debug " DN_CHILD_WITH_INVALID_ID" : EndIf
If Hd(i)\CM_Status & #DN_HAS_PROBLEM : Debug " DN_HAS_PROBLEM" : EndIf
If Hd(i)\CM_Status & #DN_FILTERED : Debug " DN_FILTERED" : EndIf
If Hd(i)\CM_Status & #DN_LEGACY_DRIVER : Debug " DN_LEGACY_DRIVER" : EndIf
If Hd(i)\CM_Status & #DN_DISABLEABLE : Debug " DN_DISABLEABLE" : EndIf
If Hd(i)\CM_Status & #DN_REMOVABLE : Debug " DN_REMOVABLE" : EndIf
If Hd(i)\CM_Status & #DN_PRIVATE_PROBLEM : Debug " DN_PRIVATE_PROBLEM" : EndIf
If Hd(i)\CM_Status & #DN_MF_PARENT : Debug " DN_MF_PARENT" : EndIf
If Hd(i)\CM_Status & #DN_MF_CHILD : Debug " DN_MF_CHILD" : EndIf
If Hd(i)\CM_Status & #DN_WILL_BE_REMOVED : Debug " DN_WILL_BE_REMOVED" : EndIf
If Hd(i)\CM_Status & #DN_NOT_FIRST_TIMEE : Debug " DN_NOT_FIRST_TIMEE" : EndIf
If Hd(i)\CM_Status & #DN_STOP_FREE_RES : Debug " DN_STOP_FREE_RES" : EndIf
If Hd(i)\CM_Status & #DN_REBAL_CANDIDATE : Debug " DN_REBAL_CANDIDATE" : EndIf
If Hd(i)\CM_Status & #DN_BAD_PARTIAL : Debug " DN_BAD_PARTIAL" : EndIf
If Hd(i)\CM_Status & #DN_NT_ENUMERATOR : Debug " DN_NT_ENUMERATOR" : EndIf
If Hd(i)\CM_Status & #DN_NT_DRIVER : Debug " DN_NT_DRIVER" : EndIf
If Hd(i)\CM_Status & #DN_NEEDS_LOCKING : Debug " DN_NEEDS_LOCKING" : EndIf
If Hd(i)\CM_Status & #DN_ARM_WAKEUP : Debug " DN_ARM_WAKEUP" : EndIf
If Hd(i)\CM_Status & #DN_APM_ENUMERATOR : Debug " DN_APM_ENUMERATOR" : EndIf
If Hd(i)\CM_Status & #DN_APM_DRIVER : Debug " DN_APM_DRIVER" : EndIf
If Hd(i)\CM_Status & #DN_SILENT_INSTALL : Debug " DN_SILENT_INSTALL" : EndIf
If Hd(i)\CM_Status & #DN_NO_SHOW_IN_DM : Debug " DN_NO_SHOW_IN_DM" : EndIf
If Hd(i)\CM_Status & #DN_BOOT_LOG_PROB : Debug " DN_BOOT_LOG_PROB" : EndIf
EndIf
Debug "-"
Next
FreeArray(Hd())
End
CompilerEndIf
Procedure.b User32_Init()
Shared hUser32, cExt
Protected Retr.b
hUser32 = OpenLibrary(#PB_Any, "user32.dll")
If hUser32 <> 0
GetIconInfoEx = GetFunction(hUser32, "GetIconInfoEx"+cExt)
Retr = 1
EndIf
ProcedureReturn Retr
EndProcedure
Procedure.b User32_End()
Shared hUser32
CloseLibrary(hUser32)
EndProcedure