C ++ windows程序消耗30%的CPU,过时的API使用率?

时间:2015-08-07 15:47:33

标签: c windows

我一直在关注windows / OpenGl编程的Cprogramming教程,到目前为止取得了很好的成功;除了我非常简单的Windows程序消耗30%的CPU,显示旋转,无响应的游标,并且不会从任务管理器的使用中退出。

因为本教程针对的是比我使用的版本更旧的Windows版本(8),我很可能滥用API。我认为最有可能是

  • A):忽略了要包含的重要文件,

  • B):利用了一个 仍然功能齐全但有缺陷的Windows软件,或

  • C): 错误编程了API的一部分(WndProc,!完成循环,可能?) 导致它表现得不好。

我的程序代码与此站点上的程序代码相同,减去" stdafx.h"(我找不到这个标题,这可能是我的问题),并添加了一些我自己编写的文件描述了我正在处理的独立程序,并且自己工作得很好。

http://www.cprogramming.com/tutorial/opengl_first_windows_app.html

理想情况下,某人可以向我显示我的错误或“正确的”错误。为Windows 8编程的方法。

编辑:这里是代码(感谢robin.koch for while(Getmessage()):

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

        PAINTSTRUCT paintStruct;

        HDC hDC;

        char string[] = "Hello, world!";

        switch (message){

        case WM_CREATE:
                    return 0;
                    break;

                case WM_CLOSE:
                    PostQuitMessage(0);
                    return 0;
                    break;


                case WM_PAINT:
                    hDC = BeginPaint(hwnd, &paintStruct);

                    SetTextColor(hDC, COLORREF(0x00FF0000));//blue text

                    TextOut(hDC, 150, 150, string, sizeof(string) - 1);
                    EndPaint(hwnd, &paintStruct);

                    return 0;
                    break;

                default:
                    break;


        }//switch(message)




    };


    int APIENTRY WinMain(   HINSTANCE       hInstance,
                            HINSTANCE       hPrevInstance,
                            LPSTR           lpCmdLine,
                            int             nCmdShow
                ){  

            WNDCLASSEX windowClass;
            HWND hwnd;//window handle
            MSG msg;
            bool done;



        windowClass.cbSize = sizeof(WNDCLASSEX);
        windowClass.style = CS_HREDRAW | CS_VREDRAW;
        windowClass.lpfnWndProc = WndProc;
        windowClass.cbClsExtra = 0;
        windowClass.cbWndExtra = 0;
        windowClass.hInstance = hInstance;
        windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        windowClass.lpszMenuName = NULL;
        windowClass.lpszClassName = "MyClass";
        windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

        if (!RegisterClassEx(&windowClass)){
            return 0;
        }


        hwnd = CreateWindowEx(NULL,//extended style
            "MyClass",//App name
            "A real win app",//app name
            WS_OVERLAPPEDWINDOW | //window style
            WS_VISIBLE |
            WS_SYSMENU,
            100, 100,       //x/y coords
            400, 400,       //width, height)
            NULL, //parent handle
            NULL, //Menu handle
            hInstance, //Application instance
            NULL//No extra parameters
            );


        //check if failed window creation

        if (!hwnd)
            return 0;

        done = false;


        while (GetMessage(&msg, NULL, 0, 0)){
        if (!IsDialogMessage(hwnd, &msg)){
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            }
        }

            return msg.wParam;}

1 个答案:

答案 0 :(得分:3)

while(!done)
    {
        PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE);
        if (msg.message == WM_QUIT) //check for a quit message
        {
            done = true; //if found, quit app
        }
        else
        {
            /*  Translate and dispatch to event queue*/
            TranslateMessage(&msg); 
            DispatchMessage(&msg);
        }
    }

这就是为什么你有这么高的CPU负载。如果没有可用消息,PeekMessage()不会阻止,它只返回false。因此,由于while循环,您一次又一次地调用此函数...而是使用GetMessage()函数。

while(GetMessage(&msg, NULL, 0, 0))
  {
    if(!IsDialogMessage(hWnd, &msg))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

这是我在当前项目中使用GetMessage()的示例 此外,窗口过程中的default:路径不应只是break,而是调用

return DefWindowProc(hWnd, message, wParam, lParam);

这可以确保您自己未处理的邮件由默认函数处理。有关详细信息,请参阅https://msdn.microsoft.com/de-de/library/windows/desktop/ms633572%28v=vs.85%29.aspx。 这是如何编写窗口proc:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
        PAINTSTRUCT paintStruct;
        HDC hDC;
        char string[] = "Hello, world!";

        switch (message){

        case WM_CREATE:
                    break;
                // WM_CLOSE is used if we want to do something BEFORE the window is destroyed. WM_CLOSE is now handled by the DefWindowProc. We handle WM_DESTROY instead
                case WM_DESTROY:
                    PostQuitMessage(0); // here we are telling the message loop in WinMain to stop
                    return 0; // here we don't want the DefWindowProc to be called. So we return before it is called.
                    break;
                case WM_PAINT:
                    hDC = BeginPaint(hwnd, &paintStruct);

                    SetTextColor(hDC, COLORREF(0x00FF0000));//blue text

                    TextOut(hDC, 150, 150, string, sizeof(string) - 1);
                    EndPaint(hwnd, &paintStruct);

                    break;
        }//switch(message)
        // Always call the DefWindowProc
        return DefWindowProc(hWnd, message, wParam, lParam);
    }