這真是對這個問題回答R.E.評論設備檢測。
在控制檯應用程序中創建一個隱藏窗口。
這個例子假設你有一個叫DevNotifier
類,與HWND hidden_wnd_;
成員變量:
static TCHAR const s_window_class[] = _T("Device notification window");
static TCHAR const* const s_window_title = s_window_class;
LRESULT CALLBACK
DevNotifierWndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
) {
DevNotifier* dn = (DevNotifier*) ::GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (message)
{
case WM_DEVICECHANGE:
dn->onWM_DEVICECHANGE(
wParam,
lParam
);
break;
default:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void
DevNotifier::createHiddenWindow()
{
HINSTANCE hinstance = ::GetModuleHandle(NULL);
if ((hinstance == 0) || (hinstance == INVALID_HANDLE_VALUE))
{
throw Exception("Failed to get application instance handle.");
}
// register window class
WNDCLASSEX wcex;
::memset(&wcex, 0, sizeof(wcex));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = &DevNotifierWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hinstance;
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = 0;
wcex.lpszMenuName = 0;
wcex.lpszClassName = s_window_class;
wcex.hIconSm = 0;
(void) ::RegisterClassEx(&wcex);
// Create the window
hidden_wnd_ = ::CreateWindow(
s_window_class,
s_window_title,
WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hinstance,
NULL
);
if (!hidden_wnd_) {
throw Exception("Failed to create device notification window");
}
#ifdef _WIN64
::SetWindowLongPtr(static_cast<HWND>(hidden_wnd_), GWLP_USERDATA, (LONG_PTR)this);
#else
::SetWindowLongPtr(static_cast<HWND>(hidden_wnd_), GWLP_USERDATA, (LONG)this);
#endif
::ShowWindow(static_cast<HWND>(hidden_wnd_), SW_HIDE);
}
您可以爲hidden_wnd_註冊通知。
例如
DEV_BROADCAST_DEVICEINTERFACE filter;
ZeroMemory(&filter, sizeof(filter));
filter.dbcc_size = sizeof(filter);
filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
filter.dbcc_classguid = /* SOME INTERFACE GUID */;
HDEVNOTIFY hdn = ::RegisterDeviceNotification(
hidden_wnd_,
&filter,
DEVICE_NOTIFY_WINDOW_HANDLE
);
您需要實現應對WM_DEVICE_CHANGE消息功能:
bool
DevNotifier::onWM_DEVICECHANGE(WPARAM wparam, LPARAM lparam)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*)lparam;
// Note dbh will NOT always be valid, depending upon the value of wparam.
if (wparam == DBT_DEVNODES_CHANGED) {
// Do some stuff here
return true;
}
else if (wparam == DBT_DEVICEARRIVAL) {
DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lparam;
if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
DEV_BROADCAST_DEVICEINTERFACE* devinterface =
(DEV_BROADCAST_DEVICEINTERFACE*)hdr;
// Do some stuff here
}
}
else if (wparam == DBT_DEVICEREMOVEPENDING) {
}
else if (wparam == DBT_DEVICEREMOVECOMPLETE) {
HANDLE h = INVALID_HANDLE_VALUE;
DEV_BROADCAST_HDR* phdr = (DEV_BROADCAST_HDR*) lparam;
if (phdr->dbch_devicetype == DBT_DEVTYP_HANDLE) {
DEV_BROADCAST_HANDLE* pdbh = (DEV_BROADCAST_HANDLE*) lparam;
h = pdbh->dbch_handle;
}
else if (phdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
DEV_BROADCAST_DEVICEINTERFACE* devinterface =
(DEV_BROADCAST_DEVICEINTERFACE*)phdr;
// Do some stuff here
}
// Maybe do some stuff here too.
}
return false;
}
在控制檯應用程序,你將不得不運行一個消息泵獲取Windows消息的工作。如果在應用程序正在等待消息時你還有其他的東西要做,那麼你也需要在這裏處理它。
while (GetMessage(&message, NULL, 0, 0) > 0) {
TranslateMessage(&message);
DispatchMessage(&message);
}
'「它在Windows 7上不顯示正確的行爲。」詳細說明。 –
@Raghav瓜爾你有沒有試試這個?打開註冊表編輯器,導航到HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ USBSTOR,鍵入4,按OK。它工作嗎?如果是的話,你可以使用win api與註冊表 – Qwerty
@Qwerty:我已經用你的方式,我也在我的問題中描述了它。這種方法在Windows XP中工作正常,但在Windows 7中沒有。 –