PeekMessage не получает сообщение? - PullRequest
3 голосов
/ 03 июня 2011

Я создал собственный тип сообщения для изменения размера Window, который называется WM_NEED_RESIZE. Я определил это в моем .h файле и инициализировал в моем .cpp файле. Я также зарегистрировал свою функцию WindowProc для приема сообщений. Вот код для этих предметов:

const uint32 WindowsGLWindow::WM_NEED_RESIZE = WM_USER + 100;
LONG WINAPI WindowsGLWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static PAINTSTRUCT ps;// do I need this?
    static sint32 newWidth = 0;
    static sint32 newHeight = 0;
    bool res = false;

    switch (uMsg) {
        case WM_PAINT:
            //display();
            BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            return 0;

        case WM_SIZE:
            //glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
            res = PostMessage(hWnd, WindowsGLWindow::WM_NEED_RESIZE, wParam,     lParam);
            std::cout << "WM_SIZE: " << res << std::endl;
            return 0;

        case WindowsGLWindow::WM_NEED_RESIZE:
            std::cout << "WindowsGLWindow::WM_NEED_RESIZE" << std::endl;
            break;

        case WM_CHAR:
            switch (wParam) {
                case 27: /* ESC key */
                    PostQuitMessage(0);
                    break;
            }
            return 0;

        case WM_CLOSE:
            PostQuitMessage(0);
            return 0;
    }

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

В другой функции я запускаю PeekMessage(..), чтобы собрать все сообщения. Вот фрагмент сообщения насоса:

    MSG msg;
    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) == TRUE) // maybe use GetInputState(?)     as well?
    {
        if (msg.message == WM_QUIT)
            retVal = -1;

        if (msg.message == WindowsGLWindow::WM_NEED_RESIZE) {
            uint32 newWidth = LOWORD(msg.lParam);
            uint32 newHeight = HIWORD(msg.lParam);

            std::cout << "PeekMessage: WindowsGLWindow::WM_NEED_RESIZE" <<         std::endl;

            // call resize only if our window-size changed
            if ((newWidth != width_) || (newHeight != height_)) {
                resize(newWidth, newHeight);
            }

            PostMessage(msg.hwnd, WM_PAINT, 0, 0);
        }

        switch (msg.message) {
            case WM_MOUSEMOVE:
                // Retrieve mouse screen position
                //int x = (short) LOWORD(lParam);
                //int y = (short) HIWORD(lParam);

                // Check to see if the left button is held down:
                //bool leftButtonDown = wParam & MK_LBUTTON;

                // Check if right button down:
                //bool rightButtonDown = wParam & MK_RBUTTON;
                break;
            case WM_LBUTTONDOWN:
            case WM_RBUTTONDOWN:
            case WM_LBUTTONUP:
            case WM_RBUTTONUP:
            case WM_KEYUP:
            case WM_KEYDOWN:
                /*
                switch (msg.wParam) {
                    case 'W':
                        // w key pressed
                        break;
                    case VK_RIGHT:
                        // Right arrow pressed
                        break;
                    default:
                        break;
                }
                */
                break;
        }

        TranslateMessage(&msg);
        DispatchMessage(&msg);

    }

Моя проблема в том, что сообщение WM_NEED_RESIZE найдено только один раз в очереди сообщений при первом открытии окна, после чего мое PeekMessage(..) никогда не находит его в очереди сообщений. Я действительно не уверен, почему это происходит. Однако - это , получаемый методом WindowProc(..) (который на самом деле мне не помогает). Я был бы признателен за любую помощь, которую вы, ребята, могли бы оказать.

Спасибо

Джарретт

Ответы [ 2 ]

2 голосов
/ 03 июня 2011
  1. Не используйте std :: cout, ожидая увидеть выходные данные в вашем отладчике, insted use OutputDebugString (); ,

  2. Вам нужно передать указатель класса на последний параметр вашего вызова CreateWindowEx, а затем извлечь этот указатель из LPCREATESTRUCT, переданного вам в LPARAM из WM_CREATE, указатель вашего класса будет находиться в поле lpCreateParmas поля структура. Установите указатель clas на GWLP_USERDATA вашего окна, и при любых других вызовах сообщений вызовите GetWindowsLong, получите указатель класса, а затем передайте сообщение, wparam и lparam всем в ваш внутренний обработчик сообщений класса.

http://msdn.microsoft.com/en-us/library/ff381400%28v=VS.85%29.aspx

0 голосов
/ 03 июня 2011

Показанный вами цикл прокачки сообщений завершится, как только очередь опустеет. Я не могу судить по тому, что вы опубликовали, если оно когда-нибудь будет введено снова.

Если это ваш основной обработчик сообщений, вам следует использовать GetMessage () , поскольку он будет ждать, пока что-то станет доступно, прежде чем вернуться. Посмотрите эту статью MSDN для получения дополнительной информации.

...