Page 1 of 2
How do I detect removable device events
Posted: Wed May 11, 2005 11:57 am
by utopiomania
Hello!
I'm checking to see if I could move one or two programs to purebasic. One of them detects
a removable drive beeing inserted or removed from the system.
I tried with the code below, but can't get it to work. It detects a removable device message
but not the type (Insert, remove). I've tried Purebasic for a couple of days only, so I'm shure
there's some stupid mistake in there, but I can't see what it is!
Code: Select all
;GENERAL PROCEDURES
Global DeviceEvent
#WM_DEVICECHANGE=$219
#DBT_DEVICEARRIVAL=$8000 ;A device has been inserted
#DBT_DEVICEREMOVECOMPLETE=$8004 ;A device has been removed.
Procedure GetDeviceEvent(WindowID,Message,wParam,lParam)
;Callback procedure to catch a removable device event
Result = #PB_ProcessPureBasicEvents
If Message=#WM_DEVICECHANGE
DeviceEvent=wParam
EndIf
ProcedureReturn Result
EndProcedure
;MAIN WINDOW AND CONTROLS
;Main window flags
Flags=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Flags=Flags|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
;Open the main window
If OpenWindow(0,0,0,600,400,Flags,"Removable device test")=0
MessageRequester("","Error",#PB_MessageRequester_Ok)
End
EndIf
;Set the callback to catch a removable device event
SetWindowCallback(@GetDeviceEvent())
;MAIN WINDOW EVENT LOOP
Repeat
Event=WaitWindowEvent()
Select Event
Case #WM_DEVICECHANGE
Select DeviceEvent
Case #DBT_DEVICEARRIVAL
MessageRequester("","Inserted",#PB_MessageRequester_Ok)
Case #DBT_DEVICEREMOVECOMPLETE
MessageRequester("","Removed",#PB_MessageRequester_Ok)
EndSelect
Case #PB_Event_CloseWindow
;Program closed
Exit=1
EndSelect
Until Exit
Posted: Wed May 11, 2005 2:27 pm
by Sparkie
Welcome to PB utopiomania
See if this works for you...
Code: Select all
;GENERAL PROCEDURES
#WM_DEVICECHANGE=$219
#DBT_DEVICEARRIVAL=$8000 ;A device has been inserted
#DBT_DEVICEREMOVECOMPLETE=$8004 ;A device has been removed.
Procedure GetDeviceEvent(WindowID,Message,wParam,lParam)
;Callback procedure to catch a removable device event
result = #PB_ProcessPureBasicEvents
If Message=#WM_DEVICECHANGE
result = #True
Select wParam
Case #DBT_DEVICEARRIVAL
MessageRequester("","Inserted",#PB_MessageRequester_Ok)
Case #DBT_DEVICEREMOVECOMPLETE
MessageRequester("","Removed",#PB_MessageRequester_Ok)
EndSelect
EndIf
ProcedureReturn result
EndProcedure
;MAIN WINDOW AND CONTROLS
;Main window flags
Flags=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Flags=Flags|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
;Open the main window
If OpenWindow(0,0,0,600,400,Flags,"Removable device test")=0
MessageRequester("","Error",#PB_MessageRequester_Ok)
End
EndIf
;Set the callback to catch a removable device event
SetWindowCallback(@GetDeviceEvent())
;MAIN WINDOW EVENT LOOP
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
;Program closed
Exit=1
EndSelect
Until Exit
Posted: Wed May 11, 2005 4:46 pm
by utopiomania
Thanks for the help!

Your sample does exactly what I was trying to do. The only thing was that the
compiler complained about #True, which it couldn't find, so I removed that line (Return=#True), with no ill effects.
Posted: Wed May 11, 2005 7:00 pm
by bingo
any way for DEV_BROADCAST_HDR to detect dbch_devicetype ? :roll:
Posted: Thu May 12, 2005 3:33 am
by Sparkie
bingo wrote:any way for DEV_BROADCAST_HDR to detect dbch_devicetype ?
I did some reading and added to the original code and came up with the following. I only tested (on WinXP) the opening and closing of my cd tray, so the rest may or may not work.
Code: Select all
;GENERAL PROCEDURES
#WM_DEVICECHANGE=$219
#DBT_DEVICEARRIVAL=$8000 ;A device has been inserted
#DBT_DEVICEREMOVECOMPLETE=$8004 ;A device has been removed.
#DBT_DEVTYP_DEVICEINTERFACE = 5
#DBT_DEVTYP_HANDLE = 6
#DBT_DEVTYP_OEM = 0
#DBT_DEVTYP_PORT = 3
#DBT_DEVTYP_VOLUME = 2
#DBTF_MEDIA = 1
#DBTF_NET = 2
Procedure GetDeviceEvent(WindowID,Message,wParam,lParam)
;Callback procedure to catch a removable device event
result = #PB_ProcessPureBasicEvents
If Message=#WM_DEVICECHANGE
result = #True
Select wParam
Case #DBT_DEVICEARRIVAL
MessageRequester("WM_DEVICECHANGE","DBT_DEVICEARRIVAL",#PB_MessageRequester_Ok)
Case #DBT_DEVICEREMOVECOMPLETE
MessageRequester("WM_DEVICECHANGE","DBT_DEVICEREMOVECOMPLETE",#PB_MessageRequester_Ok)
EndSelect
*pDBHDR.DEV_BROADCAST_HDR=lParam
Select *pDBHDR\dbch_devicetype
Case #DBT_DEVTYP_OEM
*pDBO.DEV_BROADCAST_OEM=lParam
oemID = *pDBO\dbco_identifier
MessageRequester("Device Change Info","dbco_identifier: " + Str(oemID),#PB_MessageRequester_Ok)
Case #DBT_DEVTYP_PORT
*pDBP.DEV_BROADCAST_PORT=lParam
portName$ = PeekS(*pDBP\dbcp_name)
MessageRequester("Device Change Info","dbcp_name : " + portName$,#PB_MessageRequester_Ok)
Case #DBT_DEVTYP_VOLUME
*pDBV.DEV_BROADCAST_VOLUME=lParam
Select *pDBV\dbcv_flags
Case #DBTF_MEDIA
MessageRequester("Device Change Info","DBTF_MEDIA",#PB_MessageRequester_Ok)
Case #DBTF_NET
MessageRequester("Device Change Info","DBTF_NET",#PB_MessageRequester_Ok)
EndSelect
EndSelect
EndIf
ProcedureReturn result
EndProcedure
;MAIN WINDOW AND CONTROLS
;Main window flags
Flags=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Flags=Flags|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
;Open the main window
If OpenWindow(0,0,0,600,400,Flags,"Removable device test")=0
MessageRequester("","Error",#PB_MessageRequester_Ok)
End
EndIf
;Set the callback to catch a removable device event
SetWindowCallback(@GetDeviceEvent())
;MAIN WINDOW EVENT LOOP
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
;Program closed
Exit=1
EndSelect
Until Exit
@utopiomania: If result = #True is barking at you, then you may want to investigate. #True / #False are native PB constants and should work at all times.
Code: Select all
Debug #True ; should return 1
Debug #False ; should return 0
Posted: Thu May 12, 2005 4:38 pm
by utopiomania
Sparkie wrote:
If result = #True is barking at you, then you may want to investigate.
I uninstalled, then downloaded a new demo and reinstalled, with the same result:
'Line X, Constant not found: #True'.

Posted: Thu May 12, 2005 6:10 pm
by Sparkie
I just tried the demo myself and I get the same constant not found. In the full version of PB, #True = 1 and #False = 0.
I guess I was wrong about #True and #False being native PB constants, sorry about that.

Posted: Thu May 12, 2005 6:29 pm
by utopiomania
I'm not shure if you were wrong about that, they (#True, #False) do appear in several samples in the help doc's. Anyways, it's a minor problem.

Re: How do I detect removable device events
Posted: Mon Jul 11, 2011 9:33 am
by Oliver13
Thank you for this useful code snippet.
Regrettably, there seem to be an error:
the device event is recognized properly and also the pDBHDR.DEV_BROADCAST structure will be filled.
But in the following line, there occurs an IMA; the *pDBP.DEV_BROADCAST_PORT structure remains empty
Code: Select all
Case #DBT_DEVTYP_PORT
*pDBP.DEV_BROADCAST_PORT=lParam
Can anybody help ?
TX
Oli
Re: How do I detect removable device events
Posted: Tue Jul 12, 2011 2:21 am
by PureLust
Oliver13 wrote:Can anybody help ?
I've made some slight changes - works fine for me now.
But because I don't have a Port-Device, I cannot test the part which was relevant for you.
So ... could you please test, if this version works fine for you as well?
Code: Select all
;GENERAL PROCEDURES
#WM_DEVICECHANGE=$219
#DBT_DEVICEARRIVAL=$8000 ;A device has been inserted
#DBT_DEVICEREMOVECOMPLETE=$8004 ;A device has been removed.
#DBT_DEVTYP_DEVICEINTERFACE = 5
#DBT_DEVTYP_HANDLE = 6
#DBT_DEVTYP_OEM = 0
#DBT_DEVTYP_PORT = 3
#DBT_DEVTYP_VOLUME = 2
#DBTF_MEDIA = 1
#DBTF_NET = 2
Procedure GetDeviceEvent(WindowID,Message,wParam,lParam)
;Callback procedure to catch a removable device event
Protected ValidEvent = #False
result = #PB_ProcessPureBasicEvents
If Message=#WM_DEVICECHANGE
result = #True
Select wParam
Case #DBT_DEVICEARRIVAL
MessageRequester("WM_DEVICECHANGE","DBT_DEVICEARRIVAL",#PB_MessageRequester_Ok)
ValidEvent = #True
Case #DBT_DEVICEREMOVECOMPLETE
MessageRequester("WM_DEVICECHANGE","DBT_DEVICEREMOVECOMPLETE",#PB_MessageRequester_Ok)
ValidEvent = #True
EndSelect
If ValidEvent = #True
*pDBHDR.DEV_BROADCAST_HDR=lParam
Select *pDBHDR\dbch_devicetype
Case #DBT_DEVTYP_OEM
*pDBO.DEV_BROADCAST_OEM=lParam
oemID = *pDBO\dbco_identifier
MessageRequester("Device Change Info","dbco_identifier: " + Str(oemID),#PB_MessageRequester_Ok)
Case #DBT_DEVTYP_PORT
*pDBP.DEV_BROADCAST_PORT=lParam
portName$ = PeekS(*pDBP + OffsetOf(DEV_BROADCAST_PORT\dbcp_name))
MessageRequester("Device Change Info","dbcp_name : " + portName$,#PB_MessageRequester_Ok)
Case #DBT_DEVTYP_VOLUME
*pDBV.DEV_BROADCAST_VOLUME=lParam
Select *pDBV\dbcv_flags
Case #DBTF_MEDIA
MessageRequester("Device Change Info","DBTF_MEDIA",#PB_MessageRequester_Ok)
Case #DBTF_NET
MessageRequester("Device Change Info","DBTF_NET",#PB_MessageRequester_Ok)
EndSelect
Case #DBT_DEVTYP_DEVICEINTERFACE
MessageRequester("Device Change Info","#DBT_DEVTYP_DEVICEINTERFACE",#PB_MessageRequester_Ok)
Case #DBT_DEVTYP_HANDLE
MessageRequester("Device Change Info","#DBT_DEVTYP_HANDLE",#PB_MessageRequester_Ok)
EndSelect
EndIf
EndIf
ProcedureReturn result
EndProcedure
;MAIN WINDOW AND CONTROLS
;Main window flags
Flags=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Flags=Flags|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
;Open the main window
If OpenWindow(0,0,0,600,400,"Removable device test",Flags)=0
MessageRequester("","Error",#PB_MessageRequester_Ok)
End
EndIf
;Set the callback to catch a removable device event
SetWindowCallback(@GetDeviceEvent())
;MAIN WINDOW EVENT LOOP
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
;Program closed
Exit=1
EndSelect
Until Exit
Greetz, PL.
Re: How do I detect removable device events
Posted: Tue Jul 12, 2011 4:29 am
by netmaestro
What you have there seems to work fine here on W7, flagging the inserts and removals of a USB thumbdrive.
Re: How do I detect removable device events
Posted: Tue Jul 12, 2011 9:43 pm
by Oliver13
Thank you very much, this was the solution !
best regards
Oliver
Re: How do I detect removable device events
Posted: Wed Jul 13, 2011 6:02 pm
by Kwai chang caine
Works fine on XP SP3; MsgBox when Insert and Remove USB Key
Thanks for sharing

Re: How do I detect removable device events
Posted: Thu Jul 14, 2011 12:05 am
by PureLust
Hey guys,
thanks for testing.
Good to know, that it works for others as well.
Greetz, PL.
Re: How do I detect removable device events
Posted: Mon Jan 14, 2019 1:40 am
by AZJIO
Code: Select all
#WM_DEVICECHANGE=$219
#DBT_DEVICEARRIVAL=$8000 ;A device has been inserted
#DBT_DEVICEREMOVECOMPLETE=$8004 ;A device has been removed.
#DBT_DEVTYP_VOLUME = 2
Procedure GetDeviceEvent(WindowID,Message,wParam,lParam)
;Callback procedure to catch a removable device event
Protected result, Mask, Drive.s
result = #PB_ProcessPureBasicEvents
If Message=#WM_DEVICECHANGE
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
Mask = Log(Mask) / Log(2)
Drive.s = Chr(65 + Mask) + ":"
Select wParam
Case #DBT_DEVICEARRIVAL
SetWindowTitle(0 , "Inserted, " + Drive.s)
Case #DBT_DEVICEREMOVECOMPLETE
SetWindowTitle(0 , "Removed " + Drive.s)
EndSelect
EndIf
EndSelect
EndIf
ProcedureReturn result
EndProcedure
Flags=#PB_Window_SystemMenu|#PB_Window_ScreenCentered
Flags=Flags|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
;Open the main window
OpenWindow(0,0,0,500,100,"Removable device test",Flags)
;Set the callback to catch a removable device event
SetWindowCallback(@GetDeviceEvent())
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow