我一直在关注windows / OpenGl编程的Cprogramming教程,到目前为止取得了很好的成功;除了我非常简单的Windows程序消耗30%的CPU,显示旋转,无响应的游标,并且不会从任务管理器的使用中退出。
因为本教程针对的是比我使用的版本更旧的Windows版本(8),我很可能滥用API。我认为最有可能是
A):忽略了要包含的重要文件,
B):利用了一个 仍然功能齐全但有缺陷的Windows软件,或
我的程序代码与此站点上的程序代码相同,减去" 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;}
答案 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);
}