【问题标题】:Why is this pointer (pGame inside WinProc) NULL?为什么这个指针(WndProc 中的游戏)为 NULL?
【发布时间】:2013-03-18 21:41:36
【问题描述】:

这是我的 WinMain:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
    if(SUCCEEDED(CoInitialize(NULL)))
    {
        {
            Game game;

            game.CreateRessources(hInst);

            game.ShowMainScreen();

            HWND hwnd=game.Getm_hWnd();
            HWND* pHWND=&hwnd;

            game.pWinsock->Initialize(hwnd);

            ShowWindow(game.Getm_hWnd(),SW_MAXIMIZE);
            UpdateWindow(game.Getm_hWnd());

            MSG msg;
            ZeroMemory(&msg,sizeof(MSG));

            while(GetMessage(&msg,NULL,0,0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        CoUninitialize();
    }

    return 0;
}

还有我的窗口创建类:

void Game::CreateWindowClass(HINSTANCE hInst)
{
    // Create a window class
    WNDCLASSEX wClass;
    ZeroMemory(&wClass,sizeof(WNDCLASSEX));
    wClass.cbClsExtra=NULL;
    wClass.cbSize=sizeof(WNDCLASSEX);
    wClass.cbWndExtra=NULL;
    wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
    wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wClass.hIcon=NULL;
    wClass.hIconSm=NULL;
    wClass.hInstance=hInst;
    wClass.lpfnWndProc=WinProc;
    wClass.lpszClassName="Window Class";
    wClass.lpszMenuName=NULL;
    wClass.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&wClass))
    {
        int nResult=GetLastError();

        MessageBox(NULL,"Failed to register window class","Window Class Failed",MB_ICONERROR);
    }

    m_hWnd=CreateWindowEx(NULL,
            "Window Class",
            "Game",
            WS_OVERLAPPEDWINDOW|WS_MAXIMIZE,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            NULL,
            NULL,
            hInst,
            this);

    if(!m_hWnd)
    {
        int nResult=GetLastError();

        MessageBox(NULL,"Window class creation failed","Window Class Failed",MB_ICONERROR);
    }
}

这是游戏::CreateRessources:

void Game::CreateRessources(HINSTANCE hInst)
{   
    CreateWindowClass(hInst);

    pD2DResources=CreateD2DResources(m_hWnd);
    pMessageLog=CreateMessageLog();
    pWinsock=CreateWinsock();
}

最后,我的 WinProc 在以下几行之后:if(pGame==NULL) MessageBox(NULL,"Pointer pGame 为 NULL","Error",NULL);

LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if(msg==WM_CREATE)
    {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
            Game* pGame = (Game*)pcs->lpCreateParams;

            ::SetWindowLongPtrW(
                hWnd,
                GWLP_USERDATA,
                PtrToUlong(pGame)
                );
    }

    else if(msg==WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }

    else
    {
        Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hWnd,
                GWLP_USERDATA
                )));

        if(pGame==NULL)
            MessageBox(NULL,"Pointer pGame is NULL","Error",NULL);

        if(pGame->pD2DResources!=NULL)
        {
            switch(msg)
            {

由于某种原因,pGame 为 NULL,因为 MessageBox 弹出。为什么会这样?

编辑:顺便说一句,我正在动态创建一些对象,并且我的游戏对象内的私有指针被分配给这些动态创建的对象。会不会和问题有关?

【问题讨论】:

  • 在 if(msg==WM_CREATE) 下面的括号中,以及下面的其他几行。
  • 很高兴知道。在 WM_CREATE 之前发送了哪些消息?
  • WM_NCCREATEWM_CREATE 之前发送,但这不是问题,因为this 指针与WM_CREATE 消息一起发送。我看不到所有代码,但您应该在调用SetWindowLongPtrW 后返回TRUE
  • 您可以在这里找到更好的 C++ 应用程序模板:blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx。它可以正确获取所有指针内容和窗口创建消息。
  • 您是否尝试过使用调试器单步执行您的 WndProc?如果没有,为什么不呢?

标签: c++ windows oop winapi pointers


【解决方案1】:

因为WM_CREATE 不是窗口过程收到的第一条消息。见WM_NCCREATE

【讨论】:

  • 我什至见过WM_GETMINMAX info之类的消息发生在WM_NCCREATE之前。
猜你喜欢
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 2016-05-23
  • 2011-08-22
相关资源
最近更新 更多