Reputation: 5095
When I run my program (code below) and insert a hard drive via a USB cable, the WindowProcedure
is called for a WM_DEVICECHANGE
message for device-change event type DBT_DEVICEARRIVAL
.
However, GetMessage
does not return.
The documentation for GetMessage
says GetMessage
Retrieves a message from the calling thread's message queue.
Thus, it sounds like there are no messages in the thread's message queue.
Why are there no messages in my calling thread's message queue?
If there are no messages in my calling thread's message queue, how/why is my WindowProcedure
function being called for the WM_DEVICECHANGE
message for device-change event type DBT_DEVICEARRIVAL
?
Note: I've read some related posts and pages. This stackoverflow post seems like it might be related. If so, how do I know what messages actually get placed on the message queue?
namespace {
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if( uMsg == WM_DEVICECHANGE )
{
switch(wParam)
{
case DBT_DEVICEARRIVAL:
{
PostQuitMessage('L');
break;
}
case DBT_DEVNODES_CHANGED:
{
break;
}
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
BOOL DoRegisterDeviceInterfaceToHwnd(IN GUID InterfaceClassGuid, IN HWND hWnd, OUT HDEVNOTIFY *hDeviceNotify)
{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = InterfaceClassGuid;
*hDeviceNotify = RegisterDeviceNotification(
hWnd, // events recipient
&NotificationFilter, // type of device
DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES // type of recipient handle
);
if ( NULL == *hDeviceNotify )
{
//ErrorHandler(TEXT("RegisterDeviceNotification"));
return FALSE;
}
return TRUE;
}
int processWindowsMessages()
{
WNDCLASS windowClass = {};
windowClass.lpfnWndProc = WindowProcedure;
LPCSTR windowClassName = "DetecatAndMountMessageOnlyWindow";;
windowClass.lpszClassName = windowClassName;
if (!RegisterClass(&windowClass)) {
std::cout << "Failed to register window class" << std::endl;
return 1;
}
HWND messageWindow = CreateWindow (windowClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
//HWND messageWindow = CreateWindow (windowClassName, 0, 0, 0, 0, 0, 0, (HWND) NULL, 0, 0, 0);
if (!messageWindow) {
std::cout << "Failed to create message-only window" << std::endl;
return 1;
}
static HDEVNOTIFY hDeviceNotify;
DoRegisterDeviceInterfaceToHwnd(GUID_DEVINTERFACE_VOLUME, messageWindow, &hDeviceNotify);
MSG msg;
BOOL bRet;
std::cout << "before loop" << std::endl;
while ( (bRet = GetMessage (&msg, 0, 0, 0)) != 0 )
{
std::cout << "inside loop" << std::endl;
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
std::cout << msg.wParam << std::endl;
return msg.wParam;
}
int main()
{
int result = processWindowsMessages();
return 0;
}
Upvotes: 1
Views: 2087
Reputation: 613461
The documentation for WM_DEVICECHANGE
says:
A window receives this message through its WindowProc function.
That means this is not a queued message. It is not placed on the message queue. It is not retrieved by GetMessage
.
Instead it is sent directly to the window procedure of a window. The message is broadcast to top-level windows, and sent to windows that register with RegisterDeviceNotification
.
Upvotes: 1