detect USB Device arrive/remove : how to use with harbour / HMG

Discuss anything else that does not suite other forums.

Moderator: Rathinagiri

User avatar
AUGE_OHR
Posts: 326
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 34 times
Been thanked: 42 times

detect USB Device arrive/remove : how to use with harbour / HMG

Post by AUGE_OHR » Fri Nov 08, 2019 10:32 pm

hi,

i have this Code with Xbase++ and Ot4xb

Code: Select all

   delegated_eval( { || ot4xb_CreateGenericWindow( MyVolHandler( oDlg ) ) } )

#define WM_DEVICECHANGE             0x0219
#define DBT_DEVICEARRIVAL           0x8000  // A device or piece of media has been inserted and is now available.
#define DBT_DEVICEQUERYREMOVE       0x8001  // Permission is requested to remove a device or piece of media. Any application can deny this request and cancel the removal.
#define DBT_DEVICEREMOVECOMPLETE    0x8004  // A device or piece of media has been removed.
#define DBT_DEVNODES_CHANGED        0x0007  // A device has been added to or removed from the system.
#define DBT_DEVTYP_VOLUME           2

CLASS MyVolHandler
EXPORTED:
   CLASS VAR oMain

INLINE METHOD init( oParent )
      ::oMain := oParent
RETURN self

INLINE CLASS METHOD wndproc( hWnd, nMsg, wp, lp, ctx )
LOCAL devType
LOCAL nRet    := 0
LOCAL bError

   IF nMsg == WM_DEVICECHANGE
      DO CASE
         CASE wp == DBT_DEVICEARRIVAL
            bError  := ErrorBlock( {|e| Break(e) } )
            BEGIN SEQUENCE
               devType := PeekDWord( lp, 4 )
               IF devType == DBT_DEVTYP_VOLUME
                  nRet := ::OnNewVolume( hWnd, PeekDWord( lp, 12 ), PeekWord( lp, 16 ) )
                  IF nRet > 0
                     PostAppEvent(xbeSD_Arrive,nRet,,::oMain)
                  ENDIF
               ENDIF
            END SEQUENCE
            ERRORBLOCK( bError )
            RETURN NIL

         CASE wp == DBT_DEVICEQUERYREMOVE

         CASE wp == DBT_DEVICEREMOVECOMPLETE
            bError  := ErrorBlock( {|e| Break(e) } )
            BEGIN SEQUENCE
               devType := PeekDWord( lp, 4 )
               IF devType == DBT_DEVTYP_VOLUME
                  nRet := ::OnRemoveVolume( hWnd, PeekDWord( lp, 12 ), PeekWord( lp, 16 ) )
                  PostAppEvent(xbeSD_Remove,nRet,,::oMain)
               ENDIF
            END SEQUENCE
            ERRORBLOCK( bError )
            RETURN NIL

         CASE wp == DBT_DEVNODES_CHANGED

      ENDCASE
      RETURN NIL
   ENDIF
RETURN NIL
it detect when plug-in USB Device or when remove.

but how to write it for harbour / HMG :?:

User avatar
danielmaximiliano
Posts: 2183
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Has thanked: 187 times
Been thanked: 29 times
Contact:

Post by danielmaximiliano » Sat Nov 09, 2019 1:40 pm

*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`.HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. : +54901169026142
Telegram Name : DaNiElMaXiMiLiAnO

User avatar
AUGE_OHR
Posts: 326
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 34 times
Been thanked: 42 times

Post by AUGE_OHR » Sat Nov 09, 2019 5:54 pm

hi,
THX for link but that Code does not "detect" when plugin or remove USB-Stick into PC, or :?:

i want to have Control when somebody put a USB-Stick into PC.
USB_Eject.jpg
USB_Eject.jpg (44.72 KiB) Viewed 533 times
if USB-Stick is "unknown" than it just "eject" USB-Stick.
if Serial-Number is know than a "Action" can be perform e.g. Backup

i have search in Forum for WM_DEVICECHANGE but not found so i guess it is "new".
but how do it in harbour / HMG ... need Advice please.

---

my Problem is to get into Windows Event Loop where i use delegated_eval() from Ot4xb

Code: Select all

XPPRET XPPENTRY DELEGATED_EVAL( XppParamList pl)
{
   ContainerHandle   conr = _delegated_xbase_call_(pl,"EVAL");
   _conReturn(pl,conr);
   _conRelease(conr);
}

HWND OT4XB_API __cdecl _ot4xb_get_hwnd_delegate_(void){return _hWndDelegate_;}
void OT4XB_API __cdecl _ot4xb_set_hwnd_delegate_(HWND hWnd){_hWndDelegate_ = hWnd;}

// -----------------------------------------------------------------------------------------------------------------
static ContainerHandle _delegated_xbase_call_( XppParamList pl , LPSTR pFName , ULONG nParamShift = 0, HWND hwnd_target = 0)
{
   ContainerHandle   conr = _conNew(NULLCONTAINER);
   if( hwnd_target == 0 )
   {
      if( _hWndDelegate_ == 0 )
      {
         _conEvalMacroStr( conr , "OT4XB_REGISTER_DELEGATE_HWND()" );
         _conPut(conr,NULLCONTAINER);
      }
      hwnd_target = _hWndDelegate_; 
   }
   if( hwnd_target == 0 )
   {
      TXbGenError e;
      e.subsystem( "OT4XB" );
      e.description("OT4XB Delegate Wnd is not defined");
      e.operation( __FUNCTION__ );
      e.Launch();
   }
   else
   {
      ULONG             np     = _partype(pl,0);
      ContainerHandle*  pcon;
      BOOL *            pbref;
      ULONG n;
      DWORD pdw[4];
      if( np <  nParamShift){np = 0;}
      else { np -= nParamShift; }
      pcon   = (ContainerHandle*) _xgrab( (np +1 ) * sizeof(ContainerHandle));
      pbref  = (BOOL*) _xgrab( (np+1) * sizeof(BOOL));
      for(n=0;n < np; n++) pcon[n] = _conParam(pl,n+1+nParamShift,pbref+n);
      pdw[0] = (DWORD) (void*) conr;
      pdw[1] = (DWORD) (void*) pFName;
      pdw[2] = np;
      pdw[3] = (DWORD) (void*) pcon;
      SendMessage( hwnd_target , _nMsgDelegate_ , 0 , (LPARAM) (void*) pdw );
      for(n=0;n < np; n++){if(!(pbref[n])) _conRelease(pcon[n]);}
      _xfree( (void*) pcon); _xfree( (void*) pbref);
   }
   return conr;
} 

User avatar
danielmaximiliano
Posts: 2183
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Has thanked: 187 times
Been thanked: 29 times
Contact:

Post by danielmaximiliano » Sun Nov 10, 2019 1:02 am

*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`.HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. : +54901169026142
Telegram Name : DaNiElMaXiMiLiAnO

User avatar
danielmaximiliano
Posts: 2183
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Has thanked: 187 times
Been thanked: 29 times
Contact:

Post by danielmaximiliano » Sun Nov 10, 2019 1:04 am

*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`.HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. : +54901169026142
Telegram Name : DaNiElMaXiMiLiAnO

User avatar
AUGE_OHR
Posts: 326
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 34 times
Been thanked: 42 times

Post by AUGE_OHR » Sun Nov 10, 2019 9:10 am

hi

Thx for Link.

my Code is working under Xbase++ using Ot4xb so it is not "how" to do it
it is harbour / HMG that i have to learn how i can access Windows Message.

---

i need access to "Top" Windows Event loop.
what i need is a Callback Slot to use a Codeblock like bOnDeviceChange

i saw c:\hmg.3.4.4\SOURCE\c_EventCB.c and HB_FUNC(DOEVENTS) in c:\hmg.3.4.4\SOURCE\h_windows.prg
so i have include this into

Code: Select all

function Events ( hWnd, nMsg, wParam, lParam )
   ...
   case nMsg == WM_DEVICECHANGE
      DO CASE
         CASE wParam == DBT_DEVICEARRIVAL
            MessageBox(hWnd, "A device has been inserted.", "USB Notice", MB_OK)
         CASE wParam == DBT_DEVICEQUERYREMOVE

         CASE wParam == DBT_DEVICEREMOVECOMPLETE
            MessageBox(hWnd, "A device has been removed.", "USB Notice", MB_OK)
      ENDCASE

   endcase

return (0)  // EOF function Events 
HMG_USB_arrive.JPG
HMG_USB_arrive.JPG (43.75 KiB) Viewed 489 times
---

as you see it work ... ok Mssagebox() is twice but now i want to know what Type insert Device have.

i can use DEV_BROADCAST_HDR Structrure
https://docs.microsoft.com/en-us/window ... adcast_hdr
or direct read DWORD

Problem :

HMG have
PEEKWORD()
Reads a 16-bit word from memory
so it is equal to Ot4xb
PeekWord()
Retrieve the value of one or more WORDs from the memory buffer pointed by <pMem> starting at the position <nShift>.
but what about DWORD
PeekDWord()
Retrieve the value of one or more DWORDs from the memory buffer pointed by <pMem> starting at the position <nShift>.
so how read DWORD with harbour / HMG :?:

---

when i put it into function Events it will react in every Top Windows ...

so how do it better for just the App where i want it :?:

edk
Posts: 519
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 137 times
Been thanked: 440 times

Post by edk » Sun Nov 10, 2019 12:53 pm

AUGE_OHR wrote:
Sun Nov 10, 2019 9:10 am
i saw c:\hmg.3.4.4\SOURCE\c_EventCB.c and HB_FUNC(DOEVENTS) in c:\hmg.3.4.4\SOURCE\h_windows.prg
so i have include this into

Code: Select all

function Events ( hWnd, nMsg, wParam, lParam )
   ...
   case nMsg == WM_DEVICECHANGE
      DO CASE
         CASE wParam == DBT_DEVICEARRIVAL
            MessageBox(hWnd, "A device has been inserted.", "USB Notice", MB_OK)
         CASE wParam == DBT_DEVICEQUERYREMOVE

         CASE wParam == DBT_DEVICEREMOVECOMPLETE
            MessageBox(hWnd, "A device has been removed.", "USB Notice", MB_OK)
      ENDCASE

   endcase

return (0)  // EOF function Events 
---

when i put it into function Events it will react in every Top Windows ...

so how do it better for just the App where i want it :?:
You don't need make changes in h_windows.prg. You can create your own event procedure:

Code: Select all

/*
* HMG This Demo
* (c) 2003 Roberto Lopez
*/

#include "hmg.ch"

Function Main
Local nIndex

	DEFINE WINDOW Form_1 ;
		AT 0,0 ;
		WIDTH 400 ;
		HEIGHT 200 ;
		TITLE 'This Demo' ;
		MAIN ;
		ON INIT ThisWindow.Title := 'New Title'

		@ 10,10 BUTTON Button_1 ;
			CAPTION 'Hi!!!' ;
			ACTION ThisTest() ;
			TOOLTIP 'Test Tip'

		@ 40,10 BUTTON Button_2 ;
			CAPTION 'Release' ;
			ACTION ThisWindow.Release 

	END WINDOW

	CREATE EVENT PROCNAME USB_Detect() HWND Form_1.HANDLE STOREINDEX nIndex
	
	CENTER WINDOW Form_1

	ACTIVATE WINDOW Form_1

Return

Procedure ThisTest()

	This.Caption  := 'New Caption'

	ThisWindow.Row := 10
	ThisWindow.Col := 10
	ThisWindow.Width := 200
	ThisWindow.Height := 100

Return

FUNCTION USB_Detect()
LOCAL  nHWnd := EventHWND ()
LOCAL  nMsg := EventMSG ()
LOCAL  nWParam := EventWPARAM ()
LOCAL  nLParam := EventLPARAM ()

#define WM_DEVICECHANGE 0x0219
#define DBT_DEVICEARRIVAL 0x8000
#define DBT_DEVICEQUERYREMOVE 0x8001
#define DBT_DEVICEQUERYREMOVEFAILED 0x8002
#define DBT_DEVICEREMOVEPENDING 0x8003
#define DBT_DEVICEREMOVECOMPLETE 0x8004 

DO CASE 
	CASE nMsg == WM_DEVICECHANGE
		DO CASE
			CASE nWParam == DBT_DEVICEARRIVAL
				MSGBOX ("INSERT")
			CASE nWParam == DBT_DEVICEREMOVECOMPLETE
				MSGBOX ("REMOVE")
		End CASE
End Case

Return

User avatar
AUGE_OHR
Posts: 326
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 34 times
Been thanked: 42 times

Post by AUGE_OHR » Sun Nov 10, 2019 8:57 pm

edk wrote:
Sun Nov 10, 2019 12:53 pm
You don't need make changes in h_windows.prg. You can create your own event procedure:

Code: Select all

/*
* HMG This Demo
* (c) 2003 Roberto Lopez
*/

#include "hmg.ch"

Function Main
Local nIndex

	DEFINE WINDOW Form_1 ;
		AT 0,0 ;
		WIDTH 400 ;
		HEIGHT 200 ;
		TITLE 'This Demo' ;
		MAIN ;
		ON INIT ThisWindow.Title := 'New Title'

		@ 10,10 BUTTON Button_1 ;
			CAPTION 'Hi!!!' ;
			ACTION ThisTest() ;
			TOOLTIP 'Test Tip'

		@ 40,10 BUTTON Button_2 ;
			CAPTION 'Release' ;
			ACTION ThisWindow.Release 

	END WINDOW

	CREATE EVENT PROCNAME USB_Detect() HWND Form_1.HANDLE STOREINDEX nIndex
	
	CENTER WINDOW Form_1

	ACTIVATE WINDOW Form_1

Return

Procedure ThisTest()

	This.Caption  := 'New Caption'

	ThisWindow.Row := 10
	ThisWindow.Col := 10
	ThisWindow.Width := 200
	ThisWindow.Height := 100

Return

FUNCTION USB_Detect()
LOCAL  nHWnd := EventHWND ()
LOCAL  nMsg := EventMSG ()
LOCAL  nWParam := EventWPARAM ()
LOCAL  nLParam := EventLPARAM ()

#define WM_DEVICECHANGE 0x0219
#define DBT_DEVICEARRIVAL 0x8000
#define DBT_DEVICEQUERYREMOVE 0x8001
#define DBT_DEVICEQUERYREMOVEFAILED 0x8002
#define DBT_DEVICEREMOVEPENDING 0x8003
#define DBT_DEVICEREMOVECOMPLETE 0x8004 

DO CASE 
	CASE nMsg == WM_DEVICECHANGE
		DO CASE
			CASE nWParam == DBT_DEVICEARRIVAL
				MSGBOX ("INSERT")
			CASE nWParam == DBT_DEVICEREMOVECOMPLETE
				MSGBOX ("REMOVE")
		End CASE
End Case

Return
YES ... that is what i'm asking, THX

User avatar
AUGE_OHR
Posts: 326
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 34 times
Been thanked: 42 times

Post by AUGE_OHR » Sun Nov 10, 2019 9:06 pm

hi,

any Hint about PEEKDWORD() :?:

edk
Posts: 519
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 137 times
Been thanked: 440 times

Post by edk » Sun Nov 10, 2019 10:21 pm

I'm sorry, but I've never had to use peekdword(), and I don't see the appropriate function in Harbour. I wonder if you can use PeekStr(), read 4 bytes and convert them :?:

Post Reply