设为首页 加入收藏

TOP

ImGUI 1.87 绘制D3D外部菜单(一)
2023-07-23 13:30:54 】 浏览:92
Tags: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 LPDIRECT
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇驱动开发:通过Async反向与内核通.. 下一篇有效字母异位词

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目