Search code examples
openglfreeglut

GLUT function key stop refreshing


I've used FreeGLUT 3.0.0 (built from source using MSVC 2013) under Windows 7 to create an OpenGL context for quite a while, but today I encountered some strange behavior: When I press the F10 key, the window stops to refresh. Following is the minimal code that will achieve this strange behavior under 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;
}

In this example, when I press F10, the command line stops to print the character 'a', and continues when I press F10 again.

The strange thing is that I didn't do anything special to F10 (I encountered this problem since the point I didn't write anything like GLUT_KEY_F10). All other function key don't have this problem. I don't why this is specific to the F10 key.

Does anyone have any suggestion about how to deal with this problem?


Solution

  • As suggested 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.

    Adding a flag to skip the DefWindowProc() call on SC_KEYMENU events to FreeGLUT's WM_SYSCOMMAND handler seems to "fix" the problem:

    ...
    
        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;
            }
    
    ...