GLUT功能键停止刷新

GLUT function key stop refreshing

我在 Windows 7 下使用 FreeGLUT 3.0.0(使用 MSVC 2013 从源代码构建)创建 OpenGL 上下文已经有一段时间了,但今天我遇到了一些奇怪的行为:当我按下F10键时,window停止刷新。以下是在 MSVC 2013 下实现这种奇怪行为的最少代码,Windows 7:

#define FREEGLUT_STATIC
#include <gl/glut.h>
#include <iostream>

using namespace std;

void init()
{
    glClearColor(1.0, 0.0, 0.0, 0.0);
}

void display()
{
    cout << "a" << endl;
    glClear(GL_COLOR_BUFFER_BIT);
    glutSwapBuffers();
    glutPostRedisplay();
}

void reshapeFunc(int width, int height)
{
    glViewport(0, 0, 640, 480);
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("What?");

    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshapeFunc);

    glutMainLoop();
    return 0;
}

在此示例中,当我按下 F10 时,命令行停止打印字符 'a',并在我再次按下 F10 时继续。

奇怪的是我没有对F10做任何特别的事情(我遇到这个问题是因为我没有写GLUT_KEY_F10这样的东西)。所有其他功能键都没有这个问题。我不明白为什么这是特定于 F10 键的。

有人对如何处理这个问题有什么建议吗?

按照建议here:

F10 is the shortcut key to enter a windows' menu. It should be enough to not pass a valid HMENU handle. I haven't tested this though. You probably want to avoid using F10 if it doesn't work though.

If you insist, you can get F10 by catching WM_SYSKEYDOWN and NOT passing the message on to DefWindowProc.

添加一个标志以跳过对 SC_KEYMENU 事件的 DefWindowProc() 调用到 FreeGLUT's WM_SYSCOMMAND handler 似乎 "fix" 问题:

...

    case WM_SYSCOMMAND :  /* 0x0112 */
        {
            /* HACKITTY HACK HACK HACK */
            int skipDefWindowProc = 0;
            {
                /*
                * We have received a system command message.  Try to act on it.
                * The commands are passed in through the "wParam" parameter:
                * The least significant digit seems to be which edge of the window
                * is being used for a resize event:
                *     4  3  5
                *     1     2
                *     7  6  8
                * Congratulations and thanks to Richard Rauch for figuring this out..
                */
                switch ( wParam & 0xfff0 )
                {
                case SC_SIZE       :
                    break ;

                case SC_MOVE       :
                    break ;

                case SC_MINIMIZE   :
                    /* User has clicked on the "-" to minimize the window */
                    /* Turning off the visibility is handled in WM_SIZE handler */

                    break ;

                case SC_MAXIMIZE   :
                    break ;

                case SC_NEXTWINDOW :
                    break ;

                case SC_PREVWINDOW :
                    break ;

                case SC_CLOSE      :
                    /* Followed very closely by a WM_CLOSE message */
                    break ;

                case SC_VSCROLL    :
                    break ;

                case SC_HSCROLL    :
                    break ;

                case SC_MOUSEMENU  :
                    break ;

                case SC_KEYMENU    :
                    skipDefWindowProc = 1;
                    break ;

                case SC_ARRANGE    :
                    break ;

                case SC_RESTORE    :
                    break ;

                case SC_TASKLIST   :
                    break ;

                case SC_SCREENSAVE :
                    break ;

                case SC_HOTKEY     :
                    break ;

#if(WINVER >= 0x0400)
                case SC_DEFAULT    :
                    break ;

                case SC_MONITORPOWER    :
                    break ;

                case SC_CONTEXTHELP    :
                    break ;
#endif /* WINVER >= 0x0400 */

                default:
#if _DEBUG
                    fgWarning( "Unknown wParam type 0x%x", wParam );
#endif
                    break;
                }
            }
#endif /* !defined(_WIN32_WCE) */

            /* We need to pass the message on to the operating system as well */
            if( skipDefWindowProc == 0 )
            {
                lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
            }
            break;
        }

...