游戏引擎学习第40天

仓库 : https://gitee.com/mrxiao_com/2d_game

整理了一些需要完成的任务,确保所有内容都已清理完成,因为需要为后续的数学部分打好基础。下一步将认真开始处理数学相关内容,因此在此之前,需要彻底梳理未完成的事项,清除任何可能的障碍。

昨天已经完成了一些重要的任务,其中包括为调试符号创建一个锁文件,以避免热加载时出现问题,从而防止开发工具出现混淆。这个改进解决了一些稳定性问题。

还完成了一个重要的调整,使平台层的开发更加顺利。一些内容被移到了独立的模块中,以便更好地支持跨平台的开发流程。这部分工作也已完成。

目前剩余的内容中,有一些需要进一步核实的修复任务,以及为后续开发提供支持的改动。这些任务会在接下来的整理过程中逐步处理,以确保流程顺畅。

清理 tSine

发现有一个变量 tSine 的旧版本仍然存在,虽然已经不再使用,但它仍留在 win32 的声音模块中。这部分内容需要清理,以免后续开发者看到这个变量时感到困惑,不清楚它的用途。

计划清除这些遗留的变量,以确保代码的整洁和易读性。同时,还会对平台代码进行进一步梳理和优化,移除无用的内容,使代码更清晰,便于后续维护和扩展。

修改一下cmake的文件

关于 internallocal_persistglobal_variable 的用意

在讨论中提到的主要概念是如何使用 static 关键字和宏在 C++ 代码中的影响。人们在论坛上对使用 static 感到困惑,因为它在 C++ 中有多种含义,而宏则是处理代码的文本替换工具。使用宏时,关键字 static 会被替换为实际的定义,这样会影响代码的可搜索性和易于维护性,尤其在多线程编程和动态库(DLL)加载的情况下。

主要问题是,如果所有函数都前缀 static,它会使得自动化的代码搜索(grep)更加复杂,难以区分全局变量和局部变量。虽然宏在 C++ 中是必要的文本处理工具,但它们的使用可能带来可读性问题。

因此,开发者需要谨慎使用 static 和宏,以避免引入维护上的复杂性和潜在的错误。这就是为什么尽管有宏和 static 的便利,很多人还是倾向于使用较少的全局变量,并进行更加精细的依赖管理。

解决 SetCursor

你似乎在讨论应用程序中光标行为的问题,尤其是当光标进入窗口时的处理。你描述的问题是,由于你的软件没有响应 WM_SETCURSOR 消息,导致 Windows 不会改变光标状态,当它进入应用程序的窗口时。

为了解决这个问题,你计划实现一种机制来正确处理光标的变化。这包括:

  1. 检测光标进入应用窗口 :通过响应 WM_SETCURSOR 消息并设置一个适当的光标来处理当前的状态或上下文。
  2. 避免意外的行为:目前,由于光标在进入你的窗口之前的状态会保留,因此光标可能会看起来不正确。通过正确处理光标变化,可以避免这种问题,并确保当光标进入应用程序时总是显示适当的状态。

这项调整应改善用户体验,尤其是在编辑环境中光标的外观和行为尤为关键。

LoadCursor 是一个 Windows API 函数,用于加载光标资源。它的作用是从系统或者应用程序的资源文件中加载一个光标,并返回一个指向该光标的句柄。可以使用该光标句柄来设置窗口的光标或改变光标的样式。

函数原型

cpp 复制代码
HCURSOR LoadCursor(
  HINSTANCE hInstance, // 模块实例句柄,通常传入 NULL 表示加载系统光标
  LPCSTR    lpCursorName // 光标名称,或者是光标的资源标识符
);

参数说明

  1. hInstance:

    • 如果 hInstanceNULL,则会加载系统默认的光标资源(如箭头、等待光标等)。
    • 如果 hInstance 为非 NULL,则会加载指定模块(如应用程序的 .exe 文件)中的光标资源。
  2. lpCursorName:

    • 这是光标的名称或标识符。如果是系统光标,你可以传入一些预定义的标识符(例如:IDC_ARROWIDC_WAIT)。
    • 如果是自定义光标,lpCursorName 则是自定义光标资源的名称(该光标资源应该被打包到应用程序的资源文件中)。

返回值

  • 返回一个光标的句柄(HCURSOR),如果加载失败,则返回 NULL

常用的光标资源标识符

  • IDC_ARROW: 默认的箭头光标。
  • IDC_WAIT: 等待光标(通常是一个旋转的圆圈)。
  • IDC_IBEAM: 输入框光标(I-beam 光标,用于文本输入框)。
  • IDC_CROSS: 十字光标(通常用于选择区域或进行截图等操作)。
  • IDC_HAND: 手形光标(通常用于网页上的链接)。

示例代码

  1. 加载默认光标 :

    如果你只想加载系统默认的箭头光标,可以直接调用 LoadCursor,并传入 NULLIDC_ARROW

    cpp 复制代码
    HCURSOR hCursor = LoadCursor(NULL, IDC_ARROW);
  2. 加载自定义光标 :

    如果应用程序中包含自定义光标资源,你可以使用 LoadCursor 来加载它:

    cpp 复制代码
    HCURSOR hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDR_MY_CURSOR));

    这里 IDR_MY_CURSOR 是你在资源文件中定义的光标资源标识符。

  3. 改变窗口的光标 :

    你可以使用 SetCursor 函数将加载的光标设置为当前窗口的光标。

    cpp 复制代码
    SetCursor(hCursor);

使用场景

  • 在自定义应用程序中使用不同的光标样式来提供视觉反馈(例如,鼠标悬停在按钮上时更改光标样式)。
  • 在不同的操作状态下(如加载状态、文本输入状态等)显示不同的光标。

注意事项

  • LoadCursor 只能加载 16×16 或 32×32 像素的光标资源。如果需要加载更大的光标,通常可以使用 LoadImage 函数。
  • 需要记得在程序结束时释放通过 LoadCursor 加载的光标资源,虽然 Windows 系统会在程序结束时自动清理这些资源,但在使用一些特殊光标时可以主动释放。

总结来说,LoadCursor 是一个非常基础但重要的函数,用于管理和加载系统或自定义光标,是 GUI 开发中不可或缺的一部分。

全屏支持

cpp 复制代码
internal void ToggleFullscreen(HWND Window) {
    DWORD Style = GetWindowLong(Window, GWL_STYLE);  // 获取当前窗口的样式标志

    if (Style & WS_OVERLAPPEDWINDOW) {  // 如果窗口当前是一个常规的重叠窗口
        MONITORINFO MonitorInfo = {
            sizeof(MonitorInfo)};  // 创建一个 MONITORINFO 结构,用于存储显示器信息

        // 获取当前窗口的位置和大小,并获取该窗口所在的显示器信息
        if (GetWindowPlacement(Window, &GlobalWindowPosition) &&
            GetMonitorInfo(MonitorFromWindow(Window, MONITOR_DEFAULTTONEAREST), &MonitorInfo)) {
            // 将窗口的样式从重叠窗口(有标题栏、边框等)改为无边框窗口
            SetWindowLong(Window, GWL_STYLE, Style & ~WS_OVERLAPPEDWINDOW);

            // 设置窗口的位置和大小为当前显示器的工作区(全屏显示)
            SetWindowPos(
                Window, HWND_TOP, MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top,
                MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left,  // 设置窗口宽度
                MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top,  // 设置窗口高度
                SWP_NOOWNERZORDER | SWP_FRAMECHANGED);  // 不改变窗口的 Z 顺序,更新窗口的边框和样式
        }
    } else {  // 如果当前窗口已经是全屏(没有边框)模式
        // 恢复窗口为一个常规的重叠窗口(恢复边框和标题栏)
        SetWindowLongA(Window, GWL_STYLE, Style | WS_OVERLAPPEDWINDOW);

        // 恢复窗口到之前的位置和大小
        SetWindowPlacement(Window, &GlobalWindowPosition);

        // 设置窗口不改变位置和大小,只更新窗口的显示状态
        SetWindowPos(Window, 0, 0, 0, 0, 0,
                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
    }
}
相关推荐
人需要PID2 分钟前
【C语言练习(5)—回文数判断】
c语言·开发语言·学习·算法
Genevieve_xiao19 分钟前
【数模学习笔记】灰色关联分析
笔记·学习·数学建模
Genevieve_xiao24 分钟前
【数模学习笔记】模糊综合评价
笔记·学习·数学建模
黑客KKKing37 分钟前
渗透测试学习路线
网络·学习·web安全
炸毛的飞鼠38 分钟前
虚拟机Ubuntu以及pwn的工具安装
笔记·学习·ubuntu
qwe3526331 小时前
机器视觉,opencv基础学习(一)
学习
五味香2 小时前
Java学习,字符串搜索
java·c语言·开发语言·python·学习·golang·kotlin
~菜鸟笔记~2 小时前
Docker学习笔记
学习·docker
南宫生2 小时前
力扣-图论-9【算法学习day.59】
java·学习·算法·leetcode·图论
Eshin_Ye2 小时前
transformer学习笔记-自注意力机制(1)
笔记·学习·transformer·attention·注意力机制