作者:小阿栗

Imgui又称为Dear ImGui,它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将Imgui的源码直接加到项目中使用,也可以编译成dll, Imgui使用DX或者OpenGL进行界面渲染,Imgui主要用于游戏行业。

这里我们需要用到两个工具Detours-master(微软的hook库)和imgui-master,主要讲D3D9HOOK。

我们先来创建一个DLL项目。步骤如下:

1.选择新建项目

2.选择Windows桌面->动态链接库(DLL)->D3D9HOOK,点击确定

3.删除framework.h、pch.h以及pch.cpp文件。添加一个dllmain.h头文件

4.dllmain.cpp中要包含头文件添加#include <Windows.h>

5. 配置

5.1 选择属性

5.2 修改运行库以及Spectre缓解,选择应用

5.3 配置include路径,点击“宏”,搜索DX,根据地址找到文件位置,将 $(DXSDK_DIR)include填入,应用

5.4 搜索DX,将$(DXSDK_DIR)Lib填入,搜索$(platformTarget),将$(DXSDK_DIR)lib\$(platformTarget)填入,应用

(图片注释:配置好会自动匹配x86/x64不需要再改)

5.5 新增d3d9.lib,d3dx9.lib这两个依赖项,应用

6. 配置好环境后,编译HOOK库(编译x86和x64两个版本)

X86:找到Visual Studio2017,打开“x86 Native Tools Prompt for VS 2017”,然后cd到路径里nmake进行编译

X64:找到Visual Studio2017,打开“适用于VS 2017的 x64 本机工具命令提示”,然后cd到路径里nmake进行编译

7.打开项目文件夹

8.新建一个目录Detours,将lib.x86、lib.x64和include复制过来(将lib.去掉方便后续识别)

9.新建筛选器,命名Detours

10.在Detours中添加现有项,选定两个头文件detours.h和detver.h

11.配置lib库

11.1选择属性

11.2 编辑包含目录,宏-包含目录-$(ProjectDir)Detours\include,应用

11.3编辑附加库目录,宏-附加库目录-$(ProjectDir)Detours\Lib\$(platformTarget),应用

11.4 编辑附加依赖项,添加detours.lib,应用

11.5 不使用预编译头

12.配置imgui

12.1在D3D9HOOK目录下,新建imgui文件夹,将imgui-master中backends里imgui_impl_dx9.cpp、imgui_impl_dx9.h和imgui_impl_win32.cpp、imgui_impl_win32.h;及主目录下所有.cpp和.h都复制到imgui文件夹中

12.2新建筛选器,命名imgui

12.3在imgui中添加现有项,选定目录下所有文件

12.4.dllmain.h中包含导进来的所有头文件

13.主线程imgui窗口的实现

typedef HRESULT (WINAPI * FuncReset)(IDirect3DDevice9 *pIDirect3DDevice9,D3DPRESENT_PARAMETERS *pPresentationParameters);

typedef HRESULT (WINAPI *  FuncEndScene)(IDirect3DDevice9 *pIDirect3DDevice9);

typedef LRESULT(WINAPI * FuncWndProc)(const HWND, UINT, WPARAM, LPARAM);

HWND g_hWnd = NULL;

IDirect3D9 * g_IDirect3D9;

D3DPRESENT_PARAMETERS g_d3dpp;

IDirect3DDevice9* g_pIDirect3DDevice9;

FuncReset OldReset;

FuncEndScene OldEndScene;

FuncWndProc OldWndProc;

DWORD * dwDeviceVirtualTable = NULL;

extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

LRESULT WINAPI GrkWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

if (ImGui_ImplWin32_WndProcHandler(hWnd, message, wParam, lParam))

{

return TRUE;

}

return CallWindowProc(OldWndProc, hWnd, message, wParam, lParam);

}

VOID StartHook(PVOID * OldFunctionAddr, PVOID NewFunctionAddr)

{

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());

DetourAttach(OldFunctionAddr, NewFunctionAddr);

DetourTransactionCommit();

}

VOID UnHook(PVOID * OldFunctionAddr, PVOID NewFunctionAddr)

{

DetourTransactionBegin();

DetourUpdateThread(GetCurrentThread());

DetourDetach(OldFunctionAddr, NewFunctionAddr);

DetourTransactionCommit();

}

HRESULT WINAPI GrkReset(IDirect3DDevice9 *pIDirect3DDevice9, D3DPRESENT_PARAMETERS *d3dpp)

{

UnHook((PVOID*)(&OldReset), GrkReset);

ImGui_ImplDX9_InvalidateDeviceObjects();

HRESULT bRet = pIDirect3DDevice9->Reset(d3dpp);

ImGui_ImplDX9_CreateDeviceObjects();

StartHook((PVOID*)(&OldReset), GrkReset);

return bRet;

}

HRESULT WINAPI GrkEndScene(IDirect3DDevice9 *pIDirect3DDevice9)

{

UnHook((PVOID*)(&OldEndScene), GrkEndScene);

static bool bFlag = TRUE;

if (bFlag)

{

bFlag = FALSE;

IMGUI_CHECKVERSION();

ImGui::CreateContext();

ImGuiIO & io = ImGui::GetIO();

io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;

io.WantSaveIniSettings = false;

io.IniFilename = NULL;

ImGui::StyleColorsClassic();

ImFontConfig imfConfig;

imfConfig.FontDataOwnedByAtlas = false;

ImGui_ImplWin32_Init(g_hWnd);

ImGui_ImplDX9_Init(pIDirect3DDevice9);

OldWndProc = (WNDPROC)SetWindowLongPtr(g_hWnd, GWL_WNDPROC, (LONG_PTR)GrkWndProc);

}

HRESULT hRet = pIDirect3DDevice9->EndScene();

ImGui_ImplDX9_NewFrame();

ImGui_ImplWin32_NewFrame();

ImGui::NewFrame();

ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver);

ImGui::SetNextWindowSize(ImVec2(300, 300));

ImGui::Begin("GrkTools");

ImGui::End();

ImGui::EndFrame();

ImGui::Render();

ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());

StartHook((PVOID*)(&OldEndScene), GrkEndScene);

return hRet;

}

DWORD WindowThreadCallBack(LPVOID lpBuffer)

{

g_hWnd = FindWindowA("Direct3DWindowClass", NULL);

g_IDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION);

memset(&g_d3dpp, 0, sizeof(g_d3dpp));

g_d3dpp.Windowed = TRUE;

g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

g_d3dpp.EnableAutoDepthStencil = TRUE;

g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

HRESULT hRet = g_IDirect3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_d3dpp, &g_pIDirect3DDevice9);

dwDeviceVirtualTable = (DWORD *)*(DWORD *)g_pIDirect3DDevice9;

OldReset = (FuncReset)dwDeviceVirtualTable[16];

OldEndScene = (FuncEndScene)dwDeviceVirtualTable[42];

StartHook((PVOID*)(&OldReset), GrkReset);

StartHook((PVOID*)(&OldEndScene), GrkEndScene);

return 0;

}

BOOL APIENTRY DllMain( HMODULE hModule,

DWORD  ul_reason_for_call,

LPVOID lpReserved

)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)WindowThreadCallBack, NULL, NULL, NULL);

break;

case DLL_THREAD_ATTACH:

break;

case DLL_THREAD_DETACH:

break;

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}

14.测试

14.1打开文件夹,把动态链接库D3D9HOOK.dll粘贴到桌面上

14.2打开pick,启动代码注入器,将动态链接库D3D9HOOK.dll进行注入

测试成功:在pick左上角出现窗口<span

这样,就手动创建了一个基础的imgui的框架<span

图形编程丨图形绘制基础imgui篇—D3D9 HOOK 创建内部Imgui窗口相关推荐

  1. android图形编程,Android图形编程基础

    Color //方法1 int color1 = Color.BLUE; //方法2 int color2 = Color.argb(177, 255,255,255); //方法3:在xm l里面定 ...

  2. linux图形编程,linux图形界面编程基本知识

    以前看过这篇文章,不过当时没有博客,现在又一次看到了,记下来: http://hi.baidu.com/skychen1900/blog/item/9c7b94350a5fae1290ef39fb.h ...

  3. 基础总结篇之八:创建及调用自己的ContentProvider

    鍥而捨之,朽木不折:鍥而不捨,金石可鏤.戰國.荀子<勸學篇> 若不能坚持到底,即使是朽木也不能折断:只要坚持不停地用刀刻,就算是金属玉石也可以雕出花饰.用今天的话来说就是:再容易的事情,没 ...

  4. 开发日记-20190528 关键词 读书笔记《鸟哥的Linux私房菜-基础学习篇》.desktop创建

    前言 为你的 Linux 应用创建 .desktop 文件 | Linux 中国 ubuntu下安装AndroidStudio Android 布局平铺展开效果的属性动画 Android开发自动生成的 ...

  5. java jfm入门_java图形编程

    //将布局管理器设置为边框布局 this.setLayout(new BorderLayout()); 边框布局:将组件按东南西北中的方式进行放置.一个方向只能放一个组件,组件大小岁容 jfm.set ...

  6. 《JavaScript高效图形编程(修订版)》——6.7 画布绘制基础

    本节书摘来自异步社区<JavaScript高效图形编程(修订版)>一书中的第6章,第6.7节,作者:[美]Raffaele Cecco著,更多章节内容可以访问云栖社区"异步社区& ...

  7. bada 2D游戏编程之一——图形绘制

    bada 2D游戏编程之一--图形绘制 在2D游戏中,用户见到的画面通常是通过两种方式实现的,一种是图形绘制,就是在屏幕上绘制各种几何图元,如线条和矩形等:还有一种是图像绘制,也就是常说的贴图,游戏中 ...

  8. EGE基础入门篇(六):基本图形

    EGE专栏:EGE专栏 上一篇:EGE基础入门篇(五):窗口简单操作 下一篇:EGE基础入门篇(七):组合图形 一.EGE提供的基本图形 EGE绘制图形相关库函数文档 https://xege.org ...

  9. 计算机图形编程基础,Windows图形编程基础.ppt

    Windows图形编程基础 软件教研室 计算机图形学 第三章 Window图形编程基础 一.设备描述表DC及相关的MFC类 二.图形设备接口(GDI : Graphics device Interfa ...

  10. windows图形编程基础

    windows图形编程基础 2010年08月30日 图形设备接口(GDI,Graphics Device Interface)的主要目标之一是支持在输出设备(如视频显示器.打印机和绘图仪)上的与设备无 ...

最新文章

  1. OneAPM挂牌新三板,资本市场一片看好!
  2. SDUT 贪心算法 删数问题
  3. Red Hat Enterprise Linux 5.4安装GCC
  4. 【阿里云课程】生成模型之GAN优化目标设计与改进
  5. php 机数,PHP实现自动刷数和“灌水”机
  6. 【最贴心】C++字符串转换(stoi;stol;stoul;stoll;stoull;stof;stod;stold)
  7. mysql 自动备份发送,Centos定时自动备份MySQL数据库并发送至指定邮箱
  8. read.table与readr::read_delim
  9. lua和unity如何交互_(XLua)C#与Lua中的交互
  10. python程序设计教程胡建华_Python程序设计教程
  11. 7-9 40059 四则运算 (15 分)
  12. ZMQ == 服务端创建,接受请求的过程
  13. 【转】Windows下部署Appium教程(Android App自动化测试框架搭建)
  14. 站在巨人的肩膀上-听课感想
  15. 人工智能真的具有创造力?
  16. [转贴]民国记者有多牛:揭黑损人骂街是常事
  17. C语言知识-关键字stastic
  18. word文件图标无法显示的问题
  19. 资金互助社业务学习园地(一) 灵活运用通知储蓄存款
  20. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?

热门文章

  1. uni-app 中使用背景图片
  2. rasa框架nlu源码解析
  3. 【lstm预测】基于lstm实现时间序列数据预测matlab源码
  4. css3炫酷环形背景动画
  5. windows系统bat批处理 电子教室加卡他卡 伽卡他卡学生端暴力关闭 无敌版
  6. 根据string查询是否是当月_发票勾选、查询、认证等25问!简直太全了!打印出来贴在桌子上学习!...
  7. 同义词,近义词,反义词收集
  8. dpdk大页内存原理
  9. AUTOSAR入门介绍
  10. 程序集版本号,文件版本号及发布版本号管理