[Reviving an old tread.]
On Fri, Jul 22, 2005 at 9:12 AM, Chris Mellon <
ark...@gmail.com> wrote:
> wxhInstance is an HINSTANCE, it's not what you want.
> RegisterDeviceNotification just takes a regular window handle,
> although the docs suggest that it must be a top level window (for no
> apparent reason). In your app, this would be the handle of your
> wxFrame. I would try, however, simply using the same window you're
> already processing the device notifications in.
I am trying to detect USB Hardware Insertion and/or Removal via
RegisterDeviceNotification as described here:
http://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal
I am having trouble getting this integrated into wxWidgets.
RegisterDeviceNotification keeps returning the error 'Invalid Data'
which I believe is because I don't have the correct parent window.
I'm using Windows 7, wx 3.02 with MINGW w64;
http://nuwen.net/mingw.html
My window hierarchy is :
Dialog -> Notebook -> Notebook Tab (wxPanel).
I'm calling RegisterDeviceNotification setup in the wxPanel
constructor, that looks like the wrong place?
Also found that the constructor is called six times. Why? Not really
important to the problem at hand.
I have tried using the wxPanel's parent as well as
wxTheApp->GetTopWindow() in RegisterDeviceNotification setup, both
giving 'Invalid Data Error'.
My two questions are:
What is the correct parent?
Were should I place the initialization code so that the parent is
valid and hopefully only called once (unlike the constructor) [I know
I can use a flag to only do it once]?
Code, explanation above should be sufficient without having to look at this:
FirstPanel::FirstPanel( wxWindow* parent, wxWindowID id, const
wxPoint& pos, const wxSize& size, long style )
{
...
const GUID GUID_DEVINTERFACE_LIST[] =
{
// GUID_DEVINTERFACE_USB_DEVICE
{ 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9,
0x51, 0xED } },
// GUID_DEVINTERFACE_DISK
{ 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e,
0xfb, 0x8b } },
// GUID_DEVINTERFACE_HID,
{ 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00,
0x00, 0x30 } },
// GUID_NDIS_LAN_CLASS
{ 0xad498944, 0x762f, 0x11d0, { 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3,
0x35, 0x8c } }
//// GUID_DEVINTERFACE_COMPORT
//{ 0x86e0d1e0, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30,
0x1f, 0x73 } },
//// GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
//{ 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1,
0x03, 0x18 } },
//// GUID_DEVINTERFACE_PARALLEL
//{ 0x97F76EF0, 0xF883, 0x11D0, { 0xAF, 0x1F, 0x00, 0x00, 0xF8, 0x00,
0x84, 0x5C } },
//// GUID_DEVINTERFACE_PARCLASS
//{ 0x811FC6A5, 0xF728, 0x11D0, { 0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75,
0x3E, 0xD1 } }
};
HDEVNOTIFY hDevNotify;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
for( unsigned int i=0; i<sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID); i++ )
{
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
hDevNotify = RegisterDeviceNotification( parent,
&NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE );
if( !hDevNotify )
{
wxString const com_error(
_com_error(GetLastError()).ErrorMessage() );
wxString const string_wx = wxString::Format( "Can not
register device notification: '%s' times %ul", com_error, ++count_i );
wxMessageBox( string_wx, "Can not detect USB events",
wxICON_WARNING );
}
}
...
}
#ifdef __WXMSW__
void FirstPanel::DeviceUpdate( PDEV_BROADCAST_DEVICEINTERFACE pDevInf,
WPARAM wParam )
{
// pDevInf->dbcc_name:
// \\?\USB#Vid_04e8&Pid_503b#0002F9A9828E0F06#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
// szDevId: USB\Vid_04e8&Pid_503b\0002F9A9828E0F06
// szClass: USB
wxASSERT(lstrlen(pDevInf->dbcc_name) > 4);
wxString szDevId = pDevInf->dbcc_name+4;
int idx = szDevId.Last('#');
wxASSERT( -1 != idx );
szDevId.Truncate(idx);
szDevId.Replace(_T('#'), _T('\\'));
szDevId.MakeUpper();
wxString string_wx;
if ( DBT_DEVICEARRIVAL == wParam ) {
string_wx.Format(_T("Adding %s\r\n"), szDevId );
}
else
{
string_wx.Format(_T("Removing %s\r\n"), szDevId );
}
wxMessageBox( string_wx, "Box" );
}
// Overwrite MSWWindowProc to receive all messages
WXLRESULT FirstPanel::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam,
WXLPARAM lParam)
{
bool processed = false;
if(
(DBT_DEVICEARRIVAL == wParam) ||
(DBT_DEVICEREMOVECOMPLETE == wParam)
)
{
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
PDEV_BROADCAST_DEVICEINTERFACE pDevInf;
// PDEV_BROADCAST_HANDLE pDevHnd;
// PDEV_BROADCAST_OEM pDevOem;
// PDEV_BROADCAST_PORT pDevPort;
// PDEV_BROADCAST_VOLUME pDevVolume;
switch( pHdr->dbch_devicetype )
{
case DBT_DEVTYP_DEVICEINTERFACE:
pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
DeviceUpdate(pDevInf, wParam);
processed = true;
break;
case DBT_DEVTYP_HANDLE:
// pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr;
break;
case DBT_DEVTYP_OEM:
// pDevOem = (PDEV_BROADCAST_OEM)pHdr;
break;
case DBT_DEVTYP_PORT:
// pDevPort = (PDEV_BROADCAST_PORT)pHdr;
break;
case DBT_DEVTYP_VOLUME:
// pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
break;
}
}
if( true == processed )
{
return( (WXLRESULT) 0 );
}
else
{
return wxPanel::MSWWindowProc(nMsg, wParam, lParam); // If
message was not device insert/remove, call standard handler
}
}
#endif