catching the WM_DEVICECHANGE

c, gcc, mingw, winapi, windows

Solution

The problem is that you are creating a message-only window which does not receive broadcasts:

A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.

So, you cannot use a message-only window and instead need to make a top-level window that is never shown. That's trivial to achieve — stop passing `HWND_MESSAGE` to `CreateWindow` and make sure that you never call `ShowWindow`.

As an aside, `Sleep(1000)` in the middle of a message loop is going to be a disaster. You need to pump messages in a timely fashion, not fall asleep on the job. You must get rid of that `Sleep`. Note that `GetMessage` will block if the queue is empty, so you don't need to worry about your application running hot.

Your message loop should look like this:

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
} 

Problem

How to become aware of `WM_DEVICECHANGE` arrival? `WndProc`'s overwritten. I catch the whole bunch of messages but none of them are of type `WM_DEVICECHANGE`. `RegisterDeviceNotification` makes the linker to complain that it can't find the function! So I'm stuck in this voodoo magic. Kindly help. P.S.: of course I have been googling and stackoverflowing (lol) all this stuff for about 8 hours. ``` int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { LPTSTR lolclassname = "lolclass"; WNDCLASS lolclass; HWND lolwindow; MSG lolmsg; UINT msgstatus; lolclass.style = CS_VREDRAW; lolclass.lpfnWndProc = &lol_wnd_proc; lolclass.cbClsExtra = 0; lolclass.cbWndExtra = 0; lolclass.hInstance = hInstance; lolclass.hIcon = NULL; lolclass.hCursor = NULL; lolclass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); lolclass.lpszMenuName = NULL; lolclass.lpszClassName = lolclassname; if(!RegisterClass(&lolclass)) fail("RegisterClassEx"); lolwindow = CreateWindow("lolclass", NULL, WS_MINIMIZE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, NULL, hInstance, NULL); if(lolwindow == NULL) fail("CreateWindowEx"); /*ShowWindow(lolwindow, nCmdShow); UpdateWindow(lolwindow);*/ do { /* if(!SetWindowPos(lolwindow, HWND_TOPMOST, 1, 1, 1, 1, SWP_HIDEWINDOW)) fail("SetWindowPos");*/ msgstatus = GetMessage(&lolmsg, lolwindow, 0, 0); if(!msgstatus) break; if(msgstatus == - 1) fail("GetMessage"); TranslateMessage(&lolmsg); DispatchMessage(&lolmsg); Sleep(1000); } while(1); return lolmsg.wParam; } ``` `lol_wnd_pro`c is executed but never when it supposed to (on device change of course, am I clear?)

Original source