2015-12-04 3 views
1

Когда я запускаю свою программу (код ниже) и вставляю жесткий диск через USB-кабель, WindowProcedure вызывается для сообщения WM_DEVICECHANGE для события события смены устройства DBT_DEVICEARRIVAL.GetMessage Не получать сообщения

Однако GetMessage не возвращается. documentation for GetMessage говорит GetMessage

Извлекает сообщение из очереди сообщений вызывающего потока.

Таким образом, похоже, что в очереди сообщений потока нет сообщений.

Почему в очереди сообщений вызывающего потока нет сообщений?

Если нет сообщений в очереди сообщений моего вызывающего потока, как/почему моя 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

Я думаю, что в большинстве случаев вам не нужно знать, будет ли какое-либо конкретное сообщение отправлено или отправлено в любом случае? По крайней мере, не для его обработки. До тех пор, пока вы осознаете, что это может произойти в любом случае, это, как правило, не имеет значения. –

Смежные вопросы