How do I detect removable device events

Just starting out? Need help? Post your questions and find answers here.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

How do I detect removable device events

Post 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
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post 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
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post 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.
User avatar
bingo
Enthusiast
Enthusiast
Posts: 210
Joined: Fri Apr 02, 2004 12:21 pm
Location: germany/thueringen
Contact:

Post by bingo »

any way for DEV_BROADCAST_HDR to detect dbch_devicetype ? :roll:
["1:0>1"]
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post 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
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post 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'. :?:
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post 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. :oops:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post 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. :)
Oliver13
User
User
Posts: 82
Joined: Thu Sep 30, 2010 6:40 am

Re: How do I detect removable device events

Post 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
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Re: How do I detect removable device events

Post 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.
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How do I detect removable device events

Post by netmaestro »

What you have there seems to work fine here on W7, flagging the inserts and removals of a USB thumbdrive.
BERESHEIT
Oliver13
User
User
Posts: 82
Joined: Thu Sep 30, 2010 6:40 am

Re: How do I detect removable device events

Post by Oliver13 »

Thank you very much, this was the solution !

best regards
Oliver
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: How do I detect removable device events

Post by Kwai chang caine »

Works fine on XP SP3; MsgBox when Insert and Remove USB Key :D
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Re: How do I detect removable device events

Post by PureLust »

Hey guys,

thanks for testing. :wink:
Good to know, that it works for others as well.

Greetz, PL.
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)
AZJIO
Addict
Addict
Posts: 1312
Joined: Sun May 14, 2017 1:48 am

Re: How do I detect removable device events

Post 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
Post Reply