在Win32API中注册Window类

时间:2012-03-18 20:06:54

标签: c++ windows winapi

尽管在整个网络上阅读了大量的信息,以及Petzold的书,编程Windows API ,并且该死的几乎要复制完全相同的方法,以及{{ 3}}关于如何初始化OpenGL上下文的文档,我还没有能够启动并运行Window类。

我已尝试在VC ++和MinGW(我使用Qt Creator)上进行编译,以确定这是否有效。我尝试将WNDCLASSEXA指针作为指针,并将其分配到堆栈中。两者都没有骰子。

因此,我很不确定该怎么做。有时候这个类根本没有注册,而其他时候从HWND返回的CreateWindowExA根本不起作用并返回NULL。在尝试继续该程序之后,尽管发生了这些事件,我最终得到了一个无法绘制窗口的应用程序。

这个想法很简单:我有一个结构,我只是用它来存储所有使用的数据(DEVMODEAWNDCLASSEXAHGLRC等。 / p>

从那里,我使用该结构创建一个Window,然后将其传递回函数的调用者。

我真正想做的就是使用GLSL / OpenGL 3.3在OpenGL中编写一个类似pong的游戏。要做到这一点,我显然首先需要一个上下文,但我无法辨别问题是Qt Creator,Windows还是别的。

那么,我可能做错了什么?

GameData结构

typedef struct
{
    HGLRC        hrc;
    HDC          hdc;
    HWND         hwnd;
    HINSTANCE    hInstance;
    UINT         numFormats;
    WNDCLASSEXA* winClass;
    DWORD        dwExStyle;
    DWORD        dwStyle;
    RECT         winRect;
    DEVMODEA     screenSettings;

    bool         fullscreen;
    const char*  winClassName;
    int          pixelFormat;
    bool         keys[ 256 ];
    bool         active;
}
GameData;

initPong()功能

static GameData* initContextAndWindow( void )
{
    GameData* dat = new GameData;

    const int width     = 640;
    const int height    = 480;
    const int bitsPerPixel = 32;

    dat->winRect.left   = ( long )0;
    dat->winRect.right  = ( long )width;
    dat->winRect.top    = ( long )0;
    dat->winRect.bottom = ( long )height;

    dat->fullscreen     = false;

    dat->hInstance              = GetModuleHandleA( NULL );

    dat->winClass = ( WNDCLASSEXA* )calloc( sizeof( WNDCLASSEXA ), 1 );

    if( !dat->winClass )
        MessageBoxA( NULL, "Something wrong!", "ERROR", MB_OK | MB_ICONINFORMATION );

    dat->winClass->style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    dat->winClass->lpfnWndProc   = ( WNDPROC ) eventHandler;
    dat->winClass->cbClsExtra    = 1;
    dat->winClass->cbWndExtra    = 1;
    dat->winClass->cbSize        = sizeof( WNDCLASSEXA );
    dat->winClass->hInstance     = dat->hInstance;
    dat->winClass->hIcon         = LoadIcon( NULL, IDI_WINLOGO );
    dat->winClass->hCursor       = LoadCursor( NULL, IDC_ARROW );
    dat->winClass->hbrBackground = ( HBRUSH ) GetStockObject( WHITE_BRUSH );
    dat->winClass->lpszMenuName  = NULL;
    dat->winClass->lpszClassName = "PongDH";

    if ( !RegisterClassExA( dat->winClass ) )
    {
        MessageBoxA( NULL, "Failed to register class.", "ERROR", MB_OK | MB_ICONINFORMATION );
        exit( 1 );
    }

    if ( dat->fullscreen )
    {
        memset( &dat->screenSettings, 0, sizeof( dat->screenSettings ) );

        dat->screenSettings.dmSize          = sizeof( dat->screenSettings );
        dat->screenSettings.dmPelsWidth     = width;
        dat->screenSettings.dmPelsHeight    = height;
        dat->screenSettings.dmBitsPerPel    = bitsPerPixel;
        dat->screenSettings.dmFields        = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        if ( ChangeDisplaySettingsA( &dat->screenSettings, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL )
        {
            dat->fullscreen = false;



            const int continuePlaying = MessageBoxA(
                NULL,
                "Could not implement fullscreen. Please check your drivers. Do you plan to continue?",
                "ERROR",
                MB_YESNO | MB_ICONEXCLAMATION
            );

            if ( continuePlaying == IDYES )
            {
                MessageBoxA( NULL, "Will revert back to fullscreen.", "Notifcation", MB_OK );
                dat->fullscreen = false;
            }
            else
            {
                MessageBoxA( NULL, "The program will now close", "Notification", MB_OK );
                exit( 1 );
            }
        }

    }

    if ( dat->fullscreen )
    {
        dat->dwExStyle = WS_EX_APPWINDOW;
        dat->dwStyle = WS_POPUP;
        ShowCursor( FALSE );
    }
    else
    {
        dat->dwExStyle  = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dat->dwStyle    = WS_OVERLAPPEDWINDOW;
    }

    AdjustWindowRectEx( &dat->winRect, dat->dwStyle, FALSE, dat->dwExStyle );

    dat->hwnd = CreateWindowExA(
                    dat->dwStyle,
                    dat->winClass->lpszClassName,
                    "PongDH",
                    WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    dat->winRect.right,
                    dat->winRect.bottom,
                    NULL,
                    NULL,
                    dat->hInstance,
                    NULL
                );


    if ( dat->hwnd == NULL )
    {
        MessageBoxA( NULL, "Failed to create window; exiting program.", "ERROR", MB_OK | MB_ICONEXCLAMATION );
        exit( 1 );
    }

    const int attrList[] =
    {
        WGL_DRAW_TO_WINDOW_ARB  , GL_TRUE,
        WGL_SUPPORT_OPENGL_ARB  , GL_TRUE,
        WGL_DOUBLE_BUFFER_ARB   , GL_TRUE,
        WGL_PIXEL_TYPE_ARB      , WGL_TYPE_RGBA_ARB,
        WGL_COLOR_BITS_ARB      , 32,
        WGL_DEPTH_BITS_ARB      , 24,
        WGL_STENCIL_BITS_ARB    , 8,
        0,
    };

    wglChoosePixelFormatARB( dat->hdc, attrList, NULL, 1, &dat->pixelFormat, &dat->numFormats );

    const int contextList[] =
    {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 3,
        0,
    };

    dat->hrc = wglCreateContextAttribsARB( dat->hdc, NULL, contextList );

    if( !wglMakeCurrent( dat->hdc, dat->hrc ) )
    {
        MessageBoxA( NULL, "Error making OpenGL Rendering Context current.", "ERROR", MB_OK | MB_ICONEXCLAMATION );
        exit( 1 );
    }

    ShowWindow( dat->hwnd, SW_SHOW );
    SetForegroundWindow( dat->hwnd );
    SetFocus( dat->hwnd );
    resizeScene( width, height );

    UpdateWindow( dat->hwnd );

    glEnable( GL_DEPTH_TEST );

    return dat;
}

更新

在这里,我将发布我所做的过程:

我首先尝试将cbClsExtra设置为1,然后将其设置为0.然后我将cbWndExtra设置为1.之后我尝试将cbSize设置为sizeof( WNDCLASSEXA )

我也尝试在VC ++和MinGW下进行编译;在VC ++中,该类无法注册,而在MinGW中,类将注册,但它实际上不会创建所需的hwnd

我还尝试通过使WNDCLASSEXAdat->winClass)指针而不是堆栈分配变量来编辑我的代码。

我还在我的exit项检查中评论了我的if个功能,看看是否注册,或者{ {1}} 不是创建的。这会在尝试使用hwnd呈现OpenGL上下文时产生分段错误。

更新2

这是我的WndProc:

wglChoosePixelFormatARB

0 个答案:

没有答案