2013-02-07 2 views
0

글로벌 WindowProc 함수에서 GUI 클래스로 메시지를 보내려고합니다. 다음과 같은 메시지가 정의됩니다PostMessage는 한 번만 작동합니까?

MSG msg; 
while (running) 
{ 
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
     processWindowsMessage(&msg); 

    //DirectX render calls 
} 

이제 내 문제 :

#define WM_ENV_RESIZED (WM_APP + 0) 

내 WindowProc 함수는 메시지는 다음과 같이 GUI를 클래스에 수신이

LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    int res; 
    switch (message) 
    { 
     case WM_SIZE: 
      std::cout << "window resized" << std::endl; 

      res = PostMessage(hWnd, WM_ENV_RESIZED, 0, 0); 
      if (res == 0) //<-- res is never 0 
      { 
       std::cout << "PostMessage failure!" << std::endl; 
       std::cout << "Error code: " << GetLastError() << std::endl; 
      } 
      break; 
     default: 
      return DefWindowProc(hWnd, message, wParam, lParam); 
    } 

    return DefWindowProc(hWnd, message, wParam, lParam); 
} 

처럼 보인다 PeekMessage()가 메시지를 수신하지 못했기 때문입니다. 창을 만들 때 한 번만 수신됩니다. 그 후에는 절대로받지 못합니다.

PostMessage() 직후에 GetLastError()를 호출하면 항상 MSDN에 따라 ERROR_INVALID_HANDLE을 나타내는 오류 코드 6이 반환됩니다. 그러나 PostMessage()는 0을 반환하지 않기 때문에 의미가 없습니다. 이는 게시 중에 문제가 있음을 의미합니다. 메시지 대기열을 우회하고 SendMessage()를 사용하여 메시지를 창에 직접 보내려고했지만 항상 0 (동일한 오류 코드 6 ..)이 반환됩니다.

내가 뭘 잘못하고 있는지 전혀 알지 못합니다. PeekMessage()를 사용할 때 게시 된 메시지가 항상 수신되도록하려면 어떻게해야합니까?

편집 : Remy가 제안한대로 메시지 루프를 업데이트했습니다. 아래는 메시지 크기를 조절할 같은 창에 게시되고 있기 때문에 processWindowsMessage (의 코드)

void Environment::processWindowsMessage(MSG *msg) 
{ 
    switch (msg->message) 
    { 
     case WM_ENV_RESIZED: 
      std::cout << "WM_ENV_RESIZED caught" << std::endl; 
      break; 
     case WM_QUIT: 
      running = false; 
      break; 
     default: 
      TranslateMessage(msg); 
      DispatchMessage(msg); 
      break; 
    } 
} 
+4

'PostMessage'가 성공했다고 표시하면 성공했습니다. 오류 코드는 실패시에만 정의되기 때문에'GetLastError'를 호출하면 쓸모가 없습니다. 일부 API 함수는 오류가 발생할 경우 전진 적으로 오류 코드를 설정합니다. 문서가 당신에게 권고하지 않는 한'GetLastError'를 호출하지 마십시오. 문서는 일반적으로 실패했을 때만 조언합니다. 성공을 위해 그것을 부르는 이유는 드뭅니다. –

+0

processWindowsMessage 함수의 관련 부분을 게시 할 수 있습니까? –

+0

PostMessage 호출에 사용 된 창 핸들이 의미가 없습니다. 그것은 분명히해서는 안됩니다. –

답변

1

이며, DispatchMessage()는 창을 표적으로 다른 메시지처럼 윈도우의 프로 시저에 메시지를 보내드립니다. 그래서 다음 중 하나를

LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_SIZE: 
      std::cout << "window resized" << std::endl; 

      if (!PostMessage(hWnd, WM_ENV_RESIZED, 0, 0)) 
      { 
       std::cout << "PostMessage failure!" << std::endl; 
       std::cout << "Error code: " << GetLastError() << std::endl; 
      } 
      break; 

     case WM_ENV_RESIZED: 
      std::cout << "env resized" << std::endl; 
      //... 
      return 0; 
    } 

    return DefWindowProc(hWnd, message, wParam, lParam); 
} 

:

1) windowProcedure()의 내부 메시지를 처리합니다.

MSG msg; 
while (running) 
{ 
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    //DirectX render calls 
} 

2) 번역하지 않는, 다음, 당신의 윈도우 프로 시저에서 사용자 정의 메시지를 처리 ​​processWindowsMessage()TranslateMessage()DispatchMessage() 통화를 이동 만이 아닌 사용자 정의 메시지를 전화 메시지 루프를 변경하지 않는 경우/맞춤 발송 메시지 :

LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_SIZE: 
      std::cout << "window resized" << std::endl; 

      if (!PostMessage(hWnd, WM_ENV_RESIZED, 0, 0)) 
      { 
       std::cout << "PostMessage failure!" << std::endl; 
       std::cout << "Error code: " << GetLastError() << std::endl; 
      } 
      break; 
    } 

    return DefWindowProc(hWnd, message, wParam, lParam); 
} 

.

MSG msg; 
while (running) 
{ 
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
     processWindowsMessage(&msg); 

    //DirectX render calls 
} 

.

void processWindowsMessage(MSG *msg) 
{ 
    switch (msg->message) 
    { 
     case WM_ENV_RESIZED: 
      std::cout << "env resized" << std::endl; 
      //... 
      break; 

     default: 
      TranslateMessage(msg); 
      DispatchMessage(msg); 
      break; 
    } 
} 
+0

일반적으로 좋은 조언. 나는 그것이 OP의 염려를 언급하지 않는다고 말하고 싶었지만 정직하게도 이들은 훌륭한 잡동사니입니다. – HerrJoebob

+0

원래의 코드를 보면,'TranslateMessage()'가'MSG'를'processWindowsMessage()'가 인식하지 못하는 다른 것으로 수정하고있는 것이 유일한 방법입니다. –

+0

Remy 답장을 보내 주셔서 감사합니다. 제안한대로 코드를 수정했지만 메시지가 여전히 잡히지 않습니다. 나는주의를 기울였다. processWindowsMessage()에서 스위치를 껐다가 조금 기다렸다가 코드를 계속 실행하면 메시지가 수신되어 처리된다. 이것은 이상한 행동이며, 왜 이런 일이 일어나고 있는지 확신 할 수 없습니다 ... – Krienie

관련 문제