2015-12-04 49 views
1

当我运行我的程序(下面的代码)并通过USB电缆插入硬盘驱动器时,WindowProcedure被称为WM_DEVICECHANGE消息,用于设备更改事件类型DBT_DEVICEARRIVALGetMessage不检索消息

但是,GetMessage不返回。 的documentation for GetMessageGetMessage

检索从调用线程的消息队列中的消息。

因此,听起来好像线程的消息队列中没有消息。

为什么我的调用线程的消息队列中没有消息?

如果有我的呼唤线程的消息队列中没有消息,如何/为什么我的WindowProcedure被调用函数为WM_DEVICECHANGE消息装置改变事件类型DBT_DEVICEARRIVAL

注:我读过一些相关的帖子和​​页面。 This stackoverflow post似乎可能是相关的。如果是这样,我怎么知道消息队列中实际放置了什么消息?

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; 
} 
+3

'GetMessage'将只返回发布到消息队列的消息。发送的消息在GetMessage本身内部调用,直接调用WndProc。 –

+0

无法发布'WM_DEVICECHANGE'的一条线索是'lParam'是一个指向结构体的指针。只有发送的消息可以(通常)提供指向内存的指针,因为一旦SendMessage调用返回,内存通常会被发送者释放或重新使用。 –

+0

@JonathanPotter因此,发送的消息直接发送到WndProc并发送消息到消息队列。但是,如果我只想处理发送的消息,我仍然需要调用'GetMessage',因为这会启动将发送的消息分派到WndProc的过程。它是否正确? – user3731622

回答

1

的文档WM_DEVICECHANGE说:

一个窗口,通过它的WindowProc函数接收该消息。

这意味着这不是排队的消息。它不放置在消息队列中。它不被GetMessage检索。

相反,它被直接发送到窗口的窗口过程。该消息被广播到顶层窗口,并被发送到以RegisterDeviceNotification注册的窗口。

+1

我也会用这个引用作为例子,但是后来我发现'WM_MOUSEMOVE'的文档说的是相同的东西(他们也说这个消息已经发布了,但是在典型的MSDN方式中并不是那么直截了当)。 –

+0

@JonathanPotter噢,我想这是一个人必须知道的东西 –

+0

我在想,在大多数情况下,您实际上并不需要知道是否会发布或发送任何特定消息?至少不是为了处理它。只要你意识到它可能发生在任何一个方面,它通常都不重要。 –