• ImGUI 1.87 绘制D3D外部菜单


    ImGUI 它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将ImGUI的源码直接加到项目中使用,该框架通常会配合特定的D3Dx9等图形开发工具包一起使用,ImGUI常用来实现进程内的菜单功能,而有些辅助开发作者也会使用该框架开发菜单页面,总体来说这是一个很不错的绘图库,如下将公开新版ImGUI如何实现绘制外部菜单的功能。

    ImGUI官方下载地址:https://github.com/ocornut/imgui/releases

    在使用ImGUI页面之前需要先来实现一个简单的附着功能,即如何将一个窗体附着到另一个窗体之上,其实代码很简单,如下所示当用户输入进程PID时,会自动跟随窗体并附着在窗体顶部。

    #include <Windows.h>
    #include <iostream>
    
    struct handle_data
    {
    	unsigned long process_id;
    	HWND best_handle;
    };
    
    // By: LyShark
    BOOL IsMainWindow(HWND handle)
    {
    	return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
    }
    
    BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam)
    {
    	// By: LyShark
    	handle_data& data = *(handle_data*)lParam;
    	unsigned long process_id = 0;
    	GetWindowThreadProcessId(handle, &process_id);
    	if (data.process_id != process_id || !IsMainWindow(handle)) {
    		return TRUE;
    	}
    	data.best_handle = handle;
    	return FALSE;
    }
    
    // By: LyShark
    HWND FindMainWindow(unsigned long process_id)
    {
    	handle_data data;
    	data.process_id = process_id;
    	data.best_handle = 0;
    	EnumWindows(EnumWindowsCallback, (LPARAM)&data);
    	return data.best_handle;
    }
    
    int main(int argc, char* argv[])
    {
    	DWORD pid = 28396;
    
    	std::cout << "输入进程PID: " << std::endl;
    	std::cin >> pid;
    
    	// 获取屏幕宽和高
    	int iWidth = ::GetSystemMetrics(SM_CXSCREEN);
    	int iHeight = ::GetSystemMetrics(SM_CYSCREEN);
    
    	// 根据PID寻找游戏窗口
    	HWND hwnd = FindMainWindow(pid);
    
    	while (1)
    	{
    		SetTimer(hwnd, 1, 150, NULL);
    
    		// 实现透明必须设置WS_EX_LAYERED标志
    		LONG lWinStyleEx = GetWindowLong(hwnd, GWL_EXSTYLE);
    		lWinStyleEx = lWinStyleEx | WS_EX_LAYERED;
    
    		SetWindowLong(hwnd, GWL_EXSTYLE, lWinStyleEx);
    		SetLayeredWindowAttributes(hwnd, 0, RGB(40, 40, 40), LWA_ALPHA);
    
    		// 去掉标题栏及边框
    		LONG_PTR Style = GetWindowLongPtr(hwnd, GWL_STYLE);
    		Style = Style & ~WS_CAPTION & ~WS_SYSMENU & ~WS_SIZEBOX;
    		SetWindowLongPtr(hwnd, GWL_STYLE, Style);
    
    		// 至顶层窗口 最大化
    		SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, iWidth, iHeight, SWP_SHOWWINDOW);
    
    		// 设置窗体可穿透鼠标
    		SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
    
    		// 绘图
    		HDC hdc = ::GetDC(hwnd);
    		HDC mdc = ::CreateCompatibleDC(hdc);
    
    		// 创建画笔
    		HPEN hpen = CreatePen(PS_SOLID, 10, RGB(0, 255, 0));
    		// DC 选择画笔
    		SelectObject(hdc, hpen);
    		// (画笔)从初始点移动到 50,50
    		MoveToEx(hdc, 100, 100, NULL);
    		// (画笔)从初始点画线到 100,100
    		LineTo(hdc, 1000, 1000);
    
    		RECT rect = {0};
    
    		rect.bottom = 10;
    		rect.left = 20;
    		rect.right = 20;
    		rect.top = 15;
    
    		DrawText(hdc, L"hello lyshark.com", strlen("hello lyshark.com"), &rect, DT_CALCRECT | DT_CENTER | DT_SINGLELINE);
    	}
    
    	return 0;
    }
    

    绘制效果图:

    接着我们使用Imgui绘制一个动态菜单,首先下载imgui并打开项目中的examples目录,找到example_win32_directx9打开后自己配置好dx9SDK开发工具包。

    代码直接调用,并附加到Counter-Strike Source游戏窗体之上即可,这段代码也很简单。

    #include "imgui.h"
    #include "imgui_impl_dx9.h"
    #include "imgui_impl_win32.h"
    
    #include <d3d9.h>
    #include <tchar.h>
    #include <iostream>
    
    #pragma execution_character_set("utf-8")
    
    // 全局变量
    // lyshark.com
    static HWND hwnd;
    static HWND GameHwnd;
    static RECT WindowRectangle;
    static int WindowWide, WindowHeight;
    
    static LPDIRECT3D9 g_pD3D = NULL;
    static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
    static D3DPRESENT_PARAMETERS g_d3dpp = {};
    
    // 单选框设置状态
    bool show_another_window = false;
    
    // imgui 回调函数
    extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    // By: LyShark
    bool CreateDeviceD3D(HWND hWnd)
    {
    	if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
    	{
    		return false;
    	}
    
    	ZeroMemory(&g_d3dpp, 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;
    	g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    
    	if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0)
    	{
    		return false;
    	}
    	return true;
    }
    
    void CleanupDeviceD3D()
    {
    	if (g_pd3dDevice)
    	{
    		g_pd3dDevice->Release();
    		g_pd3dDevice = NULL;
    	}
    
    	if (g_pD3D)
    	{
    		g_pD3D->Release();
    		g_pD3D = NULL;
    	}
    }
    
    void ResetDevice()
    {
    	ImGui_ImplDX9_InvalidateDeviceObjects();
    	HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp);
    	if (hr == D3DERR_INVALIDCALL)
    	{
    		IM_ASSERT(0);
    	}
    	ImGui_ImplDX9_CreateDeviceObjects();
    }
    
    LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
    	{
    		return true;
    	}
    
    	switch (msg)
    	{
    	case WM_SIZE:
    		if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
    		{
    			g_d3dpp.BackBufferWidth = LOWORD(lParam);
    			g_d3dpp.BackBufferHeight = HIWORD(lParam);
    			ResetDevice();
    		}
    		return 0;
    
    	case WM_SYSCOMMAND:
    		if ((wParam & 0xfff0) == SC_KEYMENU)
    		{
    			return 0;
    		}
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    
    // 绘制主方法
    // www.cnblogs.com/lyshark
    void DrawImGUI()
    {
    	// 启动IMGUI自绘
    	ImGui_ImplDX9_NewFrame();
    	ImGui_ImplWin32_NewFrame();
    	ImGui::NewFrame();
    
    	static float f = 0.0f;
    	static int counter = 0;
    	static char sz[256] = { 0 };
    
    	ImGui::Begin("LyShark 辅助GUI主菜单");
    	ImGui::Text("这是一段测试字符串");
    	ImGui::Checkbox("弹出子窗口", &show_another_window);
    	ImGui::SliderFloat("浮点条", &f, 0.0f, 1.0f);
    
    	ImGui::InputText("输入内容", sz, 256, 0, 0, 0);
    
    	if (ImGui::Button("点我触发"))
    		counter++;
    	ImGui::SameLine();
    	ImGui::Text("触发次数 = %d", counter);
    
    	ImGui::Text("当前FPS: %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
    	ImGui::End();
    
    	if (show_another_window)
    	{
    		ImGui::Begin("我是子窗体", &show_another_window);
    		ImGui::Text(" 您好,LyShark !");
    		if (ImGui::Button("关闭窗体"))
    			show_another_window = false;
    		ImGui::End();
    	}
    	ImGui::EndFrame();
    }
    
    // 自身窗口循环事件
    void WindowMessageLoop()
    {
    	bool done = false;
    	while (!done)
    	{
    		// 每次都将窗体置顶并跟随游戏窗体移动
    		GetWindowRect(GameHwnd, &WindowRectangle);
    		WindowWide = (WindowRectangle.right) - (WindowRectangle.left);
    		WindowHeight = (WindowRectangle.bottom) - (WindowRectangle.top);
    		DWORD dwStyle = GetWindowLong(GameHwnd, GWL_STYLE);
    		if (dwStyle & WS_BORDER)
    		{
    			WindowRectangle.top += 23;
    			WindowHeight -= 23;
    		}
    
    		// 跟随窗口移动
    		MoveWindow(hwnd, WindowRectangle.left + 8, WindowRectangle.top + 8, WindowWide - 11, WindowHeight - 11, true);
    
    		// 开始消息循环
    		MSG msg;
    		while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    			if (msg.message == WM_QUIT)
    			{
    				done = true;
    			}
    		}
    
    		if (done)
    		{
    			break;
    		}
    
    		// 开始绘制
    		DrawImGUI();
    
    		g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    		g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    		g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
    		g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
    
    		if (g_pd3dDevice->BeginScene() >= 0)
    		{
    			ImGui::Render();
    			ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
    			g_pd3dDevice->EndScene();
    		}
    
    		HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
    		if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
    		{
    			ResetDevice();
    		}
    	}
    }
    
    int main(int argc, char *argv[])
    {
    	// 注册窗体类
    	WNDCLASSEX wc;
    
    	// 附加到指定窗体上
    	wc.cbClsExtra = NULL;
    	wc.cbSize = sizeof(WNDCLASSEX);
    	wc.cbWndExtra = NULL;
    	wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
    	wc.hCursor = LoadCursor(0, IDC_ARROW);
    	wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    	wc.hIconSm = LoadIcon(0, IDI_APPLICATION);
    	wc.hInstance = GetModuleHandle(NULL);
    	wc.lpfnWndProc = (WNDPROC)WndProc;
    	wc.lpszClassName = L" ";
    	wc.lpszMenuName = L" ";
    	wc.style = CS_VREDRAW | CS_HREDRAW;
    
    	RegisterClassEx(&wc);
    
    	// 得到窗口句柄
    	GameHwnd = FindWindowA(NULL, "Counter-Strike Source");
    	GetWindowRect(GameHwnd, &WindowRectangle);
    	WindowWide = WindowRectangle.right - WindowRectangle.left;
    	WindowHeight = WindowRectangle.bottom - WindowRectangle.top;
    
    	// 创建窗体
    	hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TOOLWINDOW, L" ", L" ", WS_POPUP, 1, 1, WindowWide, WindowHeight, 0, 0, wc.hInstance, 0);
    
    	// 显示窗口
    	SetLayeredWindowAttributes(hwnd, 0, RGB(0, 0, 0), LWA_ALPHA);
    	SetLayeredWindowAttributes(hwnd, 0, RGB(0, 0, 0), LWA_COLORKEY);
    	ShowWindow(hwnd, SW_SHOW);
    
    	// 初始化D3D
    	if (!CreateDeviceD3D(hwnd))
    	{
    		CleanupDeviceD3D();
    		UnregisterClass(wc.lpszClassName, wc.hInstance);
    		return 0;
    	}
    
    	// 更新窗体
    	UpdateWindow(hwnd);
    
    	// 初始化ImGUI
    	ImGui::CreateContext();
    	ImGuiIO& io = ImGui::GetIO(); (void)io;
    	io.Fonts->AddFontFromFileTTF("c:/windows/fonts/simhei.ttf", 13.0f, NULL, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
    
    	ImGui::StyleColorsDark();
    	ImGui_ImplWin32_Init(hwnd);
    	ImGui_ImplDX9_Init(g_pd3dDevice);
    
    	// 开始执行绘制循环事件
    	WindowMessageLoop();
    
    	ImGui_ImplDX9_Shutdown();
    	ImGui_ImplWin32_Shutdown();
    	ImGui::DestroyContext();
    
    	CleanupDeviceD3D();
    	DestroyWindow(hwnd);
    	UnregisterClass(wc.lpszClassName, wc.hInstance);
    	return 0;
    }
    

    绘制效果如下:

    另外,Imgui也支持绘制到整个屏幕上,也可以当作全局GUI界面来使用。

    #include "imgui.h"
    #include "imgui_impl_dx9.h"
    #include "imgui_impl_win32.h"
    
    #include <d3d9.h>
    #include <tchar.h>
    #include <iostream>
    
    #pragma execution_character_set("utf-8")
    
    // 全局变量
    static HWND hwnd;
    static HWND GameHwnd;
    static RECT WindowRectangle;
    static int WindowWide, WindowHeight;
    
    static LPDIRECT3D9 g_pD3D = NULL;
    static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
    static D3DPRESENT_PARAMETERS g_d3dpp = {};
    
    // 单选框设置状态
    bool show_another_window = false;
    
    // imgui 回调函数
    // By: LyShark
    extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    bool CreateDeviceD3D(HWND hWnd)
    {
    	if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
    	{
    		return false;
    	}
    
    	ZeroMemory(&g_d3dpp, 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;
    	g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    
    	if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0)
    	{
    		return false;
    	}
    	return true;
    }
    
    void CleanupDeviceD3D()
    {
    	if (g_pd3dDevice)
    	{
    		g_pd3dDevice->Release();
    		g_pd3dDevice = NULL;
    	}
    
    	if (g_pD3D)
    	{
    		g_pD3D->Release();
    		g_pD3D = NULL;
    	}
    }
    // https://www.cnblogs.com/lyshark
    void ResetDevice()
    {
    	ImGui_ImplDX9_InvalidateDeviceObjects();
    	HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp);
    	if (hr == D3DERR_INVALIDCALL)
    	{
    		IM_ASSERT(0);
    	}
    	ImGui_ImplDX9_CreateDeviceObjects();
    }
    
    LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
    	{
    		return true;
    	}
    
    	switch (msg)
    	{
    	case WM_SIZE:
    		if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
    		{
    			g_d3dpp.BackBufferWidth = LOWORD(lParam);
    			g_d3dpp.BackBufferHeight = HIWORD(lParam);
    			ResetDevice();
    		}
    		return 0;
    
    	case WM_SYSCOMMAND:
    		if ((wParam & 0xfff0) == SC_KEYMENU)
    		{
    			return 0;
    		}
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    
    // 绘制主方法
    // lyshark.com
    void DrawImGUI()
    {
    	// 启动IMGUI自绘
    	ImGui_ImplDX9_NewFrame();
    	ImGui_ImplWin32_NewFrame();
    	ImGui::NewFrame();
    
    	static float f = 0.0f;
    	static int counter = 0;
    	static char sz[256] = { 0 };
    
    	ImGui::Begin("LyShark 辅助GUI主菜单");
    	ImGui::Text("这是一段测试字符串");
    	ImGui::Checkbox("弹出子窗口", &show_another_window);
    	ImGui::SliderFloat("浮点条", &f, 0.0f, 1.0f);
    
    	ImGui::InputText("输入内容", sz, 256, 0, 0, 0);
    
    	if (ImGui::Button("点我触发"))
    		counter++;
    	ImGui::SameLine();
    	ImGui::Text("触发次数 = %d", counter);
    
    	ImGui::Text("当前FPS: %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
    	ImGui::End();
    
    	if (show_another_window)
    	{
    		ImGui::Begin("我是子窗体", &show_another_window);
    		ImGui::Text(" 您好,LyShark !");
    		if (ImGui::Button("关闭窗体"))
    			show_another_window = false;
    		ImGui::End();
    	}
    	ImGui::EndFrame();
    }
    
    // 自身窗口循环事件
    void WindowMessageLoop()
    {
    	bool done = false;
    	while (!done)
    	{
    		// 每次都将窗体置顶并跟随游戏窗体移动
    		GetWindowRect(GameHwnd, &WindowRectangle);
    		WindowWide = (WindowRectangle.right) - (WindowRectangle.left);
    		WindowHeight = (WindowRectangle.bottom) - (WindowRectangle.top);
    		DWORD dwStyle = GetWindowLong(GameHwnd, GWL_STYLE);
    		if (dwStyle & WS_BORDER)
    		{
    			WindowRectangle.top += 23;
    			WindowHeight -= 23;
    		}
    
    		// 跟随窗口移动
    		MoveWindow(hwnd, WindowRectangle.left + 8, WindowRectangle.top + 8, WindowWide - 11, WindowHeight - 11, true);
    
    		// 开始消息循环
    		MSG msg;
    		while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    			if (msg.message == WM_QUIT)
    			{
    				done = true;
    			}
    		}
    
    		if (done)
    		{
    			break;
    		}
    
    		// 开始绘制
    		DrawImGUI();
    
    		g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    		g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    		g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
    		g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
    
    		if (g_pd3dDevice->BeginScene() >= 0)
    		{
    			ImGui::Render();
    			ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
    			g_pd3dDevice->EndScene();
    		}
    
    		HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
    		if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
    		{
    			ResetDevice();
    		}
    	}
    }
    
    int main(int argc, char *argv[])
    {
    	// 注册窗体类
    	WNDCLASSEX wc;
    
    	// 附加到整个屏幕上
    	wc.cbClsExtra = NULL;
    	wc.cbSize = sizeof(WNDCLASSEX);
    	wc.cbWndExtra = NULL;
    	wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
    	wc.hCursor = LoadCursor(0, IDC_ARROW);
    	wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    	wc.hIconSm = LoadIcon(0, IDI_APPLICATION);
    	wc.hInstance = GetModuleHandle(NULL);
    	wc.lpfnWndProc = (WNDPROC)WndProc;
    	wc.lpszClassName = L" ";
    	wc.lpszMenuName = L" ";
    	wc.style = CS_VREDRAW | CS_HREDRAW;
    	::RegisterClassEx(&wc);
    
    	// 屏幕宽度和高度
    	WindowWide = GetSystemMetrics(SM_CXSCREEN);
    	WindowHeight = GetSystemMetrics(SM_CYSCREEN);
    
    	// 创建窗体
    	HWND hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TOOLWINDOW, L" ", L" ", WS_POPUP, 1, 1, WindowWide, WindowHeight, 0, 0, wc.hInstance, 0);
    
    	// 显示窗口
    	SetLayeredWindowAttributes(hwnd, 0, 1.0f, LWA_ALPHA);
    	SetLayeredWindowAttributes(hwnd, 0, RGB(0, 0, 0), LWA_COLORKEY);
    	ShowWindow(hwnd, SW_SHOW);
    
    	// 初始化D3D
    	if (!CreateDeviceD3D(hwnd))
    	{
    		CleanupDeviceD3D();
    		UnregisterClass(wc.lpszClassName, wc.hInstance);
    		return 0;
    	}
    
    	// 更新窗体
    	UpdateWindow(hwnd);
    
    	// 初始化ImGUI
    	ImGui::CreateContext();
    	ImGuiIO& io = ImGui::GetIO(); (void)io;
    	io.Fonts->AddFontFromFileTTF("c:/windows/fonts/simhei.ttf", 13.0f, NULL, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
    
    	ImGui::StyleColorsDark();
    	ImGui_ImplWin32_Init(hwnd);
    	ImGui_ImplDX9_Init(g_pd3dDevice);
    
    	// 开始执行绘制循环事件
    	WindowMessageLoop();
    
    	ImGui_ImplDX9_Shutdown();
    	ImGui_ImplWin32_Shutdown();
    	ImGui::DestroyContext();
    
    	CleanupDeviceD3D();
    	DestroyWindow(hwnd);
    	UnregisterClass(wc.lpszClassName, wc.hInstance);
    	return 0;
    }
    

    绘制效果如下:

  • 相关阅读:
    servlet上传图片 服务器路径(转)
    图片和提交servlet的相对和绝对路径
    Intel 的面试经历中国研究院
    CentOS-6.5-x86_64 最小化安装,已安装包的总数,这些包?
    西门子PLC学习笔记8-(计时器)
    这个周末我太累了
    windows7股票的,win8残疾人,安装Han澳大利亚sinoxn个时间,sinox它支持大多数windows软体
    net.sf.json 迄今 时刻 格式 办法
    ar命令提取.a时刻,一个错误 is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
    POJ 2187: Beauty Contest(旋转卡)
  • 原文地址:https://www.cnblogs.com/LyShark/p/16655693.html
Copyright © 2020-2023  润新知