注册消息函数0x0219,怎么样能同时检测到所有变动的分区?
注册消息函数0x0219,比如插入的移动硬盘有两个分区,它只能检测到其中一个分区,拔除的时候也是一样的。怎么样能同时检测到所有变动的分区?谢谢!#NoTrayIcon
#RequireAdmin
#PRE_UseX64 = n
$Form = GUICreate("", 800, 240)
GUIRegisterMsg(0x0219, "_WM_DEVICECHANGE");0x0219/*_WM_DEVICECHANGE*/,"当设备的硬件配置改变时,发送本消息给应用程序或设备驱动程序"
While 1
Sleep(10)
WEnd
Func _WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam);$hWnd:窗口句柄, $Msg:发送的消息类型, $wParam:32位消息的特定附加信息,确切含义依赖于消息值, $lParam:指向内存中数据的指针,通常用于存储消息所需要的对象。
Switch $wParam
Case 0x8000;设备插入
Local $_DEV_BROADCAST_HDR = DllStructCreate("int dbch_size; int dbch_devicetype; int dbch_reserved;", $lParam);创建一个 C/C++ 样式的数据结构,$lParam:指针,[可选参数] 如果指定的数据结构不能分配内存,则使用此指针参数。
If DllStructGetData($_DEV_BROADCAST_HDR, "dbch_devicetype") = 2 Then;dbch_devicetype:表示设备的类型
Local Const $DEV_BROADCAST_VOLUME = DllStructCreate("int dbcv_size; int dbcv_devicetype; int dbcv_reserved; int dbcv_unitmask; word dbcv_flags", $lParam)
Local Const $unitMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_unitmask")
$drivers = _Get_DriverFlag($unitMask);获取插入设备的盘符
MsgBox(0, "", "分区 " & $drivers & " 被插入", 2)
EndIf
Case 0x8004;设备移除
Local $_DEV_BROADCAST_HDR = DllStructCreate("int dbch_size; int dbch_devicetype; int dbch_reserved;", $lParam)
If DllStructGetData($_DEV_BROADCAST_HDR, "dbch_devicetype") = 2 Then
Local Const $DEV_BROADCAST_VOLUME_yc = DllStructCreate("int dbcv_size; int dbcv_devicetype; int dbcv_reserved; int dbcv_unitmask; word dbcv_flags", $lParam)
Local Const $unitMask_yc = DllStructGetData($DEV_BROADCAST_VOLUME_yc, "dbcv_unitmask")
$drivers = _Get_Driverflag($unitMask_yc);获取拔出设备的盘符
MsgBox(0, "", "分区 " & $drivers & " 被移除", 2)
EndIf
;文档官网:https://learn.microsoft.com/zh-c ... vio/wm-devicechange
;windows数据类型:https://learn.microsoft.com/zh-c ... /windows-data-types
;$wParam的值:
;0x0007:设备已添加到系统或从系统中删除
;0x0017:请求权限以更改当前配置(停靠或取消停靠)
;0x0018:由于停靠或取消停靠,当前配置已更改
;0x0019:已取消更改当前配置(停靠或取消停靠)的请求
;0x8000:已插入设备或介质片段,现已可用
;0x8001:请求权限以删除设备或介质。任何应用程序都可以拒绝此请求并取消删除
;0x8002:删除设备或介质的请求已取消
;0x8003:即将删除设备或介质片段。不可拒绝
;0x8004:已删除设备或介质片段
;0x8005:发生了特定于设备的事件
;0x8006:发生了自定义事件
;0xFFFF:此消息的含义是用户定义的
EndSwitch
EndFunc ;==>_WM_DEVICECHANGE
Func _Get_DriverFlag($unitMask);搭配_WM_DEVICECHANGE()使用
Local $Count = 0
Local $Pom = Round($unitMask / 2)
While $Pom > 0
$Pom = BitShift($Pom, 1)
$Count += 1
WEnd
If $Count >= 1 And $Count <= 26 Then
Return Chr(65 + $Count) & ":"
Else
Return '?'
EndIf
EndFunc ;==>_Get_DriverFlag
本帖最后由 smooth 于 2024-3-3 07:15 编辑
没搞明白,为什么没有意义?以下代码来源于论坛,其中一个函数的写法看不懂,运行报错,所以修改了。
$DBT_DEVICEARRIVAL = 0x8000
$DBT_DEVICEQUERYREMOVE = 0x8001
$DBT_DEVICEQUERYREMOVEFAILED = 0x8002
$DBT_DEVICEREMOVEPENDING = 0x8003
$DBT_DEVICEREMOVECOMPLETE = 0x8004
$DBT_DEVICETYPESPECIFIC = 0x8005
$DBT_CUSTOMEVENT = 0x8006
$DBT_DEVTYP_OEM = 0x00000000
$DBT_DEVTYP_DEVNODE = 0x00000001
$DBT_DEVTYP_VOLUME = 0x00000002
$DBT_DEVTYP_PORT = 0x00000003
$DBT_DEVTYP_NET = 0x00000004
$DEV_BROADCAST_HDR = "DWORD size;DWORD devicetype;DWORD reserved"
$DEV_BROADCAST_VOLUME = "DWORD size;DWORD devicetype;DWORD reserved;DWORD unitmask;WORD flags"
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 416, 428, 192, 132)
$List1 = GUICtrlCreateList("", 72, 40, 289, 310, BitOR($LBS_NOTIFY, $LBS_MULTIPLESEL, $LBS_DISABLENOSCROLL, $WS_VSCROLL, $WS_BORDER))
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
GUIRegisterMsg($WM_DEVICECHANGE, "WM_DEVICECHANGE")
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func WM_DEVICECHANGE($hWnd, $MsgID, $WParam, $LParam)
Switch $WParam
Case $DBT_DEVICEARRIVAL, $DBT_DEVICEREMOVECOMPLETE
$dbhdr = DllStructCreate($DEV_BROADCAST_HDR, $LParam)
$devicetype = DllStructGetData($dbhdr, "devicetype")
Switch $devicetype
Case $DBT_DEVTYP_VOLUME
$dbv = DllStructCreate($DEV_BROADCAST_VOLUME, $LParam)
$unitmask = DllStructGetData($dbv, "unitmask")
ConsoleWrite($unitmask)
For $i = 0 To 25
If BitAND(BitShift(1, -$i), $unitmask) <> 0 Then print(StringFormat("磁盘已%s,盘符为:%s:", ($WParam = $DBT_DEVICEARRIVAL ? "插入" : "删除"), Chr(Asc("A") + $i)))
Next
EndSwitch
EndSwitch
EndFunc ;==>WM_DEVICECHANGE
Func print($data)
_GUICtrlListBox_AddString($List1, $data)
_GUICtrlListBox_UpdateHScroll($List1)
EndFunc ;==>print
页:
[1]