12.ImGui-外部绘制独立的界面窗体

发布于:2025-09-14 ⋅ 阅读:(20) ⋅ 点赞:(0)

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

本次游戏没法给

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

上一个内容:11.ImGui-加载字体和中文

到这ImGui基础的东西就搞完了,然后接下来绘制一个,正常的窗口,如下图现在绘制的东西都在下图红框里面,正常的窗口它应该是在下图黄框里面绘制控件(输入框、进度条、文本、单选框、复选框等)

然后我们的程序运行后,它还有一个控制台,正常的窗口程序它也是没有控制台的,所以还要把控制台关了

关闭控制台,鼠标右击选择属性

如下图选择,把控制台改成窗口就可以关闭控制台了,选择完窗口然后点击确定

再次运行会报错,因为控制台的入口函数和窗口的入口函数不一样

把下图红框的main改成下图黄框的WinMain就可以了

正常运行,然后控制台的问题就解决了,然后是窗口的问题

然后再次来到ImGui的官网

https://github.com/ocornut/imgui

然后点击下图蓝框的箭头,然后再点击下图红框

然后再把它的docking版本的源码下载下来

下载完后解压,不要放在中文的目录里,官网的代码没有中文字体

它也有实例

然后使用vs2022(vs几都可以,但最好跟我一样使用vs2022)打开它,如下图红框点击确定

然后再找到directx11设置为启动项目

效果图:可以看到它可以脱离下图黄框的窗口了,这样可以做的事情就多了

修改它的代码后效果图:可以看到ImGui窗口的窗口脱离出来了

这样运行后在任务栏,如下图会有三个

上图左边第一个是通过,下图红框的代码创建的,如果想隐藏它可以使用CreateWindowExW

如下图的代码

效果图:这样搞完也会有其它的问题,窗口默认的关闭没了,需要自己写消息循环和ImGui的退出按钮

然后还有一种方式,ImGui提供,如下图红框的代码,

效果图:任务栏只有一个CreateWindowW创建的图标

然后它实现脱离CreateWindowW窗口的代码,就比我们的代码多出了下图红框的代码,下一节将整合进去

用到的代码和说明

// 定义窗口类扩展结构(WNDCLASSEXW 是 WNDCLASS 的扩展版本,支持额外成员)
// 用于描述窗口类的属性,注册后可基于该类创建窗口实例
WNDCLASSEXW wc = { 
    sizeof(wc),                  // cbSize:结构体自身大小(必须设置,用于系统验证)
    CS_CLASSDC,                  // style:窗口类样式,CS_CLASSDC 表示该类窗口共享一个设备上下文(DC)
    WndProc,                     // lpfnWndProc:窗口过程函数(回调),处理窗口消息(如点击、关闭等)
    0L, 0L,                      // cbClsExtra/cbWndExtra:类/窗口的额外数据字节数,此处无需额外数据
    GetModuleHandle(nullptr),    // hInstance:当前模块实例句柄(关联窗口所属的程序)
    nullptr,                     // hIcon:窗口类默认图标(nullptr 表示使用系统默认)
    nullptr,                     // hCursor:窗口类默认光标(nullptr 表示使用系统默认)
    nullptr,                     // hbrBackground:窗口背景画刷(nullptr 表示无默认背景,由程序自行绘制)
    nullptr,                     // lpszMenuName:默认菜单资源名(nullptr 表示无默认菜单)
    L"ImGui Example",            // lpszClassName:窗口类名(唯一标识,创建窗口时需匹配)
    nullptr                      // hIconSm:小图标(任务栏/标题栏小图标,nullptr 表示使用系统默认)
};

// 向系统注册窗口类
// 注册成功后,系统认可该窗口类,可基于此类创建窗口实例
::RegisterClassExW(&wc);

// 创建窗口实例(基于上面注册的窗口类)
HWND hwnd = ::CreateWindowW(
    wc.lpszClassName,            // lpClassName:窗口类名(必须与注册的类名一致)
    L"Dear ImGui DirectX11 Example", // lpWindowName:窗口标题(显示在标题栏,若有标题栏)
    WS_POPUP,                    // dwStyle:窗口样式,WS_POPUP 表示弹出窗口(无标题栏、边框等默认样式)
    100, 100,                    // x/y:窗口左上角在屏幕中的初始坐标(以像素为单位)
    1, 1,                        // nWidth/nHeight:窗口初始宽高(此处为 1x1 像素,通常会后续调整)
    nullptr,                     // hWndParent:父窗口句柄(nullptr 表示顶级窗口)
    nullptr,                     // hMenu:窗口菜单句柄(nullptr 表示无菜单)
    wc.hInstance,                // hInstance:当前模块实例句柄(与窗口类注册时一致)
    nullptr                      // lpParam:创建窗口时传递的额外数据(此处无需传递)
);
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;         // 启用 Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;       // 启用多视口
// ConfigViewportsNoTaskBarIcon它的值是true时,禁止 ImGui 为独立视口创建任务栏图标。
// 使用时需要 有 ImGuiConfigFlags_DockingEnable 和 ImGuiConfigFlags_ViewportsEnable
io.ConfigViewportsNoTaskBarIcon = true;

img