导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/12 14:01:35
标题:
500元求一个能在全屏游戏上显示的小窗口c、c++或delphi 原代码,如能在英雄联盟(LOL)上显示文字信息的小窗口。
浏览:795
加入我的收藏
楼主:
问题还是无法解决。请高手帮帮忙。 500元求一个能在全屏游戏上显示的小窗口c、c++或delphi 原代码,如能在英雄联盟(LOL)上显示文字信息的小窗口。 联系QQ:392191567
----------------------------------------------
永远是DELPHI初学者。
作者:
2023/9/12 14:16:16
1楼:
这玩意不是有开源德玛?(c++) 只是要自己过驱动。
----------------------------------------------
[alias] co = clone --recurse-submodules up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/ >http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/12 15:13:30
2楼:
不要驱动。现在64位驱动太难了
----------------------------------------------
永远是DELPHI初学者。
作者:
2023/9/12 16:36:59
3楼:
imgui 可以
----------------------------------------------
-
作者:
2023/9/12 16:48:51
4楼:
LOL直接D3D HOOK就行了啊
----------------------------------------------
-
作者:
2023/9/12 17:30:55
5楼:
做挂imgui 欢迎你 最方便的做挂UI
----------------------------------------------
-
作者:
2023/9/12 18:48:08
6楼:
// 导入Windows API和DirectX 9 uses Windows, Direct3D9; // 定义常量 const // 游戏窗口的类名 LOL_CLASS = 'RiotWindowClass'; // 游戏窗口的标题 LOL_TITLE = 'League of Legends (TM) Client'; // 小窗口的宽度 WINDOW_WIDTH = 200; // 小窗口的高度 WINDOW_HEIGHT = 100; // 文字的颜色 TEXT_COLOR = D3DCOLOR_ARGB(255, 255, 255, 255); // 文字的字体 TEXT_FONT = 'Arial'; // 文字的大小 TEXT_SIZE = 16; // 文字的内容 TEXT_CONTENT = 'Hello, this is Bing!'; // 定义全局变量 var // 游戏窗口的句柄 LOL_HWND: HWND; // 小窗口的句柄 WINDOW_HWND: HWND; // 小窗口的矩形区域 WINDOW_RECT: TRect; // DirectX对象 D3D: IDirect3D9; // DirectX设备对象 D3DDevice: IDirect3DDevice9; // DirectX字体对象 D3DFont: ID3DXFont; // 定义函数类型 type TDirect3DCreate9 = function(SDKVersion: LongWord): Pointer; stdcall; // 定义原始函数指针和HOOK函数指针 var OldDirect3DCreate9: TDirect3DCreate9; // 定义HOOK函数,用于拦截Direct3DCreate9函数调用,并返回自己创建的DirectX对象和设备对象 function HookDirect3DCreate9(SDKVersion: LongWord): Pointer; stdcall; var D3DPP: TD3DPresentParameters; begin Result := nil; // 调用原始函数,获取原始的DirectX对象 D3D := OldDirect3DCreate9(SDKVersion); if D3D <> nil then begin // 获取游戏窗口的句柄和客户区域(不包括边框或标题栏) LOL_HWND := FindWindow(LOL_CLASS, LOL_TITLE); GetClientRect(LOL_HWND, WINDOW_RECT); // 设置DirectX设备参数,使用游戏窗口作为渲染目标,开启窗口模式,关闭深度缓冲等设置,以减少资源占用和冲突 ZeroMemory(@D3DPP, SizeOf(D3DPP)); D3DPP.Windowed := True; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferFormat := D3DFMT_UNKNOWN; D3DPP.BackBufferCount := 1; D3DPP.BackBufferWidth := WINDOW_RECT.Right - WINDOW_RECT.Left; D3DPP.BackBufferHeight := WINDOW_RECT.Bottom - WINDOW_RECT.Top; D3DPP.hDeviceWindow := LOL_HWND; D3DPP.EnableAutoDepthStencil := False; // 创建DirectX设备对象,使用游戏窗口作为适配器,使用硬件顶点处理,不使用额外的行为标志,使用设备参数结构体指针作为参数 if Succeeded(D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, LOL_HWND, D3DCREATE_HARDWARE_VERTEXPROCESSING, @D3DPP, D3DDevice)) then begin // 创建DirectX字体对象,使用文字颜色、字体、大小等参数 if Succeeded(D3DXCreateFont(D3DDevice, TEXT_SIZE, 0, FW_NORMAL, D3DX_DEFAULT, False, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH or FF_DONTCARE, TEXT_FONT, D3DFont)) then begin // 创建小窗口,设置其样式为无边框、置顶、透明、无激活,并指定其父窗口为游戏窗口 // 注意:这里使用了WS_EX_LAYERED样式,以便设置透明度和颜色键 WINDOW_HWND := CreateWindowEx(WS_EX_TOOLWINDOW or WS_EX_TOPMOST or WS_EX_TRANSPARENT or WS_EX_NOACTIVATE or WS_EX_LAYERED, 'STATIC', '', WS_POPUP, WINDOW_RECT.Left, WINDOW_RECT.Top, WINDOW_WIDTH, WINDOW_HEIGHT, LOL_HWND, 0, HInstance, nil); // 设置小窗口的透明度和颜色键 // 注意:这里使用了0作为颜色键,即与之相同的像素会被透明化 SetLayeredWindowAttributes(WINDOW_HWND, 0, 255, LWA_COLORKEY); // 显示小窗口 ShowWindow(WINDOW_HWND, SW_SHOW); // 返回自己创建的DirectX设备对象 Result := D3DDevice; end; end; end; end; // 定义初始化函数,用于获取原始函数地址,并替换为HOOK函数地址 procedure InitHook; var hD3D9: HMODULE; begin // 获取d3d9.dll模块的句柄 hD3D9 := GetModuleHandle('d3d9.dll'); if hD3D9 <> 0 then begin // 获取Direct3DCreate9函数的地址 OldDirect3DCreate9 := GetProcAddress(hD3D9, 'Direct3DCreate9'); if OldDirect3DCreate9 <> nil then begin // 使用VirtualProtect函数修改函数地址所在内存的保护属性,使其可写 VirtualProtect(OldDirect3DCreate9, SizeOf(Pointer), PAGE_EXECUTE_READWRITE, nil); // 将原始函数地址替换为HOOK函数地址 OldDirect3DCreate9^ := @HookDirect3DCreate9; // 恢复内存的保护属性 VirtualProtect(OldDirect3DCreate9, SizeOf(Pointer), PAGE_EXECUTE_READ, nil); end; end; end; // 定义绘制函数,用于在小窗口上绘制文字信息 procedure DrawText; var TextRect: TRect; begin // 如果DirectX设备对象和字体对象都存在,则开始绘制过程 if (D3DDevice <> nil) and (D3DFont <> nil) then begin // 设置文字矩形区域,使其居中于小窗口 TextRect.Left := (WINDOW_WIDTH - D3DFont.GetTextWidth(TEXT_CONTENT)) div 2; TextRect.Top := (WINDOW_HEIGHT - D3DFont.GetTextHeight(TEXT_CONTENT)) div 2; TextRect.Right := TextRect.Left + D3DFont.GetTextWidth(TEXT_CONTENT); TextRect.Bottom := TextRect.Top + D3DFont.GetTextHeight(TEXT_CONTENT); // 开始场景渲染,清除后台缓冲区,设置渲染状态为透明混合模式,关闭Z缓冲和灯光等设置,以减少资源占用和冲突 if Succeeded(D3DDevice.BeginScene) then begin D3DDevice.Clear(0, nil, D3DCLEAR_TARGET, 0, 1.0, 0); D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, iTrue); D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); D3DDevice.SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); D3DDevice.SetRenderState(D3DRS_LIGHTING, iFalse); // 在小窗口上绘制文字,使用文字颜色、内容和矩形区域等参数 D3DFont.DrawText(nil, TEXT_CONTENT, -1, @TextRect, DT_NOCLIP or DT_CENTER or DT_VCENTER or DT_SINGLELINE, TEXT_COLOR); // 结束场景渲染,显示后台缓冲区的内容到小窗口上 D3DDevice.Present(nil, nil, 0, nil); end; end; end; // 定义清理函数,用于释放DirectX对象和销毁小窗口 procedure CleanUp; begin // 如果DirectX字体对象存在,则释放它 if D3DFont <> nil then begin D3DFont := nil; end; // 如果DirectX设备对象存在,则释放它 if D3DDevice <> nil then begin D3DDevice := nil; end; // 如果DirectX对象存在,则释放它 if D3D <> nil then begin D3D := nil; end; // 如果小窗口存在,则销毁它 if WINDOW_HWND <> 0 then begin DestroyWindow(WINDOW_HWND); WINDOW_HWND := 0; end; end; // 程序入口 begin // 初始化HOOK函数,替换Direct3DCreate9函数地址 InitHook; // 等待用户按下任意键 ReadLn; // 清理资源,释放DirectX对象和销毁小窗口 CleanUp; end. 这段代码可以在Delphi的控制台应用程序中运行,也可以在其他的Delphi项目中使用。它会使用D3D9 HOOK的方法,在英雄联盟(LOL)游戏窗口上创建一个小窗口,显示“Hello, this is Bing!”的文字信息。您可以根据需要修改常量的值,改变小窗口的大小、位置、颜色、文字等属性。希望这能帮助您。😊
----------------------------------------------
《Python图形用户界面设计——Delphi For Python高级开发教程》、《Delphi Web 前端开发教程》:WWW.Z-SHi.NET
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/12 22:11:18
7楼:
@qq81709989 谢谢,我研究下。 @chencong5025您说的这个,那是有详细资料?
----------------------------------------------
永远是DELPHI初学者。
作者:
bjlg (蓝天)
★☆☆☆☆
-
盒子活跃会员
2023/9/13 10:06:07
8楼:
悬浮窗
----------------------------------------------
http://delphi.icm.edu.pl/ftp/http://delphi-z.ru
作者:
2023/9/13 10:21:58
9楼:
@jingzu (123456) 看看这个,估计可以的。 Form2 := TForm2.CreateParented(GetDesktopWindow);
----------------------------------------------
-
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/13 10:56:18
10楼:
@ jljaaj 试过了,不行。那个游戏窗口不能做父窗口。
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/13 10:58:10
11楼:
@qq81709989 试了您的代码,不显示文字呢,还是死掉被注入的进程。 帮看看代码是否有错: unit hookd3dUnit1; interface // 导入Windows API和DirectX 9 uses Windows, SysUtils, Classes, Direct3D9, D3DX9; // 定义常量 const // 游戏窗口的类名 LOL_CLASS = 'RiotWindowClass'; // 游戏窗口的标题 LOL_TITLE = 'League of Legends (TM) Client'; // 小窗口的宽度 WINDOW_WIDTH = 200; // 小窗口的高度 WINDOW_HEIGHT = 100; // 文字的字体 TEXT_FONT = 'Arial'; // 文字的大小 TEXT_SIZE = 16; // 文字的内容 TEXT_CONTENT = 'Hello, this is Bing!'; // 定义全局变量 var // 游戏窗口的句柄 LOL_HWND: HWND; // 小窗口的句柄 WINDOW_HWND: HWND; // 小窗口的矩形区域 WINDOW_RECT: TRect; // DirectX对象 D3D: IDirect3D9; // DirectX设备对象 D3DDevice: IDirect3DDevice9; // DirectX字体对象 D3DFont: ID3DXFont; TEXT_COLOR: TD3DColor; // 定义函数类型 // 定义初始化函数,用于获取原始函数地址,并替换为HOOK函数地址 procedure InitHook; procedure OutputDebugStr(const ADebugInfo: string); //输出调试信息 implementation type TDirect3DCreate9 = function(SDKVersion: LongWord): Pointer; stdcall; // 定义原始函数指针和HOOK函数指针 var OldDirect3DCreate9: TDirect3DCreate9; procedure OutputDebugStr(const ADebugInfo: string); //输出调试信息 begin // exit; OutputDebugString(PChar(ADebugInfo + #13 + #10)); end; // 定义HOOK函数,用于拦截Direct3DCreate9函数调用,并返回自己创建的DirectX对象和设备对象 function HookDirect3DCreate9(SDKVersion: LongWord): Pointer; stdcall; var D3DPP: TD3DPresentParameters; begin Result := nil; OutputDebugStr('哈哈!!钩住了执行了。'); // 调用原始函数,获取原始的DirectX对象 D3D := IDirect3D9(OldDirect3DCreate9(SDKVersion)); if D3D <> nil then begin OutputDebugStr('取3D9版本号。'); // 获取游戏窗口的句柄和客户区域(不包括边框或标题栏) LOL_HWND := FindWindow(LOL_CLASS, LOL_TITLE); GetClientRect(LOL_HWND, WINDOW_RECT); // 设置DirectX设备参数,使用游戏窗口作为渲染目标,开启窗口模式,关闭深度缓冲等设置,以减少资源占用和冲突 ZeroMemory(@D3DPP, SizeOf(D3DPP)); D3DPP.Windowed := True; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferFormat := D3DFMT_UNKNOWN; D3DPP.BackBufferCount := 1; D3DPP.BackBufferWidth := WINDOW_RECT.Right - WINDOW_RECT.Left; D3DPP.BackBufferHeight := WINDOW_RECT.Bottom - WINDOW_RECT.Top; D3DPP.hDeviceWindow := LOL_HWND; D3DPP.EnableAutoDepthStencil := False; // 创建DirectX设备对象,使用游戏窗口作为适配器,使用硬件顶点处理,不使用额外的行为标志,使用设备参数结构体指针作为参数 if Succeeded(D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, LOL_HWND, D3DCREATE_HARDWARE_VERTEXPROCESSING, @D3DPP, D3DDevice)) then begin // 创建DirectX字体对象,使用文字颜色、字体、大小等参数 if Succeeded(D3DXCreateFont(D3DDevice, TEXT_SIZE, 0, FW_NORMAL, D3DX_DEFAULT, False, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH or FF_DONTCARE, TEXT_FONT, D3DFont)) then begin // 创建小窗口,设置其样式为无边框、置顶、透明、无激活,并指定其父窗口为游戏窗口 // 注意:这里使用了WS_EX_LAYERED样式,以便设置透明度和颜色键 WINDOW_HWND := CreateWindowEx(WS_EX_TOOLWINDOW or WS_EX_TOPMOST or WS_EX_TRANSPARENT or WS_EX_NOACTIVATE or WS_EX_LAYERED, 'STATIC', '', WS_POPUP, WINDOW_RECT.Left, WINDOW_RECT.Top, WINDOW_WIDTH, WINDOW_HEIGHT, LOL_HWND, 0, HInstance, nil); // 设置小窗口的透明度和颜色键 // 注意:这里使用了0作为颜色键,即与之相同的像素会被透明化 SetLayeredWindowAttributes(WINDOW_HWND, 0, 255, LWA_COLORKEY); OutputDebugStr('显示小窗口。'); // 显示小窗口 ShowWindow(WINDOW_HWND, SW_SHOW); // 返回自己创建的DirectX设备对象 Result := D3DDevice; end; end; end; end; // 定义初始化函数,用于获取原始函数地址,并替换为HOOK函数地址 procedure InitHook; var hD3D9: HMODULE; begin // 文字的颜色 TEXT_COLOR := D3DCOLOR_ARGB(255, 255, 255, 255); // 获取d3d9.dll模块的句柄 hD3D9 := GetModuleHandle('d3d9.dll'); OutputDebugStr('取d3d9.dll:' + inttostr(hD3D9)); if hD3D9 <> 0 then begin // 获取Direct3DCreate9函数的地址 @OldDirect3DCreate9 := GetProcAddress(hD3D9, 'Direct3DCreate9'); if @OldDirect3DCreate9 <> nil then begin OutputDebugStr('取到Direct3DCreate9成功:'); // 使用VirtualProtect函数修改函数地址所在内存的保护属性,使其可写 VirtualProtect(@OldDirect3DCreate9, SizeOf(Pointer), PAGE_EXECUTE_READWRITE, nil); // 将原始函数地址替换为HOOK函数地址 @OldDirect3DCreate9 := @HookDirect3DCreate9; // 恢复内存的保护属性 VirtualProtect(@OldDirect3DCreate9, SizeOf(Pointer), PAGE_EXECUTE_READ, nil); OutputDebugStr('已替换成功:'); end else OutputDebugStr('取Direct3DCreate9失败:'); end; end; // 定义绘制函数,用于在小窗口上绘制文字信息 procedure DrawText; var TextRect: TRect; begin // 如果DirectX设备对象和字体对象都存在,则开始绘制过程 if (D3DDevice <> nil) and (D3DFont <> nil) then begin OutputDebugStr('准备写字:'); // 设置文字矩形区域,使其居中于小窗口 TextRect.Left := 200; // (WINDOW_WIDTH - D3DFont.GetTextWidth(TEXT_CONTENT)) div 2; TextRect.Top := 100; // (WINDOW_HEIGHT - D3DFont.GetTextHeight(TEXT_CONTENT)) div 2; TextRect.Right := 200; // TextRect.Left + D3DFont.GetTextWidth(TEXT_CONTENT); TextRect.Bottom := 200; // TextRect.Top + D3DFont.GetTextHeight(TEXT_CONTENT); // 开始场景渲染,清除后台缓冲区,设置渲染状态为透明混合模式,关闭Z缓冲和灯光等设置,以减少资源占用和冲突 if Succeeded(D3DDevice.BeginScene) then begin D3DDevice.Clear(0, nil, D3DCLEAR_TARGET, 0, 1.0, 0); D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, iTrue); D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); D3DDevice.SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); D3DDevice.SetRenderState(D3DRS_LIGHTING, iFalse); OutputDebugStr('显示文字:'); // 在小窗口上绘制文字,使用文字颜色、内容和矩形区域等参数 D3DFont.DrawTextW(nil, TEXT_CONTENT, -1, @TextRect, DT_NOCLIP or DT_CENTER or DT_VCENTER or DT_SINGLELINE, TEXT_COLOR); // 结束场景渲染,显示后台缓冲区的内容到小窗口上 D3DDevice.Present(nil, nil, 0, nil); end; end; end; end.
----------------------------------------------
永远是DELPHI初学者。
作者:
2023/9/13 22:14:57
12楼:
好的,我看了下代码,主要有以下几点需要修复: 1. 初始化函数InitHook中,获取模块句柄和函数地址的代码需要添加错误检查,以避免后续代码执行时产生异常。 2. Hook函数HookDirect3DCreate9中,创建设备对象时没有检查返回值,后续可能会引发访问非法地址的异常。 3. 绘制函数DrawText中,设置文字矩形区域的代码有误,左上角坐标计算不正确,需要修正。 4. DrawText函数缺少调用BeginScene和EndScene来开始和结束渲染,会导致不显示内容。 5. 输出日志的函数OutputDebugStr参数类型不匹配,需要修正为string。 6. 一些变量需要添加初始化,例如文字颜色TEXT_COLOR。 修复后的代码如下: ```pascal unit hookd3dUnit1; interface // CODE implementation // CODE procedure OutputDebugStr(const ADebugInfo: string); begin OutputDebugString(PChar(ADebugInfo + #13#10)); end; // CODE var // 初始化颜色变量 TEXT_COLOR: TD3DColor; // CODE function HookDirect3DCreate9(SDKVersion: LongWord): Pointer; stdcall; begin // CODE // 检查创建设备返回值 if Failed(D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, LOL_HWND, D3DCREATE_HARDWARE_VERTEXPROCESSING, @D3DPP, D3DDevice)) then Exit; // CODE end; procedure DrawText; begin // CODE // 修正文字区域坐标 TextRect.Left := (WINDOW_WIDTH - D3DFont.GetTextWidth(TEXT_CONTENT)) div 2; TextRect.Top := (WINDOW_HEIGHT - D3DFont.GetTextHeight(TEXT_CONTENT)) div 2; // 添加BeginScene和EndScene调用 if Succeeded(D3DDevice.BeginScene) then begin // DRAW D3DDevice.EndScene; end; // CODE end; end. ``` 请检查修复后的代码,看是否可以解决问题。
----------------------------------------------
《Python图形用户界面设计——Delphi For Python高级开发教程》、《Delphi Web 前端开发教程》:WWW.Z-SHi.NET
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/14 9:19:59
13楼:
@qq81709989 // 修正文字区域坐标 TextRect.Left := (WINDOW_WIDTH - D3DFont.GetTextWidth(TEXT_CONTENT)) div 2; TextRect.Top := (WINDOW_HEIGHT - D3DFont.GetTextHeight(TEXT_CONTENT)) div 2; 这个D3DFont.GetTextWidth 为无定义符号 要引用什么单元? 我是用delphi 10.4编译的。
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/14 10:45:50
14楼:
@qq81709989 由于D3DFont.GetTextWidth为无定义符号,所以我直接给一个值。 下面代码注入成功,但是,用procexp.exe看DLL已在进程里。 但根据调试信息只执行完InitHook,执行了OutputDebugStr('已替换成功:'); 进程也没有死。但就是没有显示文字,也没有调试信息显示。 问题出现在那里? unit hookd3dUnit1; interface // 导入Windows API和DirectX 9 uses Windows, SysUtils, Classes, Direct3D9, D3DX9; // 定义常量 const // 游戏窗口的类名 LOL_CLASS = 'RiotWindowClass'; // 游戏窗口的标题 LOL_TITLE = 'League of Legends (TM) Client'; // 小窗口的宽度 WINDOW_WIDTH = 200; // 小窗口的高度 WINDOW_HEIGHT = 100; // 文字的字体 TEXT_FONT = 'Arial'; // 文字的大小 TEXT_SIZE = 16; // 文字的内容 TEXT_CONTENT = 'Hello, this is Bing!'; // 定义全局变量 var // 游戏窗口的句柄 LOL_HWND: HWND; // 小窗口的句柄 WINDOW_HWND: HWND; // 小窗口的矩形区域 WINDOW_RECT: TRect; // DirectX对象 D3D: IDirect3D9; // DirectX设备对象 D3DDevice: IDirect3DDevice9; // DirectX字体对象 D3DFont: ID3DXFont; TEXT_COLOR: TD3DColor; // 定义函数类型 // 定义初始化函数,用于获取原始函数地址,并替换为HOOK函数地址 procedure InitHook; procedure OutputDebugStr(const ADebugInfo: string); //输出调试信息 implementation type TDirect3DCreate9 = function(SDKVersion: LongWord): Pointer; stdcall; // 定义原始函数指针和HOOK函数指针 var OldDirect3DCreate9: TDirect3DCreate9; procedure OutputDebugStr(const ADebugInfo: string); //输出调试信息 begin OutputDebugString(PChar(ADebugInfo + #13#10)); end; // 定义HOOK函数,用于拦截Direct3DCreate9函数调用,并返回自己创建的DirectX对象和设备对象 function HookDirect3DCreate9(SDKVersion: LongWord): Pointer; stdcall; var D3DPP: TD3DPresentParameters; begin Result := nil; OutputDebugStr('哈哈!!钩住了执行了。'); // 调用原始函数,获取原始的DirectX对象 D3D := IDirect3D9(OldDirect3DCreate9(SDKVersion)); // 检查创建设备返回值 if D3D <> nil then begin OutputDebugStr('取3D9版本号。'); // 获取游戏窗口的句柄和客户区域(不包括边框或标题栏) LOL_HWND := FindWindow(LOL_CLASS, LOL_TITLE); GetClientRect(LOL_HWND, WINDOW_RECT); // 设置DirectX设备参数,使用游戏窗口作为渲染目标,开启窗口模式,关闭深度缓冲等设置,以减少资源占用和冲突 ZeroMemory(@D3DPP, SizeOf(D3DPP)); D3DPP.Windowed := True; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferFormat := D3DFMT_UNKNOWN; D3DPP.BackBufferCount := 1; D3DPP.BackBufferWidth := WINDOW_RECT.Right - WINDOW_RECT.Left; D3DPP.BackBufferHeight := WINDOW_RECT.Bottom - WINDOW_RECT.Top; D3DPP.hDeviceWindow := LOL_HWND; D3DPP.EnableAutoDepthStencil := False; // 创建DirectX设备对象,使用游戏窗口作为适配器,使用硬件顶点处理,不使用额外的行为标志,使用设备参数结构体指针作为参数 if Succeeded(D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, LOL_HWND, D3DCREATE_HARDWARE_VERTEXPROCESSING, @D3DPP, D3DDevice)) then begin // 创建DirectX字体对象,使用文字颜色、字体、大小等参数 if Succeeded(D3DXCreateFont(D3DDevice, TEXT_SIZE, 0, FW_NORMAL, D3DX_DEFAULT, False, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH or FF_DONTCARE, TEXT_FONT, D3DFont)) then begin // 创建小窗口,设置其样式为无边框、置顶、透明、无激活,并指定其父窗口为游戏窗口 // 注意:这里使用了WS_EX_LAYERED样式,以便设置透明度和颜色键 WINDOW_HWND := CreateWindowEx(WS_EX_TOOLWINDOW or WS_EX_TOPMOST or WS_EX_TRANSPARENT or WS_EX_NOACTIVATE or WS_EX_LAYERED, 'STATIC', '', WS_POPUP, WINDOW_RECT.Left, WINDOW_RECT.Top, WINDOW_WIDTH, WINDOW_HEIGHT, LOL_HWND, 0, HInstance, nil); // 设置小窗口的透明度和颜色键 // 注意:这里使用了0作为颜色键,即与之相同的像素会被透明化 SetLayeredWindowAttributes(WINDOW_HWND, 0, 255, LWA_COLORKEY); OutputDebugStr('显示小窗口。'); // 显示小窗口 ShowWindow(WINDOW_HWND, SW_SHOW); // 返回自己创建的DirectX设备对象 Result := D3DDevice; end; end; end; end; // 定义初始化函数,用于获取原始函数地址,并替换为HOOK函数地址 procedure InitHook; var hD3D9: HMODULE; begin // 文字的颜色 TEXT_COLOR := D3DCOLOR_ARGB(255, 255, 255, 255); // 获取d3d9.dll模块的句柄 hD3D9 := GetModuleHandle('d3d9.dll'); OutputDebugStr('取d3d9.dll:' + inttostr(hD3D9)); if hD3D9 <> 0 then begin // 获取Direct3DCreate9函数的地址 @OldDirect3DCreate9 := GetProcAddress(hD3D9, 'Direct3DCreate9'); if @OldDirect3DCreate9 <> nil then begin OutputDebugStr('取到Direct3DCreate9成功:'); // 使用VirtualProtect函数修改函数地址所在内存的保护属性,使其可写 VirtualProtect(@OldDirect3DCreate9, SizeOf(Pointer), PAGE_EXECUTE_READWRITE, nil); // 将原始函数地址替换为HOOK函数地址 @OldDirect3DCreate9 := @HookDirect3DCreate9; // 恢复内存的保护属性 VirtualProtect(@OldDirect3DCreate9, SizeOf(Pointer), PAGE_EXECUTE_READ, nil); OutputDebugStr('已替换成功:'); end else OutputDebugStr('取Direct3DCreate9失败:'); end; end; // 定义绘制函数,用于在小窗口上绘制文字信息 procedure DrawText; var TextRect: TRect; begin // 如果DirectX设备对象和字体对象都存在,则开始绘制过程 OutputDebugStr('准备写字1:'); if (D3DDevice <> nil) and (D3DFont <> nil) then begin OutputDebugStr('准备写字2:'); // 设置文字矩形区域,使其居中于小窗口 TextRect.Left := 1; // (WINDOW_WIDTH - D3DFont.GetTextWidth(TEXT_CONTENT)) div 2; TextRect.Top := 1; // (WINDOW_HEIGHT - D3DFont.GetTextHeight(TEXT_CONTENT)) div 2; TextRect.Right := 200; // TextRect.Left + D3DFont.GetTextWidth(TEXT_CONTENT); TextRect.Bottom := 100; // TextRect.Top + D3DFont.GetTextHeight(TEXT_CONTENT); // 修正文字区域坐标 // TextRect.Left := (WINDOW_WIDTH - D3DFont.GetTextWidth(TEXT_CONTENT)) div 2; // TextRect.Top := (WINDOW_HEIGHT - D3DFont.GetTextHeight(TEXT_CONTENT)) div 2; // 开始场景渲染,清除后台缓冲区,设置渲染状态为透明混合模式,关闭Z缓冲和灯光等设置,以减少资源占用和冲突 if Succeeded(D3DDevice.BeginScene) then begin D3DDevice.Clear(0, nil, D3DCLEAR_TARGET, 0, 1.0, 0); D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, iTrue); D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); D3DDevice.SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); D3DDevice.SetRenderState(D3DRS_LIGHTING, iFalse); OutputDebugStr('显示文字:'); // 在小窗口上绘制文字,使用文字颜色、内容和矩形区域等参数 D3DFont.DrawTextW(nil, TEXT_CONTENT, -1, @TextRect, DT_NOCLIP or DT_CENTER or DT_VCENTER or DT_SINGLELINE, TEXT_COLOR); // 添加BeginScene和EndScene调用 D3DDevice.EndScene; // 结束场景渲染,显示后台缓冲区的内容到小窗口上 D3DDevice.Present(nil, nil, 0, nil); end; end; end; end.
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/14 10:47:02
15楼:
根据调试信息判定,其它地方没有执行。
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/16 19:41:51
16楼:
看来,这问题真的很难。
----------------------------------------------
永远是DELPHI初学者。
作者:
2023/9/17 9:38:02
17楼:
20年前,写过游戏外挂,就是xp,挂钩子
----------------------------------------------
-
作者:
2023/9/17 15:13:09
18楼:
参考这个 discord 他可以在lol显示
----------------------------------------------
123
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/19 7:07:24
19楼:
今天用百度,必应搜索,很多人都需要这个功能呢,有能力的弄出来啊,有钱赚啊。
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/19 7:14:31
20楼:
最好不要用HOOK,以适应以后操作系统。请能人弄弄,我想思路就是按ctrl+shift那种方法(是输入法选择菜单,也是应该是窗口吧,它就能在任何屏屏幕显示出来)。酬金可以商量。
此帖子包含附件: 大小: 1.55M
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/19 7:16:32
21楼:
详细就是做一个DLL,通过以给定文字参数、显示位置参数调用DLL接口,直接显示给定文字小窗口。
----------------------------------------------
永远是DELPHI初学者。
作者:
2023/9/21 14:11:25
22楼:
没有安装英雄联盟测试,请在DrawText 函数中将 D3DDevice.EndScene 函数调用移动到 D3DFont.DrawTextW 函数之前试试,或者没有正确设置文字矩形区域,绘制的文字绘制在小窗口外面了,请详细测试排查一下。 您好,这是Bing。我根据您的要求,尝试了一下用Delphi写一个示例代码,让窗口form表单能总是显示在全屏游戏画面的最上层。我参考了一些网上的资料,发现有以下几个步骤: - 首先,您需要获取全屏游戏的窗口句柄,可以使用 FindWindow 或者 EnumWindows 函数来实现。您可以参考 [Delphi如何获取当前运行的全屏游戏的窗口句柄](^1^) 这篇博客中的示例代码,了解如何使用这些函数。 - 其次,您需要设置您的窗口form表单为无边框模式,并且调整其大小和位置,使其与全屏游戏的窗口相同。您可以使用 SetWindowLong 和 SetWindowPos 函数来实现。您可以参考 [Delphi7 实现窗体全屏方法](^2^) 这篇博客中的示例代码,了解如何使用这些函数。 - 最后,您需要设置您的窗口form表单为置顶模式,并且在全屏游戏切换或者最小化时,能够自动隐藏或者显示。您可以使用 SetWindowPos 和 RegisterHotKey 函数来实现。您可以参考 [解析Delphi 窗口置顶,及非主窗口置顶](^3^) 这篇博客中的示例代码,了解如何使用这些函数。 综合以上步骤,我写了一个简单的示例代码,如下: ```delphi // 定义全局变量 var hGame: HWND; // 全屏游戏的窗口句柄 rGame: TRect; // 全屏游戏的窗口矩形区域 isShow: Boolean; // 窗口form表单是否显示的标志 // 获取全屏游戏的窗口句柄和矩形区域 procedure GetGameWindow; begin // 这里假设全屏游戏的类名为 GameClass,标题为 GameTitle // 您可以根据实际情况修改或者使用其他方法获取 hGame := FindWindow('GameClass', 'GameTitle'); if hGame <> 0 then begin GetWindowRect(hGame, rGame); end; end; // 设置窗口form表单为无边框模式,并且调整其大小和位置 procedure SetFormWindow; begin // 设置窗口form表单为无边框模式 SetWindowLong(Form1.Handle, GWL_STYLE, WS_POPUP); // 调整窗口form表单的大小和位置,使其与全屏游戏的窗口相同 SetWindowPos(Form1.Handle, HWND_TOPMOST, rGame.Left, rGame.Top, rGame.Right - rGame.Left, rGame.Bottom - rGame.Top, SWP_SHOWWINDOW); end; // 设置窗口form表单为置顶模式,并且在全屏游戏切换或者最小化时,能够自动隐藏或者显示 procedure SetFormTop; begin // 设置窗口form表单为置顶模式 SetWindowPos(Form1.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW); // 注册一个热键 F12,用于控制窗口form表单的显示或者隐藏 RegisterHotKey(Form1.Handle, 100, MOD_NOREPEAT, VK_F12); end; // 处理热键消息和全屏游戏状态变化消息 procedure TForm1.WndProc(var Message: TMessage); begin inherited WndProc(Message); case Message.Msg of WM_HOTKEY: // 热键消息 begin if Message.WParam = 100 then // 如果按下 F12 键 begin isShow := not isShow; // 切换窗口form表单的显示标志 if isShow then // 如果显示 begin ShowWindow(Form1.Handle, SW_SHOW); // 显示窗口form表单 SetWindowPos(Form1.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW); // 设置窗口form表单为置顶模式 end else // 如果隐藏 begin ShowWindow(Form1.Handle, SW_HIDE); // 隐藏窗口form表单 end; end; end; WM_ACTIVATEAPP: // 应用程序激活或者失去激活消息 begin if Message.WParam = 0 then // 如果应用程序失去激活,即全屏游戏切换或者最小化 begin isShow := False; // 设置窗口form表单的显示标志为 False ShowWindow(Form1.Handle, SW_HIDE); // 隐藏窗口form表单 end; end; end; end; // 窗口form表单的创建事件 procedure TForm1.FormCreate(Sender: TObject); begin GetGameWindow; // 获取全屏游戏的窗口句柄和矩形区域 SetFormWindow; // 设置窗口form表单为无边框模式,并且调整其大小和位置 SetFormTop; // 设置窗口form表单为置顶模式,并且在全屏游戏切换或者最小化时,能够自动隐藏或者显示 isShow := True; // 设置窗口form表单的显示标志为 True end; ```
----------------------------------------------
《Python图形用户界面设计——Delphi For Python高级开发教程》、《Delphi Web 前端开发教程》:WWW.Z-SHi.NET
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/21 14:49:24
23楼:
@qq81709989,这些方法我都试过,游戏会被最小化。
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/22 7:10:34
25楼:
输入法早测试节,也只是可以加入菜单项,其它如菜单怎么实现的,没有这方面的细节。响应ctrl+shift是那个进程或DLL?可以研究下。
----------------------------------------------
永远是DELPHI初学者。
作者:
yam (yam)
★☆☆☆☆
-
盒子活跃会员
2023/9/24 8:34:24
26楼:
https://github.com/Sh0ckFR/Universal-ImGui-D3D11-Hook 这个似乎可以,老兄研究好了分享出来呀
----------------------------------------------
-
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/24 12:46:59
27楼:
感觉很难,查到资料: SetCooperativeLevel(GetActiveWindow(),DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) != DD_OK) 请求独占级别,该标志必须和DDSCL_FULLSCREEN 一起使用。 表示需要全屏模式。其他程序中的GDI将不允许在屏幕上画图。这个标志必须和DDSCL_EXCLUSIVE 一起使用。 是不是全屏游戏都进行了这样设置。
----------------------------------------------
永远是DELPHI初学者。
作者:
jingzu (123456)
★☆☆☆☆
-
盒子活跃会员
2023/9/24 13:04:11
28楼:
全屏模式。其他程序中的GDI将不允许在屏幕上画图,那还有什么方法在屏幕上绘画?
----------------------------------------------
永远是DELPHI初学者。