当前位置: 首页 > news >正文

3.ImGui-窗体

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

上一个内容:2.ImGui-搭建一个外部绘制的窗口环境(使用ImGui绘制一个空白窗口)

创建我们的窗体,如下图红框通过两行代码创建的窗体,然后可以发现它中文是?,这个原因是我们没有导入字体,或者说IMGui默认的字体库不支持中文,需要我自己手动导入一个支持中文的字体库(后面会导入)

鼠标拖动下图红框位置,可以改变窗体的大小

然后点击下图红框停止运行

然后点击下图红框再次运行

会发现我们创建的窗体,它会保持上一次我们修改过的大小和位置,这是因为它有一个文件在保存这些数据

配置文件位置,首先点击打开所在的文件夹

如果是通过vs运行的它的配置文件在下图红框位置 imgui.ini

它的内容,pos是坐标x和y,size是大小

如果是通过双击下图红框的exe文件运行的程序

它就会在双击运行的exe目录下创建 imgui.ini文件

第三个参数的值,下方的代码都是从ImGui的原理复制出来的

// ImGui 窗口标志枚举(用于控制窗口的各种行为和样式)
enum ImGuiWindowFlags_
{ImGuiWindowFlags_None                   = 0,  // 无任何特殊设置(默认状态)ImGuiWindowFlags_NoTitleBar             = 1 << 0,   // 禁用窗口的标题栏ImGuiWindowFlags_NoResize               = 1 << 1,   // 禁用用户通过右下角调整窗口大小的功能ImGuiWindowFlags_NoMove                 = 1 << 2,   // 禁用用户拖动窗口改变位置的功能ImGuiWindowFlags_NoScrollbar            = 1 << 3,   // 禁用滚动条(窗口仍可通过鼠标或代码控制滚动)ImGuiWindowFlags_NoScrollWithMouse      = 1 << 4,   // 禁用鼠标滚轮控制窗口垂直滚动。如果是子窗口,鼠标滚轮事件可能会传递给父窗口(除非同时设置了NoScrollbar)ImGuiWindowFlags_NoCollapse             = 1 << 5,   // 禁用用户通过双击窗口折叠窗口的功能(也会影响窗口菜单按钮,比如在 docking 布局中的按钮)ImGuiWindowFlags_AlwaysAutoResize       = 1 << 6,   // 窗口会在每一帧自动调整大小,以适应其内容ImGuiWindowFlags_NoBackground           = 1 << 7,   // 禁用绘制窗口背景色(WindowBg等)和外边框,效果类似调用SetNextWindowBgAlpha(0.0f)(设置背景透明度为0)ImGuiWindowFlags_NoSavedSettings        = 1 << 8,   // 从不将窗口的设置(位置、大小等)保存到.ini文件,也不从.ini文件加载这些设置ImGuiWindowFlags_NoMouseInputs          = 1 << 9,   // 禁用窗口捕获鼠标输入,鼠标悬停会"穿透"到窗口下方(不响应任何鼠标事件)ImGuiWindowFlags_MenuBar                = 1 << 10,  // 窗口包含菜单栏ImGuiWindowFlags_HorizontalScrollbar    = 1 << 11,  // 允许水平滚动条出现(默认关闭)。可在调用Begin()前用SetNextWindowContentSize(ImVec2(width,0.0f))指定宽度,参考imgui_demo中的"Horizontal Scrolling"示例ImGuiWindowFlags_NoFocusOnAppearing     = 1 << 12,  // 当窗口从隐藏状态变为可见状态时,不自动获取焦点ImGuiWindowFlags_NoBringToFrontOnFocus  = 1 << 13,  // 当窗口获取焦点时(比如点击窗口或通过代码设置焦点),不将窗口提到最前面ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14,  // 总是显示垂直滚动条(即使内容高度小于窗口高度)ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15,  // 总是显示水平滚动条(即使内容宽度小于窗口宽度)ImGuiWindowFlags_NoNavInputs            = 1 << 16,  // 禁用窗口内的键盘/手柄导航功能(无法用键盘/手柄操作窗口内容)ImGuiWindowFlags_NoNavFocus             = 1 << 17,  // 通过键盘/手柄导航时,不能聚焦到这个窗口(比如会被CTRL+TAB等导航方式跳过)ImGuiWindowFlags_UnsavedDocument        = 1 << 18,  // 在窗口标题旁显示一个小点(表示有未保存的内容)。在标签页或docking场景中:点击关闭按钮时不会立即关闭标签(会等用户停止提交该标签);否则点击X会关闭窗口,若继续提交该窗口可能重新出现在标签栏末尾ImGuiWindowFlags_NoNav                  = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,  // 组合标志:同时禁用导航输入和导航聚焦(等于上面两个标志的组合)ImGuiWindowFlags_NoDecoration           = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse,  // 组合标志:同时禁用标题栏、调整大小、滚动条和折叠功能(上面四个标志的组合)ImGuiWindowFlags_NoInputs               = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,  // 组合标志:同时禁用鼠标输入、导航输入和导航聚焦(上面三个标志的组合)// 【内部使用】以下标志由ImGui内部函数使用,不建议手动设置ImGuiWindowFlags_ChildWindow            = 1 << 24,  // 不要手动使用!供BeginChild()函数内部使用(子窗口专用)ImGuiWindowFlags_Tooltip                = 1 << 25,  // 不要手动使用!供BeginTooltip()函数内部使用(提示框专用)ImGuiWindowFlags_Popup                  = 1 << 26,  // 不要手动使用!供BeginPopup()函数内部使用(弹窗专用)ImGuiWindowFlags_Modal                  = 1 << 27,  // 不要手动使用!供BeginPopupModal()函数内部使用(模态弹窗专用)ImGuiWindowFlags_ChildMenu              = 1 << 28,  // 不要手动使用!供BeginMenu()函数内部使用(子菜单专用)// 过时的标志(旧版本使用,新版本已废弃)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONSImGuiWindowFlags_NavFlattened           = 1 << 29,  // 在1.90.9版本后废弃:请在BeginChild()中使用ImGuiChildFlags_NavFlattenedImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 30,  // 在1.90.0版本后废弃:请在BeginChild()中使用ImGuiChildFlags_AlwaysUseWindowPadding
#endif
};

使用这些样式

完整代码:

#include "main.h"  // 包含程序所需的头文件(包含ImGui、DirectX等声明,具体内容在main.h中定义)// 全局变量:存储DirectX 11核心资源和窗口状态(整个程序共享,方便各函数访问)
static UINT                     g_ResizeWidth = 0, g_ResizeHeight = 0; // 窗口调整大小时的新宽高(由消息处理函数记录,主循环处理)
static ID3D11Device* g_pd3dDevice = nullptr;                          // D3D11设备对象(核心!用于创建纹理、缓冲区等渲染资源)
static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;             // D3D11设备上下文(用于执行绘制、清空等渲染命令)
static IDXGISwapChain* g_pSwapChain = nullptr;                          // 交换链(双缓冲区机制,避免画面闪烁,负责显示渲染结果)
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;        // 主渲染目标视图(绑定交换链的后台缓冲区,ImGui绘制的内容会输出到这里)
static bool                     g_SwapChainOccluded = false;           // 标记交换链是否被遮挡(如窗口被覆盖,用于优化性能)// 声明ImGui的Win32消息处理函数(来自imgui_impl_win32.cpp,用于让ImGui处理鼠标/键盘输入)
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);// 窗口消息处理函数:处理所有窗口事件(如点击、关闭、调整大小等)
// 参数:
// - hWnd:窗口句柄(标识当前窗口)
// - msg:消息类型(如WM_SIZE表示窗口大小改变)
// - wParam:消息附加参数(如WM_SIZE中表示 resize 类型)
// - lParam:消息附加参数(如WM_SIZE中存储新的宽高)
// 返回值:LRESULT类型(消息处理结果,0表示成功处理)
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{// 让ImGui先处理消息(如果是ImGui的UI控件触发的事件,优先由ImGui处理)if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))return true;  // ImGui已处理,直接返回// 根据消息类型处理不同事件switch (msg){case WM_SIZE:  // 窗口大小改变事件if (wParam == SIZE_MINIMIZED)  // 如果是窗口最小化,无需处理渲染相关return 0;// 从lParam中提取新的窗口尺寸:低16位是宽度,高16位是高度g_ResizeWidth = (UINT)LOWORD(lParam);  // 记录新宽度g_ResizeHeight = (UINT)HIWORD(lParam); // 记录新高度return 0;case WM_SYSCOMMAND:  // 系统命令事件(如ALT+空格调出窗口菜单)// 禁用ALT菜单(避免菜单遮挡ImGui控件,影响操作体验)if ((wParam & 0xfff0) == SC_KEYMENU)return 0;break;  // 其他系统命令交给默认处理case WM_DESTROY:  // 窗口销毁事件(如点击关闭按钮)::PostQuitMessage(0);  // 发送退出消息,主循环会捕获并结束程序return 0;}// 其他未处理的消息,交给Windows系统默认处理return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}// 创建渲染目标视图:将交换链的后台缓冲区绑定为渲染目标(ImGui绘制的内容会输出到这里)
void CreateRenderTarget()
{ID3D11Texture2D* pBackBuffer = nullptr;  // 临时存储交换链的后台缓冲区// 从交换链获取后台缓冲区(参数0表示第一个缓冲区,IID_ID3D11Texture2D指定缓冲区类型)g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));// 用D3D设备创建渲染目标视图(将后台缓冲区转换为可渲染的目标)g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);// 释放临时缓冲区(渲染目标视图已引用它,无需保留此指针)pBackBuffer->Release();
}// 清理渲染目标视图:释放资源,避免内存泄漏
void CleanupRenderTarget()
{// 释放渲染目标视图(COM对象需调用Release()减少引用计数,为0时自动释放内存)if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; }
}// 创建D3D11设备和交换链:初始化DirectX渲染环境
// 参数:hWnd - 窗口句柄(渲染结果会显示在这个窗口)
// 返回值:bool - 成功创建返回true,失败返回false
bool CreateDeviceD3D(HWND hWnd)
{// 初始化交换链描述(定义交换链的属性,告诉系统如何创建交换链)DXGI_SWAP_CHAIN_DESC sd;ZeroMemory(&sd, sizeof(sd));  // 清空结构体,避免随机值导致错误sd.BufferCount = 2;           // 缓冲区数量(2=双缓冲,避免画面闪烁)sd.BufferDesc.Width = 0;      // 缓冲区宽度(0=自动匹配窗口宽度)sd.BufferDesc.Height = 0;     // 缓冲区高度(0=自动匹配窗口高度)sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;  // 像素格式(32位色,含透明度)sd.BufferDesc.RefreshRate.Numerator = 60;  // 刷新率分子(60=60Hz)sd.BufferDesc.RefreshRate.Denominator = 1; // 刷新率分母(60/1=60Hz)sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;  // 允许切换显示模式(如全屏/窗口)sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;   // 缓冲区用途(作为渲染目标)sd.OutputWindow = hWnd;       // 绑定的窗口(渲染结果显示到该窗口)sd.SampleDesc.Count = 1;      // 多重采样数量(1=无抗锯齿,性能优先)sd.SampleDesc.Quality = 0;    // 采样质量(0=默认)sd.Windowed = TRUE;           // 窗口模式(TRUE=窗口,FALSE=全屏)sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;  // 交换效果(交换后丢弃后台数据,性能最好)UINT createDeviceFlags = 0;   // 创建设备的标志(0=默认,调试时可加D3D11_CREATE_DEVICE_DEBUG)// createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;  // 调试模式(需安装DirectX SDK)D3D_FEATURE_LEVEL featureLevel;  // 存储实际支持的D3D版本(如11.0、10.0)// 支持的D3D版本列表(优先11.0,不支持则用10.0)const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };// 创建设备、设备上下文和交换链(DirectX核心函数)HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE,  // 使用硬件加速(显卡渲染)nullptr, createDeviceFlags,         // 无软件渲染模块,创建标志featureLevelArray, 2,               // 支持的D3D版本列表及数量D3D11_SDK_VERSION, &sd,             // SDK版本,交换链描述&g_pSwapChain, &g_pd3dDevice,       // 输出交换链和设备&featureLevel, &g_pd3dDeviceContext // 输出支持的版本和设备上下文);// 如果硬件加速失败(如显卡不支持D3D11),尝试软件渲染(WARP驱动)if (res == DXGI_ERROR_UNSUPPORTED)res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP,   // 软件渲染(性能较差,兼容旧设备)nullptr, createDeviceFlags,featureLevelArray, 2,D3D11_SDK_VERSION, &sd,&g_pSwapChain, &g_pd3dDevice,&featureLevel, &g_pd3dDeviceContext);if (res != S_OK)  // 创建失败(S_OK表示成功)return false;CreateRenderTarget();  // 创建渲染目标视图return true;
}// 清理D3D资源:释放所有DirectX相关对象,避免内存泄漏
void CleanupDeviceD3D()
{CleanupRenderTarget();  // 先清理渲染目标// 释放COM对象(按依赖顺序释放,避免资源冲突)if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; }if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; }if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; }
}// 主函数:程序入口,控制整个程序的生命周期
int main() {// -------------------------- 步骤1:DPI适配(解决高分辨率屏幕UI模糊问题) --------------------------ImGui_ImplWin32_EnableDpiAwareness();  // 开启ImGui对系统DPI的感知// 获取主显示器的DPI缩放比例(如4K屏幕可能为2.0,1080P可能为1.0)float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)  // 获取主显示器);// -------------------------- 步骤2:创建Windows窗口(ImGui需要依附的窗口载体) --------------------------// 定义窗口类(描述窗口的基本属性,如消息处理函数、图标等)WNDCLASSEXW wc = { sizeof(wc),                  // 结构体大小CS_CLASSDC,                  // 窗口类风格(使用专属设备上下文,避免绘图冲突)WndProc,                     // 消息处理函数0L, 0L,                      // 额外数据(未使用)GetModuleHandle(nullptr),    // 程序实例句柄nullptr, nullptr, nullptr, nullptr,  // 图标、光标、背景等(用默认)L"ImGui Example",            // 窗口类名(自定义,后续创建窗口需使用)nullptr                      // 小图标(默认)};::RegisterClassExW(&wc);  // 注册窗口类(向系统注册这个窗口类型)// 创建窗口(生成实际窗口)HWND hwnd = ::CreateWindowW(wc.lpszClassName,            // 窗口类名(对应注册的类)L"Dear ImGui DirectX11 Example",  // 窗口标题WS_OVERLAPPEDWINDOW,         // 窗口风格(标准窗口,带标题栏、关闭按钮等)100, 100,                    // 初始位置(屏幕左上角x=100,y=100)(int)(1280 * main_scale),    // 宽度(1280 * DPI缩放,适配高分辨率)(int)(800 * main_scale),     // 高度(800 * DPI缩放)nullptr, nullptr,            // 父窗口、菜单(无)wc.hInstance, nullptr        // 程序实例、额外参数);// -------------------------- 步骤3:初始化DirectX 11(创建渲染环境) --------------------------if (!CreateDeviceD3D(hwnd))  // 调用函数创建D3D设备和交换链,失败则清理资源并退出{CleanupDeviceD3D();::UnregisterClassW(wc.lpszClassName, wc.hInstance);return 1;  // 返回1表示程序异常退出}// 显示窗口(创建后默认隐藏,需手动显示)::ShowWindow(hwnd, SW_SHOWDEFAULT);::UpdateWindow(hwnd);  // 刷新窗口,确保立即显示// -------------------------- 步骤4:初始化ImGui(配置UI环境) --------------------------IMGUI_CHECKVERSION();  // 检查ImGui版本(确保编译版本与运行时一致)ImGui::CreateContext(); // 创建ImGui上下文(UI的"全局环境")ImGuiIO& io = ImGui::GetIO(); (void)io;  // 获取IO对象(管理输入输出,如键盘、帧率)io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // 开启键盘导航(方向键、Tab操作UI)io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // 开启手柄导航(支持游戏手柄操作)// -------------------------- 步骤5:设置UI缩放(适配DPI,避免高分辨率下UI过小) --------------------------ImGuiStyle& style = ImGui::GetStyle();style.ScaleAllSizes(main_scale);  // 缩放所有UI元素(按钮、文本等)style.FontScaleDpi = main_scale;  // 缩放字体大小// -------------------------- 步骤6:初始化ImGui后端(连接ImGui与系统/渲染API) --------------------------ImGui_ImplWin32_Init(hwnd);       // 初始化Win32后端(处理窗口消息、输入)ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);  // 初始化DX11后端(负责渲染UI)// -------------------------- 步骤7:程序状态变量(控制UI显示) --------------------------bool show_demo_window = true;    // 是否显示ImGui演示窗口bool show_another_window = false; // 是否显示"另一个窗口"ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // 窗口背景色(浅蓝色)// -------------------------- 步骤8:主循环(程序的核心,持续运行直到退出) --------------------------bool done = false;  // 控制循环是否结束(true=退出)while (!done){// -------------------------- 8.1 处理窗口消息(如关闭、点击等) --------------------------MSG msg;  // 存储消息的结构体// 从消息队列中获取消息(PM_REMOVE表示获取后移除,避免重复处理)while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)){::TranslateMessage(&msg);  // 翻译消息(如键盘按键转字符)::DispatchMessage(&msg);   // 分发消息到WndProc处理if (msg.message == WM_QUIT)  // 收到退出消息(如点击关闭按钮)done = true;  // 标记循环结束}if (done)break;  // 退出循环// -------------------------- 8.2 处理窗口遮挡(优化性能) --------------------------// 如果交换链被遮挡(如窗口被覆盖),且确认遮挡状态:if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED){::Sleep(10);  // 休眠10ms,减少CPU占用continue;     // 跳过本次循环,不渲染}g_SwapChainOccluded = false;  // 重置遮挡状态// -------------------------- 8.3 处理窗口大小调整(避免画面拉伸) --------------------------if (g_ResizeWidth != 0 && g_ResizeHeight != 0)  // 如果有新的窗口尺寸{CleanupRenderTarget();  // 先清理旧的渲染目标// 调整交换链缓冲区大小(匹配新窗口尺寸)g_pSwapChain->ResizeBuffers(0, g_ResizeWidth, g_ResizeHeight, DXGI_FORMAT_UNKNOWN, 0);g_ResizeWidth = g_ResizeHeight = 0;  // 重置尺寸变量CreateRenderTarget();  // 创建新的渲染目标(适配新尺寸)}// -------------------------- 8.4 开始ImGui新帧(准备绘制UI) --------------------------ImGui_ImplDX11_NewFrame();  // DX11后端准备新帧ImGui_ImplWin32_NewFrame(); // Win32后端准备新帧ImGui::NewFrame();          // ImGui核心准备(通知ImGui可以开始定义UI了)// -------------------------- 8.5 定义UI界面(核心:这里是你要显示的UI) --------------------------/**ImGui::Begin()函数说明:函数声明:bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0);参数:- name:窗口标题(唯一标识,相同标题会合并窗口)- p_open:控制窗口是否显示的指针(关闭窗口时会将其设为false)- flags:窗口标志(组合使用,如禁用标题栏、禁止移动等)*/bool i = true;  // 控制窗口是否显示(true=显示)// 创建一个自定义窗口:标题为"我的IMGui",禁止标题栏(NoTitleBar)和移动(NoMove)ImGui::Begin("我的IMGui", &i, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);// 这里可以添加其他UI控件(如按钮、文本等),目前是空窗口// 例如:ImGui::Text("这是我的第一个ImGui窗口!");ImGui::End();  // 结束窗口定义(必须与Begin配对,否则崩溃)// -------------------------- 8.6 渲染UI(将定义的UI绘制到屏幕) --------------------------ImGui::Render();  // 生成绘制命令(将UI转换为显卡可执行的指令)// 计算背景色(考虑透明度:clear_color.w是透明度,乘以RGB值)const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };// 设置渲染目标(告诉显卡:接下来的绘制输出到主渲染目标)g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);// 清空屏幕(用背景色填充,避免上一帧画面残留)g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);// 渲染ImGui的UI(执行绘制命令,将UI画到屏幕)ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());// -------------------------- 8.7 显示画面(交换前后缓冲区,展示渲染结果) --------------------------// Present函数:交换前后缓冲区(后台缓冲区是刚渲染的画面,前台是正在显示的)// 参数1:1=开启垂直同步(VSync,防止画面撕裂,帧率与显示器一致);0=关闭(帧率更高)HRESULT hr = g_pSwapChain->Present(1, 0);   // 开启垂直同步// HRESULT hr = g_pSwapChain->Present(0, 0); // 关闭垂直同步// 检查交换链是否被遮挡(用于后续优化)g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);}// -------------------------- 步骤9:程序退出,清理资源 --------------------------// 关闭ImGui后端ImGui_ImplDX11_Shutdown();ImGui_ImplWin32_Shutdown();ImGui::DestroyContext();  // 销毁ImGui上下文// 清理D3D资源CleanupDeviceD3D();// 销毁窗口和窗口类::DestroyWindow(hwnd);::UnregisterClassW(wc.lpszClassName, wc.hInstance);return 0;  // 程序正常退出
}

img

http://www.dtcms.com/a/363845.html

相关文章:

  • 大模型推理加速深度对比:vLLM vs TensorRT-LLM vs ONNX Runtime,谁是生产环境最优解?
  • 【智能体开发】怎样提升AI智能体的运行速度?
  • 重新审视信任基石:公网IP证书对网络安全生态的影响
  • 多态——面向对象编程的 “灵活密码”
  • p049基于Flask的医疗预约与诊断系统
  • Linux 安装docker-compose安装方法(安装docker compose安装)
  • Android Activity 任务栈详解
  • 一种简单而有效的融合时空特征嵌入的城区多变量长序列风速预测模型
  • 基于Springboot和Vue的前后端分离项目
  • MD5加密算法详解与实现
  • Python-Flask企业网页平台深度Q网络DQN强化学习推荐系统设计与实现:结合用户行为动态优化推荐策略
  • Dockerfile 自动化构建容器镜像
  • OpenStack:典型的面向服务架构(Service-Oriented Architecture, SOA)
  • Java Bitmap 去重:原理、代码实现与应用
  • 广东省省考备考(第九十二天9.2)——言语(刷题巩固第一节课)
  • 从全栈开发到微服务架构:一次真实的Java全栈面试经历
  • 子进程、父进程
  • 高效数据传输的秘密武器:Protobuf
  • Linux系统:进程信号的处理
  • TKDE-2022《Low-Rank Linear Embedding for Robust Clustering》
  • 【机器学习深度学习】向量模型与重排序模型:RAG 的双引擎解析
  • 利用 Java 爬虫获取淘宝商品 SKU 详细信息实战指南
  • keycloak中对接oidc协议时设置prompt=login
  • 机器学习回顾——决策树详解
  • SOL中转转账教程
  • Android Binder 驱动 - Media 服务启动流程
  • TiDB v8.5.3 单机集群部署指南
  • rocketmq启动与测试
  • 数据结构--跳表(Skip List)
  • playwright+python UI自动化测试中实现图片颜色和像素对比