模仿磁盘管理显示接入硬盘-已解决
本帖最后由 rally 于 2021-1-26 21:03 编辑想做个类似磁盘管理监控多块硬盘拔插,像磁盘管理一样实时更新列表。奈何菜鸟还不知道从哪入手。参考了"CoProc.au3“多进程处理方式。总不完美,
#NoTrayIcon
#include "CoProc.au3"
#region 主程序区域
#include <GUIConstants.au3>
$Form1 = GUICreate("Multiple File Download", 622, 300, 192, 300)
$label1 = GUICtrlCreateLabel("现在接入硬盘数量:",5,5,140,30)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
$label2 = GUICtrlCreateLabel("0",145,5,120,30)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
$edit = GUICtrlCreateEdit("",50,50,400,220,$ES_AUTOHSCROLL)
$Button1 = GUICtrlCreateButton("写入随机数据", 480, 120, 81, 25)
$Button2 = GUICtrlCreateButton("Test",480, 60, 81, 25)
$iPidSmall = _CoProc("Small") ;开启子进程,子进程将执行Small()函数,$iPidSmall得到的是子进程的PID
GUISetState(@SW_SHOW)
_CoProcReciver("Reciver") ;注册Reciver()函数来接收子进程传递过来的消息
While 1
$msg = GuiGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
ExitLoop
AdlibUnRegister("Reciver")
Case $msg = $Button1
For $i=1 to 20
$n = Random(1,999)
GUICtrlSetData($edit,$n & @CRLF,'')
Next
Case $msg = $Button2
MsgBox(0,"","Test ok")
EndSelect
WEnd
FileDelete(@TempDir & "\smalltest.tmp")
FileDelete(@TempDir & "\bigtest.tmp")
Exit
Func Reciver($vParameter)
GUICtrlSetData($label2,$vParameter)
EndFunc
#endregion
Func Small()
While 1
Local $objWMI = ObjGet('Winmgmts:{ImpersonationLevel=Impersonate,AuthenticationLevel=PktPrivacy,(Debug)}!\\.\root\CIMV2')
Local $objClass = $objWMI.InstancesOf('Win32_DiskDrive')
Local $count = $objClass.Count
_CoProcSend($gi_CoProcParent,$count)
sleep(200)
WEnd
EndFunc
这个既不用多进程,更不用循环检测。注册 WM_DEVICECHANGE 消息,简单几行代码。 afan 发表于 2021-1-25 20:54
这个既不用多进程,更不用循环检测。注册 WM_DEVICECHANGE 消息,简单几行代码。
我查了WM_DEVIECECHANGE,好像要HOOK到界面才行,无奈看不懂,能不能指点一下几行代码学习一下。麻烦版主大大 上次也是查自动获取U盘提示的,也有看到afan大大提到WM_DEVIECECHANGE,没有学习到 GUICreate('磁盘监控')
Global $iLb = GUICtrlCreateLabel('', 50, 10, 300, 20, 0x201)
Global $iEdit = GUICtrlCreateEdit('', 50, 30, 300, 320)
_DeviceInfo()
GUISetState()
GUIRegisterMsg(537, '_WM_DEVICECHANGE')
While GUIGetMsg() <> -3
WEnd
Exit
Func _DeviceInfo()
Local $iMask = DllCall('kernel32.dll', 'dword', 'GetLogicalDrives')
Local $td = DllStructCreate('dword;dword;int')
Local $hDevice, $aRt, $nDrive, $nMax, $sInfo = ''
For $ii = 0 To 25
If Not BitAND(BitShift($iMask, $ii), 1) Then ContinueLoop
$aRt = DllCall('kernel32.dll', 'hwnd', 'CreateFile', 'str', '\\.\' & Chr(65 + $ii) & ':', 'dword', 0, 'dword', 0, 'ptr', 0, 'dword', 3, 'dword', 128, 'ptr', 0)
$hDevice = $aRt
DllCall('kernel32.dll', 'int', 'DeviceIoControl', 'hwnd', $hDevice, 'dword', 0x2D1080, 'ptr', 0, 'dword', 0, 'ptr', DllStructGetPtr($td), 'dword', DllStructGetSize($td), 'dword*', 0, 'ptr', 0)
DllCall('kernel32.dll', 'int', 'CloseHandle', 'hwnd', $hDevice)
$nDrive = DllStructGetData($td, 2)
If $nMax < $nDrive Then $nMax = $nDrive
$sInfo &= Chr(65 + $ii) & ': 硬盘 ' & $nDrive & ', 分区 ' & DllStructGetData($td, 3) & @CRLF
Next
GUICtrlSetData($iLb, '当前接入硬盘数量:' & $nMax + 1)
GUICtrlSetData($iEdit, $sInfo)
GUICtrlSetState($iLb, 256)
EndFunc ;==>_DeviceInfo
Func _WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam)
Switch $wParam
Case 0x8000, 0x8004
_DeviceInfo()
EndSwitch
EndFunc ;==>_WM_DEVICECHANGE
模仿磁盘管理显示接入硬盘 - 已解决
本帖最后由 rally 于 2021-1-26 13:17 编辑非常感谢版主大大,好好学习一下:face (10): 本帖最后由 rally 于 2021-1-26 16:20 编辑
afan 发表于 2021-1-25 22:31
版主大大,我在测试的时候,发现,如果硬盘没有分区,接上去是不会有显示的,这个WM_DEVICECHANGE只能检测已经分区的硬盘吗? rally 发表于 2021-1-26 16:18
版主大大,我在测试的时候,发现,如果硬盘没有分区,接上去是不会有显示的,这个WM_DEVICECHANGE只能检 ...
消息应该都是有的,只是获取磁盘信息是通过盘符逐盘获取的,不然哪来的对应信息。
没有未分区的磁盘,无法测试。也不知道获取未分区磁盘的意义,难不成还想操作分区格式化… 如此也犯不着检测消息那么及时,直接干就是了 嗯,后面我又尝试了一下,在不加 Switch $wParam Case 0x8000, 0x8004 情况下,只要有消息就判断一下是不是硬盘接入,这样没那么直接,也能达到效果。谢谢版主大大的关照
页:
[1]