Описание функции
WM_DEVICECHANGE
Сообщение выполняется при подключении или отключении устройств к системе.
Параметры
Указанные параметры передаются системой.wParam | Содержит флаг подключения или отключения устройства DBT_DEVICEARRIVAL = $8000 ; Новое устройство подключено и готово к использованию DBT_DEVICEQUERYREMOVE = $8001 ; Запрос на удаление устройства. Любое приложение может отменить удаление. Чтобы разрешить удаление, надо вернуть TRUE. Чтобы отменить удаление, надо вернуть BROADCAST_QUERY_DENY DBT_DEVICEQUERYREMOVEFAILED = $8002 ; Удаление устройства прервано DBT_DEVICEREMOVEPENDING = $8003 ; Устройство сейчас будет удалено. Нельзя отменить удаление. Возвращает TRUE. DBT_DEVICEREMOVECOMPLETE = $8004 ; Устройство отключено DBT_DEVICETYPESPECIFIC = $8005 ; type specific event DBT_DEVNODES_CHANGED = $0007 ; любое изменение в аппаратном профиле |
lParam |
Указатель на структуру Структура DEV_BROADCAST_HDR задаёт тип устройств для отслеживания dbch_size - размер структуры в байтах. dbch_devicetype - тип устройства, например DBT_DEVTYP_VOLUME - логический раздел DBT_DEVTYP_OEM = $00000000 ; oem-defined device type DBT_DEVTYP_DEVNODE = $00000001 ; devnode number DBT_DEVTYP_VOLUME = $00000002; логический раздел DBT_DEVTYP_PORT = $00000003 ; serial, parallel DBT_DEVTYP_NET = $00000004 ; network resource dbch_reserved - зарезервировано, не используется или структура DEV_BROADCAST_VOLUME, если dbch_devicetype возвращает DBT_DEVTYP_VOLUME dbch_size - размер структуры в байтах. dbch_devicetype - тип устройства (тоже что выше указанные) dbch_reserved - зарезервировано, не используется dbcv_unitmask - битовая маска, соответствие числа (бита) с буквой диска 0 = A 1 = B ... 26 = Z dbcv_flags - флаг Для отслеживания всех устройств поле dbch_devicetype должно быть равен значению DBT_DEVTYP_DEVICEINTERFACE и включать DEVICE_NOTIFY_ALL_INTERFACE_CLASSES для получения сообщений об изменении всех классов устройств. |
Примечания
Смотрите функцию SetWindowCallback.Пример
EnableExplicit
#Windows_0 = 0
#SysTrayIcon_0 = 0
#Menu = 0
Enumeration
#About
#Exit
EndEnumeration
Global ExeDir$, hWin_0, drives_avail, Letters$, MarkFileName$
Global StartDisk = 2
; Executable file (disk marker file)
MarkFileName$ = "Start.exe"
ExeDir$ = GetCurrentDirectory()
; here you need a code to prevent the program from restarting
Define *a = CreateSemaphore_(#Null, 0, 1, "USB5671230")
If *a And GetLastError_() = #ERROR_ALREADY_EXISTS
CloseHandle_(*a)
; MessageRequester("","The program is already running") ; optional, but you can report that the program is already running
End
EndIf
Procedure Exit()
RemoveSysTrayIcon(#SysTrayIcon_0)
CloseWindow(#Windows_0)
End
EndProcedure
Procedure Add_drive(Mask.l)
Protected i, CurLetter$
For i = StartDisk To 25
If ((Mask >> i) & 1) ; check each flag
CurLetter$ = Chr(i + 65)
; Reaction to marker file
If FileSize(CurLetter$ + ":\" + MarkFileName$) >= 0
RunProgram(CurLetter$ + ":\" + MarkFileName$)
EndIf
Letters$ + CurLetter$
EndIf
Next
Debug Letters$
EndProcedure
Procedure Del_drive(Mask.l)
Protected k, Count, CurLetter$, title.s;, z
Count = Len(Letters$)
For k = Count To 1 Step -1
CurLetter$ = Mid(Letters$, k, 1)
If (Mask >> (Asc(CurLetter$) - 65)) & 1
Letters$ = ReplaceString(Letters$, CurLetter$, "", #PB_String_NoCase, k, 1)
; RunProgram("cmd.exe", "/c (taskkill /im " + MarkFileName$ + ")", "")
EndIf
Next
Debug Letters$
EndProcedure
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents, Mask, Drive.s, *pDBHDR.DEV_BROADCAST_HDR, *pDBV.DEV_BROADCAST_VOLUME
Protected tmp
Select uMsg
; Case #WM_UNINITMENUPOPUP
; Debug "PopupMenu был закрыт."
Case #WM_DEVICECHANGE ; Change when connecting external drives.
Result = #True
Select wParam
Case #DBT_DEVICEARRIVAL, #DBT_DEVICEREMOVECOMPLETE
*pDBHDR.DEV_BROADCAST_HDR=lParam
If *pDBHDR\dbch_devicetype = #DBT_DEVTYP_VOLUME
*pDBV.DEV_BROADCAST_VOLUME=lParam
Mask = *pDBV\dbcv_unitmask
Select wParam
Case #DBT_DEVICEARRIVAL
; Debug Bin(drives_avail)
; Debug Bin(Mask)
tmp = drives_avail
drives_avail | Mask
If tmp <> drives_avail
Add_drive(Mask)
EndIf
Case #DBT_DEVICEREMOVECOMPLETE
drives_avail ! (Mask & drives_avail)
Del_drive(Mask)
EndSelect
EndIf
EndSelect
EndSelect
ProcedureReturn Result
EndProcedure
hWin_0 = OpenWindow(#Windows_0, 0, 0, 200, 20, "", #PB_Window_Invisible)
AddSysTrayIcon(#SysTrayIcon_0, hWin_0, GetClassLongPtr_(hWin_0, #GCL_HICON))
; AddSysTrayIcon(#SysTrayIcon_0, WindowID(0), LoadImage(0, ExeDir$ + "2.ico"))
SysTrayIconToolTip(#SysTrayIcon_0, "Surveillance")
CreatePopupMenu(#Menu)
MenuItem(#Exit, "Exit")
BindMenuEvent(#Menu, #Exit, @Exit())
SetWindowCallback(@WinCallback())
Repeat
Select WaitWindowEvent()
Case #PB_Event_SysTray
Select EventType()
Case #PB_EventType_RightClick
DisplayPopupMenu(#Menu, hWin_0)
EndSelect
Case #PB_Event_CloseWindow
Exit()
EndSelect
ForEver
Exit()