Created
December 16, 2011 18:24
-
-
Save taxilian/1487248 to your computer and use it in GitHub Desktop.
Example of receiving WM_DEVICECHANGE in a plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <set> | |
#include "USBNotify.h" | |
USBNotify::USBNotify() | |
{ | |
} | |
USBNotify::~USBNotify() | |
{ | |
} | |
void USBNotify::NotifyDeviceChange() | |
{ | |
boost::recursive_mutex::scoped_lock _l(m_mutex); | |
bool hasDevice = false; // TODO: detect if the device has changed | |
APIList::iterator it = weakApiList.begin(); | |
APIList::iterator it_end = weakApiList.end(); | |
while (it != it_end) { | |
USBNotifyAPIPtr ptr(it->lock()); | |
if (!ptr) { | |
// Remove any expired API pointers | |
it = weakApiList.erase(it); | |
} else { | |
ptr->fire_changed(hasDevice); | |
++it; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#ifndef H_USBNotify_ | |
#define H_USBNotify_ | |
#include <list> | |
#include <boost/noncopyable.hpp> | |
#include <boost/thread/recursive_mutex.hpp> | |
#include "FBPointers.h" | |
FB_FORWARD_PTR(USBNotifyAPI); | |
class USBNotify: boost::noncopyable { | |
public: | |
typedef std::list<USBNotifyAPIWeakPtr> APIList; | |
USBNotify(); | |
virtual ~USBNotify(); | |
static USBNotify* create(); | |
void NotifyDeviceChange(); | |
void registerAPI(const USBNotifyAPIPtr& api) { | |
boost::recursive_mutex::scoped_lock _l(m_mutex); | |
weakApiList.push_back(api); | |
} | |
void unregisterAPI(const USBNotifyAPIPtr& api) { | |
boost::recursive_mutex::scoped_lock _l(m_mutex); | |
APIList::iterator it = weakApiList.begin(); | |
APIList::iterator it_end = weakApiList.end(); | |
while (it != it_end) { | |
USBNotifyAPIPtr ptr(it->lock()); | |
if (!ptr || ptr == api) { | |
it = weakApiList.erase(it); | |
} else { | |
++it; | |
} | |
} | |
} | |
protected: | |
APIList weakApiList; | |
boost::recursive_mutex m_mutex; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "win_common.h" | |
#include "Win/WinMessageWindow.h" | |
#include <dbt.h> | |
#include <boost/bind.hpp> | |
#include "USBNotifyWin.h" | |
#include "logging.h" | |
static const GUID usb_hid = { 0xA5DCBF10L, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} }; | |
USBNotify* USBNotify::create() | |
{ | |
return new USBNotifyWin(); | |
} | |
USBNotifyWin::USBNotifyWin() | |
{ | |
m_window.setWinProc(boost::bind(&USBNotifyWin::WinProc, this, _1, _2, _3, _4, _5)); | |
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; | |
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) ); | |
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); | |
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; | |
NotificationFilter.dbcc_classguid = usb_hid; | |
hDeviceNotify = RegisterDeviceNotification( | |
m_window.getHWND(), // events recipient | |
&NotificationFilter, // type of device | |
DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle | |
); | |
if ( hDeviceNotify == NULL ) | |
{ | |
LPTSTR lpMsgBuf; | |
DWORD dw = GetLastError(); | |
FormatMessage( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
FORMAT_MESSAGE_FROM_SYSTEM | | |
FORMAT_MESSAGE_IGNORE_INSERTS, | |
NULL, | |
dw, | |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
(LPTSTR) &lpMsgBuf, | |
0, NULL ); | |
FBLOG_ERROR("USBNotifyWin", "Could not register for device notification: " << lpMsgBuf); | |
LocalFree(lpMsgBuf); | |
} | |
} | |
USBNotifyWin::~USBNotifyWin() | |
{ | |
UnregisterDeviceNotification(hDeviceNotify); | |
} | |
bool USBNotifyWin::WinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult ) | |
{ | |
switch(uMsg) { | |
case WM_DEVICECHANGE: | |
{ | |
// | |
// This is the actual message from the interface via Windows messaging. | |
// This code includes some additional decoding for this particular device type | |
// and some common validation checks. | |
// | |
// Note that not all devices utilize these optional parameters in the same | |
// way. Refer to the extended information for your particular device type | |
// specified by your GUID. | |
// | |
PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) lParam; | |
// Output some messages to the window. | |
switch (wParam) | |
{ | |
case DBT_DEVICEARRIVAL: | |
FBLOG_INFO("USBNotifyWin", "Device arrived"); | |
break; | |
case DBT_DEVICEREMOVECOMPLETE: | |
FBLOG_INFO("USBNotifyWin", "Device removal complete"); | |
break; | |
case DBT_DEVNODES_CHANGED: | |
FBLOG_INFO("USBNotifyWin", "Device nodes changed"); | |
break; | |
default: | |
FBLOG_WARN("USBNotifyWin", "WM_DEVICECHANGE received"); | |
break; | |
} | |
NotifyDeviceChange(); | |
} | |
break; | |
} | |
return false; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#ifndef H_USBNotifyWin_ | |
#define H_USBNotifyWin_ | |
#include <list> | |
#include <boost/noncopyable.hpp> | |
#include <boost/thread/recursive_mutex.hpp> | |
#include "FBPointers.h" | |
#include "../USBNotify.h" | |
namespace FB { class WinMessageWindow; }; | |
class USBNotifyWin : public USBNotify { | |
public: | |
typedef std::list<USBNotifyAPIWeakPtr> myAPIList; | |
USBNotifyWin(); | |
virtual ~USBNotifyWin(); | |
bool WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult); | |
protected: | |
FB::WinMessageWindow m_window; | |
HDEVNOTIFY hDeviceNotify; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment