Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;Windows没有收到任何消息_C++_Windows_Message - Fatal编程技术网

C++ C++;Windows没有收到任何消息

C++ C++;Windows没有收到任何消息,c++,windows,message,C++,Windows,Message,我正在创建一个简单的窗口,但当我看到正在创建的窗口并将其关闭时,不会收到WM_退出消息。下面是一些代码: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) { cWindowApplication app(hInstance); const long width = 1024L; const long height = 768L;

我正在创建一个简单的窗口,但当我看到正在创建的窗口并将其关闭时,不会收到WM_退出消息。下面是一些代码:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
{
    cWindowApplication app(hInstance);

    const long width = 1024L;
    const long height = 768L;

    if (app.CreateWindowApplication(width, height) == false)
    {
        MessageBox(NULL, "Unable to create OpenGL Window", "An error occurred", MB_ICONERROR | MB_OK);
        app.DestroyWindowApplication();
        return 1;
    }

    return app.MainLoop();
}
以下是CreateWindowApplication(int,int)函数:

bool cWindowApplication::CreateWindowApplication(long width, long height, bool full_screen /*= false*/)
{
    DWORD dwExStyle;    // Window Extended Style
    DWORD dwStyle;      // Window Style

    mWindowRect.left = 0L;          // Set Left Value To 0
    mWindowRect.right = width;      // Set Right Value To Requested Width
    mWindowRect.top = 0L;           // Set Top Value To 0
    mWindowRect.bottom = height;    // Set Bottom Value To Requested Height

    mFullScreen = full_screen;

    // fill out the window class structure
    const char* class_name      = "MyClass";
    mWindowClass.cbSize         = sizeof(WNDCLASSEX);
    mWindowClass.style          = CS_HREDRAW | CS_VREDRAW;
    mWindowClass.lpfnWndProc    = cWindowApplication::StaticWindowsProcessCallback;
    mWindowClass.cbClsExtra     = 0;
    mWindowClass.cbWndExtra     = 0;
    mWindowClass.hInstance      = mhInstance;
    mWindowClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);          // default icon
    mWindowClass.hCursor        = LoadCursor(NULL, IDC_ARROW);              // default arrow
    mWindowClass.hbrBackground  = NULL;                                     // don't need background
    mWindowClass.lpszMenuName   = NULL;                                     // no menu
    mWindowClass.lpszClassName  = class_name;
    mWindowClass.hIconSm        = LoadIcon(NULL, IDI_WINLOGO);              // windows logo small icon

    // register the windows class
    if (!RegisterClassEx(&mWindowClass))
    {
        return false;
    }

    if (mFullScreen == true) //If we are Full Screen, we need to change the display mode                             
    {
        DEVMODE dmScreenSettings;                           // device mode

        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize = sizeof(dmScreenSettings);

        dmScreenSettings.dmPelsWidth = width;               // screen width
        dmScreenSettings.dmPelsHeight = height;             // screen height
        dmScreenSettings.dmBitsPerPel = BITS_PER_PIXEL;     // bits per pixel
        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {
            // setting display mode failed, switch to windowed
            MessageBox(NULL, "Display mode failed", NULL, MB_OK);
            mFullScreen = false;
        }
    }

    if (mFullScreen == true)                // Are We Still In Full Screen Mode?
    {
        dwExStyle = WS_EX_APPWINDOW;        // Window Extended Style
        dwStyle =   WS_POPUP;               // Windows Style
        //ShowCursor(false);                  // Hide Mouse Pointer
    }
    else
    {
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   // Window Extended Style
        dwStyle = WS_OVERLAPPEDWINDOW;                    // Windows Style
    }

    AdjustWindowRectEx(&mWindowRect, dwStyle, false, dwExStyle);     // Adjust Window To True Requested Size

    // class registered, and create our window
    mHWND = CreateWindowEx(NULL,                            // extended style
        class_name,                                         // class name
        "My Windows",                           // application name
        dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0,                                               // x,y coordinate
        mWindowRect.right - mWindowRect.left,
        mWindowRect.bottom - mWindowRect.top,               // width, height
        NULL,                                               // handle to parent
        NULL,                                               // handle to menu
        mhInstance,                                         // application instance
        this);                                              // this pointer to call member functions

    // check if window creation failed (hwnd would equal NULL)
    if (mHWND == false)
    {
        return false;
    }

    mHDC = GetDC(mHWND);

    ShowWindow(mHWND, SW_SHOW);          // display the window
    UpdateWindow(mHWND);                 // update the window
    return true;
}
基本上,在此函数调用之后,CreateWindowEx()函数将调用StaticWindowProcessCallback(),如下所示:

LRESULT cWindowApplication::StaticWindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    cWindowApplication* win_app = NULL;

    if (msg == WM_CREATE)
    {
        //Creation event
        //Get the pointer we pass during CreateWindowApplication() call
        win_app = (cWindowApplication*)((LPCREATESTRUCT)lParam)->lpCreateParams;

        //Associate window pointer with the hwnd for the other events to access
        SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)win_app);
    }
    else
    {
        //Non-creation event
        win_app = (cWindowApplication*)GetWindowLongPtr(wnd, GWLP_USERDATA);

        if (win_app != NULL)
        {
            return DefWindowProc(wnd, msg, wParam, lParam);
        }
    }

    //call member
    return win_app->WindowsProcessCallback(wnd, msg, wParam, lParam);
}
LRESULT cWindowApplication::WindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
    {
        mHDC = GetDC(wnd);
        SetupPixelFormat();
        //Set the version that we want, in this case 3.0
        int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0 };  //zero indicates the end of the array
        //Create temporary context so we can get a pointer to the function
        HGLRC tmp_context = wglCreateContext(mHDC);
        //Make it current
        wglMakeCurrent(mHDC, tmp_context);

        PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
        wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

        if (wglCreateContextAttribsARB == NULL)
        {
            //No OpenGL 3.0, back to 2.0
            mHGLRC = tmp_context;
        }
        else
        {
            //Create OpenGL 3.0
            mHGLRC = wglCreateContextAttribsARB(mHDC, 0, attribs);
            //Delete the temp context
            wglDeleteContext(tmp_context);
        }

        //Make OpenGL 3.0
        wglMakeCurrent(mHDC, mHGLRC);
        mIsRunning = true;
    }
        break;
    case WM_QUIT:
    case WM_DESTROY:
    case WM_CLOSE:
        wglMakeCurrent(mHDC, NULL);
        wglDeleteContext(mHGLRC);
        mIsRunning = false;
        PostQuitMessage(0); //Send a WM_QUIT message
        return 0;
    default:
        break;
    }

    return DefWindowProc(wnd, msg, wParam, lParam);
}
int cWindowApplication::MainLoop()
{
    while (mIsRunning == true)
    {
        ProcessWindowsMessages();
    }

    DestroyWindowApplication();
    return 0;
}
void cWindowApplication::ProcessWindowsMessages()
{
    MSG msg;

    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
最后,此函数的最后一行调用成员函数WindowProcessCallback(),如下所示:

LRESULT cWindowApplication::StaticWindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    cWindowApplication* win_app = NULL;

    if (msg == WM_CREATE)
    {
        //Creation event
        //Get the pointer we pass during CreateWindowApplication() call
        win_app = (cWindowApplication*)((LPCREATESTRUCT)lParam)->lpCreateParams;

        //Associate window pointer with the hwnd for the other events to access
        SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)win_app);
    }
    else
    {
        //Non-creation event
        win_app = (cWindowApplication*)GetWindowLongPtr(wnd, GWLP_USERDATA);

        if (win_app != NULL)
        {
            return DefWindowProc(wnd, msg, wParam, lParam);
        }
    }

    //call member
    return win_app->WindowsProcessCallback(wnd, msg, wParam, lParam);
}
LRESULT cWindowApplication::WindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
    {
        mHDC = GetDC(wnd);
        SetupPixelFormat();
        //Set the version that we want, in this case 3.0
        int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0 };  //zero indicates the end of the array
        //Create temporary context so we can get a pointer to the function
        HGLRC tmp_context = wglCreateContext(mHDC);
        //Make it current
        wglMakeCurrent(mHDC, tmp_context);

        PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
        wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

        if (wglCreateContextAttribsARB == NULL)
        {
            //No OpenGL 3.0, back to 2.0
            mHGLRC = tmp_context;
        }
        else
        {
            //Create OpenGL 3.0
            mHGLRC = wglCreateContextAttribsARB(mHDC, 0, attribs);
            //Delete the temp context
            wglDeleteContext(tmp_context);
        }

        //Make OpenGL 3.0
        wglMakeCurrent(mHDC, mHGLRC);
        mIsRunning = true;
    }
        break;
    case WM_QUIT:
    case WM_DESTROY:
    case WM_CLOSE:
        wglMakeCurrent(mHDC, NULL);
        wglDeleteContext(mHGLRC);
        mIsRunning = false;
        PostQuitMessage(0); //Send a WM_QUIT message
        return 0;
    default:
        break;
    }

    return DefWindowProc(wnd, msg, wParam, lParam);
}
int cWindowApplication::MainLoop()
{
    while (mIsRunning == true)
    {
        ProcessWindowsMessages();
    }

    DestroyWindowApplication();
    return 0;
}
void cWindowApplication::ProcessWindowsMessages()
{
    MSG msg;

    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
如您所见,这里有一些消息处理代码。。。但除了WM_CREATE,没有其他案例受到影响。发送WM_CREATE消息后,调用函数MainLoop(),如下所示:

LRESULT cWindowApplication::StaticWindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    cWindowApplication* win_app = NULL;

    if (msg == WM_CREATE)
    {
        //Creation event
        //Get the pointer we pass during CreateWindowApplication() call
        win_app = (cWindowApplication*)((LPCREATESTRUCT)lParam)->lpCreateParams;

        //Associate window pointer with the hwnd for the other events to access
        SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)win_app);
    }
    else
    {
        //Non-creation event
        win_app = (cWindowApplication*)GetWindowLongPtr(wnd, GWLP_USERDATA);

        if (win_app != NULL)
        {
            return DefWindowProc(wnd, msg, wParam, lParam);
        }
    }

    //call member
    return win_app->WindowsProcessCallback(wnd, msg, wParam, lParam);
}
LRESULT cWindowApplication::WindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
    {
        mHDC = GetDC(wnd);
        SetupPixelFormat();
        //Set the version that we want, in this case 3.0
        int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0 };  //zero indicates the end of the array
        //Create temporary context so we can get a pointer to the function
        HGLRC tmp_context = wglCreateContext(mHDC);
        //Make it current
        wglMakeCurrent(mHDC, tmp_context);

        PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
        wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

        if (wglCreateContextAttribsARB == NULL)
        {
            //No OpenGL 3.0, back to 2.0
            mHGLRC = tmp_context;
        }
        else
        {
            //Create OpenGL 3.0
            mHGLRC = wglCreateContextAttribsARB(mHDC, 0, attribs);
            //Delete the temp context
            wglDeleteContext(tmp_context);
        }

        //Make OpenGL 3.0
        wglMakeCurrent(mHDC, mHGLRC);
        mIsRunning = true;
    }
        break;
    case WM_QUIT:
    case WM_DESTROY:
    case WM_CLOSE:
        wglMakeCurrent(mHDC, NULL);
        wglDeleteContext(mHGLRC);
        mIsRunning = false;
        PostQuitMessage(0); //Send a WM_QUIT message
        return 0;
    default:
        break;
    }

    return DefWindowProc(wnd, msg, wParam, lParam);
}
int cWindowApplication::MainLoop()
{
    while (mIsRunning == true)
    {
        ProcessWindowsMessages();
    }

    DestroyWindowApplication();
    return 0;
}
void cWindowApplication::ProcessWindowsMessages()
{
    MSG msg;

    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
基本上,ProcessWindowsMessages()函数在窗口关闭后不会获取任何消息。。。我必须按下停止VS以停止运行进程。ProcessWindowsMessages()函数如下所示:

LRESULT cWindowApplication::StaticWindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    cWindowApplication* win_app = NULL;

    if (msg == WM_CREATE)
    {
        //Creation event
        //Get the pointer we pass during CreateWindowApplication() call
        win_app = (cWindowApplication*)((LPCREATESTRUCT)lParam)->lpCreateParams;

        //Associate window pointer with the hwnd for the other events to access
        SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)win_app);
    }
    else
    {
        //Non-creation event
        win_app = (cWindowApplication*)GetWindowLongPtr(wnd, GWLP_USERDATA);

        if (win_app != NULL)
        {
            return DefWindowProc(wnd, msg, wParam, lParam);
        }
    }

    //call member
    return win_app->WindowsProcessCallback(wnd, msg, wParam, lParam);
}
LRESULT cWindowApplication::WindowsProcessCallback(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
    {
        mHDC = GetDC(wnd);
        SetupPixelFormat();
        //Set the version that we want, in this case 3.0
        int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0 };  //zero indicates the end of the array
        //Create temporary context so we can get a pointer to the function
        HGLRC tmp_context = wglCreateContext(mHDC);
        //Make it current
        wglMakeCurrent(mHDC, tmp_context);

        PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
        wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

        if (wglCreateContextAttribsARB == NULL)
        {
            //No OpenGL 3.0, back to 2.0
            mHGLRC = tmp_context;
        }
        else
        {
            //Create OpenGL 3.0
            mHGLRC = wglCreateContextAttribsARB(mHDC, 0, attribs);
            //Delete the temp context
            wglDeleteContext(tmp_context);
        }

        //Make OpenGL 3.0
        wglMakeCurrent(mHDC, mHGLRC);
        mIsRunning = true;
    }
        break;
    case WM_QUIT:
    case WM_DESTROY:
    case WM_CLOSE:
        wglMakeCurrent(mHDC, NULL);
        wglDeleteContext(mHGLRC);
        mIsRunning = false;
        PostQuitMessage(0); //Send a WM_QUIT message
        return 0;
    default:
        break;
    }

    return DefWindowProc(wnd, msg, wParam, lParam);
}
int cWindowApplication::MainLoop()
{
    while (mIsRunning == true)
    {
        ProcessWindowsMessages();
    }

    DestroyWindowApplication();
    return 0;
}
void cWindowApplication::ProcessWindowsMessages()
{
    MSG msg;

    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

StaticWindowsProcessCallback
中的此逻辑向后看:

    if (win_app != NULL)
    {
        return DefWindowProc(wnd, msg, wParam, lParam);
    }
如果没有指向窗口包装器对象的指针,则需要调用
DefWindowProc
。因此,如果(win\u app==NULL),应该会发生这种情况。这是为了处理在
WM\u CREATE
之前发送的少量消息。因此,您的代码在
WM\u CREATE
之前处理的消息上具有未定义的行为,并且在
WM\u CREATE
之后丢弃(通过应用默认处理)所有消息

不过,使用
WM\NCCREATE
设置链接会更好。同样,
win_app
也不是一个很好的名字,可能是
win_obj
或其他什么

您也不应该在窗口过程中处理
WM_QUIT
,因为它不会发送到窗口。而
WM\u CLOSE
的默认行为应该很好,它将调用
DESTROY窗口
,这将触发
WM\u DESTROY


但是第一,在
WM\u CREATE
之后没有将任何消息转发到您的窗口过程,这可能解释了主消息循环中缺少
WM\u QUIT

谢谢,这就解释了一切。我在看另一个源代码,他们有if(!win_app)。。。我把它翻译错了。可能是因为你应该能够通过调试器找到它,如果你知道它应该如何运行的话。引入第三方代码时,请确保您理解它。如果是这样,则不需要此网站。您可以阅读一些常见问题解答。此站点不应用于调试帮助。你的问题是,即使将来有人有完全相同的问题,他们也无法找到你的问题和我的解决方案。(不是你的错;我也想不出一个好的标题或搜索词)好的,我会尽力的。当您连续几天尝试调试,但仍然不知道出了什么问题时,这是很困难的。无论如何,很高兴它现在可以工作了。