📄 5dg_window.cpp
字号:
GL_Window* window = (GL_Window*)(GetWindowLong(hWnd, GWL_USERDATA));
switch (uMsg) // 取得Window的消息值
{
case WM_SYSCOMMAND: // 截取系统命令
{
switch (wParam) // 监听系统调用
{
case SC_SCREENSAVE: // 要运行屏保(Screensaver)?
case SC_MONITORPOWER: // 显示器进入节电模式(Powersave)?
return 0; // 提前返回0,防止系统调用执行
}
break; // 退出
}
case WM_CREATE: // 创建Window
{
CREATESTRUCT* creation = (CREATESTRUCT*)(lParam); // 保存窗口结构指针
window = (GL_Window*)(creation->lpCreateParams);
SetWindowLong(hWnd, GWL_USERDATA, (LONG)(window)); // 改变窗口属性
return 0; // 返回
}
case WM_CLOSE: // 关闭窗口
{
PostMessage(window->hWnd, WM_QUIT, 0, 0); // 结束程序
g_isProgramLooping = FALSE;
return 0;
}
case WM_SIZE: // WM_SIZE消息处理
switch (wParam) // 判断消息句柄
{
case SIZE_MINIMIZED: // 窗口最小化?
window->isVisible = FALSE; // 设置isVisible 为 FALSE
return 0;
case SIZE_MAXIMIZED: // 窗口最大化?
window->isVisible = TRUE; // 设置isVisible 为 TRUE
ResizeWindowGL (LOWORD (lParam), HIWORD (lParam)); // 修改窗口大小为 Width=LoWord, Height=HiWord
return 0; // 返回
case SIZE_RESTORED: // 窗口还原?
window->isVisible = TRUE; // 设置isVisible 为 TRUE
ResizeWindowGL (LOWORD (lParam), HIWORD (lParam)); // 修改窗口大小为 Width=LoWord, Height=HiWord
return 0; // 返回
}
break; // 退出
case WM_KEYDOWN: // 更新键盘缓冲区
if ((wParam >= 0) && (wParam <= 255)) // 按键是否合法?
{
window->keys->keyDown[wParam] = TRUE; // 设相应键为 TRUE (被按下的键)
return 0; // 返回
}
break; // 退出
case WM_KEYUP: // 松开按键的时候更新键盘缓冲
if ((wParam >= 0) && (wParam <= 255)) // 按键是否合法?
{
window->keys->keyDown[wParam] = FALSE; // 设相应键为 FALSE (被释放的键)
return 0; // 返回
}
break; // 退出
case WM_TOGGLEFULLSCREEN: // 切换全屏/窗口模式
{
g_createFullScreen = !g_createFullScreen;
PostMessage(hWnd, WM_QUIT, 0, 0);
break; // 退出
}
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam); // 将本程序不处理的消息传给 DefWindowProc
}
BOOL RegisterWindowClass(Application* application) // 为本应用程序注册一个类.
{
WNDCLASSEX windowClass; // 窗口类
ZeroMemory(&windowClass, sizeof(WNDCLASSEX)); // 清空内存
windowClass.cbSize = sizeof(WNDCLASSEX); // 窗口类的大小
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // 在移动,改变大小的时候重绘
windowClass.lpfnWndProc = (WNDPROC)(WindowProc); // 用WindowProc函数处理消息
windowClass.hInstance = application->hInstance; // 设置实例
windowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); // 类背景的画刷颜色
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // 载入箭头光标
windowClass.lpszClassName = application->className; // 设置应用程序的类名
if (RegisterClassEx(&windowClass) == 0) // 注册类失败?
{
MessageBox(HWND_DESKTOP, "应用程序类注册失败!\nRegisterClassEx Failed!", "Error", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回FALSE (注册失败)
}
return TRUE; // 返回TRUE (注册成功)
}
// 应用程序的入口 (WinMain)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Application application; // 应用程序
GL_Window window; // 窗口
Keys keys; // 键盘按键
MSG msg; // Window消息
BOOL isMessagePumpActive;
// 给应用程序赋值
application.className = CLASSNAME; // 程序类名字
application.hInstance = hInstance; // 程序入口
// 窗口相关信息设置
ZeroMemory(&window, sizeof(GL_Window)); // 清零窗口变量的内存空间
window.keys = &keys; // 设置按键
window.init.application = &application; // 设置窗口程序
window.init.title = TITLE; // 设置标题
window.init.width = WIDTH; // 设置窗口宽度
window.init.height = HEIGHT; // 设置窗口高度
window.init.bitsPerPixel = BPP; // 设置每像素的位数
window.init.isFullScreen = FALSE; // 设置初始窗口是否全屏否(FALSE)
ZeroMemory(&keys, sizeof(Keys)); // 键盘缓冲清零
if (RegisterWindowClass(&application) == FALSE) // 注册类是否失败
{
MessageBox(HWND_DESKTOP, "窗口类注册失败!\nError Registering Window Class!", "Error", MB_OK | MB_ICONEXCLAMATION);
return -1; // 结束程序
}
g_isProgramLooping = TRUE; // 将g_isProgramLooping设TRUE
g_createFullScreen = window.init.isFullScreen; // g_createFullScreen 设为默认值
while (g_isProgramLooping) // 循环直到程序停止
{
// 建立窗口
window.init.isFullScreen = g_createFullScreen; // 传递是否全屏信息
if (CreateWindowGL(&window) == TRUE) // 创建GL窗口成功否?
{
if (Initialize(&window, &keys) == FALSE) // 初始化
{
// 失败
PostMessage(window.hWnd, WM_QUIT, 0, 0); // 抛出消息WM_QUIT
g_isProgramLooping = FALSE;
}
else
{ // 初始化成功
isMessagePumpActive = TRUE; // 设isMessagePumpActive为TRUE
while (isMessagePumpActive == TRUE) // 当isMessagePumpActive为TRUE时
{
// 成功建立窗口,监测Window消息
if (PeekMessage(&msg, window.hWnd, 0, 0, PM_REMOVE) != 0)
{
// 检测WM_QUIT消息
if (msg.message != WM_QUIT) // WM_QUIT消息?
{
DispatchMessage(&msg); // 如果不是,分派消息
}
else // 否则(消息是WM_QUIT)
{
isMessagePumpActive = FALSE; // 结束 Message Pump
}
}
else // 如果没有消息
{
if (window.isVisible == FALSE) // 如果窗口不可见
{
WaitMessage(); // 等待消息
}
else // 如果窗口可见
{
Update(); // 更新处理消息事件
DrawSceneGL(); // 绘制场景
SwapBuffers(window.hDC); // 交换缓存
}
}
} // 当isMessagePumpActive 为TRUE时循环执行
}
// 程序结束
Deinitialize(); // 做扫尾工作
DestroyWindowGL(&window); // 销毁窗口
}
else // 如果窗口创建失败
{
MessageBox(HWND_DESKTOP, "创建OpenGL窗口失败\nError Creating OpenGL Window", "Error", MB_OK | MB_ICONEXCLAMATION);
g_isProgramLooping = FALSE; // 结束循环
}
}
UnregisterClass(application.className, application.hInstance); // 注销窗口类
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -