问两个和游戏相关的问题

alphax 2005-08-15 05:22:17
近来在重温一个游戏,感觉兴趣来了,想做个修改器什么的,现在碰到两个问题,特来请教:

1,我的修改器进程能否在游戏的画面内显示一个窗口(windows,非模式的),这个窗口可以接收特殊按键(就是游戏没定义的按键),但我这个窗口使用的是游戏的主线程,通过按键调出,是否可行,大概应该怎么做?

2,如果我正在桌面操作我的修改器,我能否调用什么函数使之从桌面切换到游戏中

谢了
...全文
151 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
chijingde 2005-11-02
  • 打赏
  • 举报
回复
......
alphax 2005-10-28
  • 打赏
  • 举报
回复
我哪有这个本事啊?
chijingde 2005-08-29
  • 打赏
  • 举报
回复
结贴了?

老大搞出来了?
alphax 2005-08-18
  • 打赏
  • 举报
回复
昨晚弄了一下,好像直接显示一个窗口不行,我试着显示一个窗口,结果导致游戏退回桌面来显示我的窗口

to 甲骨文:
我有了新想法,不要在进程外操作它,我可以用我的程序来引导它,在他执行以前安排我一个DLL在他的进程内,然后通过键盘钩子使用它的游戏窗口线程来创建一个窗口,但是这个窗口必须和游戏窗口在同一个屏幕内,我的初步想法是把他安排在一个固定的角落,我按某个键时他才出来,有没有办法?或者在游戏窗口内开个区域显示也可以

我观察了一下,可以钩住键盘消息,但是鼠标消息勾不住,估计是用了DXInput,在XP下好像有一个wm_input消息和dxinput有关,我还没有具体试

昨晚看了一下dx的例子程序,头昏啊,咔咔,很多东西根本没接触过,概念很多,不知从何开始,还有几何的东西,混乱阿,咔咔

不过不着急,反正不是工作上的东西,慢慢来,先熟悉一些基本的dx概念再说,咔咔

hexenzhou 2005-08-18
  • 打赏
  • 举报
回复
有点难度,DxDraw好像还没有提供接口可以让进程外的程序操作它,一些的外挂好像是用了游戏本身提供的Plugin技术!
alphax 2005-08-16
  • 打赏
  • 举报
回复
看到你的短信了,很感谢你给我来一段
游戏用Window那一套来弄就好办
我晚上回家看看游戏是否用消息来处理键盘和鼠标的,具体问题明天再来讨教

现在想问,我想实现在DX的屏幕内显示一个置顶的窗口,不知道难度大不大?
chijingde 2005-08-16
  • 打赏
  • 举报
回复
怎么这么客气……

难度不知道,我没做过,不好说……


不过你来做的话,应该没什么问题吧?哈哈

chijingde 2005-08-15
  • 打赏
  • 举报
回复
void Cleanup(void)
{
//释放接口
SafeRelease(lpBmp);
SafeRelease(lpDDSPrimary);//删除主页面
SafeRelease(lpClip);//删除剪裁
SafeRelease(lpDD);//删除ddraw对象
//ps:与创建的顺序正好相反
}


void DrawImage()
{
if (lpBmp==NULL)
{
return;
}
//全屏画图
lpDDSPrimary->Blt(NULL,lpBmp,NULL,DDBLT_WAIT,NULL);
}

//************************************************************
//函数:WinMain( )
//功能:Windows程序入口函数。创建主窗口,处理消息循环
//************************************************************
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if ( !InitWindow( hInstance, nCmdShow ) ) return FALSE; //创建主窗口
//如果创建不成功则返回FALSE并同时退出程序
MSG msg;
//进入消息循环:
for(;;)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if ( msg.message==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}

//************************************************************
//函数:InitWindow( )
//功能:创建窗口
//************************************************************

static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
{
//定义窗口风格:
WNDCLASS wc;
wc.style = CS_VREDRAW|CS_HREDRAW;//窗体类的风格
wc.lpfnWndProc = (WNDPROC)WinProc; //窗口消息处理函数的指针
wc.cbClsExtra = 0;//分配给窗口类结构之后的额外字节数
wc.cbWndExtra = 0;//分配给窗口实例之后的额外字节数
wc.hInstance = hInstance;//窗口所对应的应用程序的句柄
wc.hIcon = NULL;//窗口的图标
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //窗口的鼠标
wc.hbrBackground = CreateSolidBrush (RGB(0, 0, 0)); //黑色的背景
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);//窗口的菜单资源名称
wc.lpszClassName = "My_Test";//窗口类的名称
RegisterClass(&wc);//注册窗口

//按所给参数创造窗口
hWnd = CreateWindow("My_Test",//创建窗口所用的窗口类的名称
"24小时学DX_第2个小时",//窗口标题
WS_POPUP|WS_CAPTION,//窗口风格,定义为普通型
0,0,//窗口位置的x,y坐标
1024,768,//窗口的宽度,高度
NULL,//父窗口句柄
NULL,//菜单句柄
hInstance,//应用程序句柄
NULL);
if(!hWnd ) return FALSE;
ShowWindow(hWnd,nCmdShow);//显示窗口
UpdateWindow(hWnd);//刷新窗口
InitDDraw();//初始化DX
return TRUE;
}

//************************************************************
//函数:WinProc( )
//功能:处理窗口消息
//************************************************************

LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch(message)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_Exit:
DestroyWindow(hWnd);
break;
}
break;
case WM_KEYDOWN://击键消息
switch(wParam)
{
case VK_ESCAPE:
PostMessage(hWnd, WM_CLOSE, 0, 0);//给窗口发送WM_CLOSE消息
break;
}
break;
case WM_PAINT://画图消息
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
DrawImage();
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //如果窗口被人释放…
Cleanup();
PostQuitMessage(0); //给窗口发送WM_QUIT消息
break;
default://调用缺省消息处理过程
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
chijingde 2005-08-15
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include "resource.h"
#define INITGUID
#include
#define SafeRelease(x) if (x) { x->Release(); x=NULL; }

//函数声明
BOOL InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
void DrawImage();

//变量说明
HWND hWnd; //窗口句柄

LPDIRECTDRAW7 lpDD=NULL;// DirectDraw对象的指针
LPDIRECTDRAWSURFACE7 lpDDSPrimary=NULL;// DirectDraw主页面的指针
LPDIRECTDRAWCLIPPER lpClip=NULL; // DirectDraw 剪裁对象
LPDIRECTDRAWSURFACE7 lpBmp=NULL; // 存放背景图的页面的指针

//************************************************************
//函数:InitDDraw()
//功能:DX初始化函数
//************************************************************
BOOL InitDDraw()
{
DDSURFACEDESC2 ddsd; // DirectDraw的页面描述
HRESULT hRet;
/*
如果要使用DirectDraw,必须创建一个DirectDraw对象,它是DirectDraw接口的核心。
用DirectDrawCreateEx( )函数可以创建DirectDraw对象,
DirectDrawCreateEx( )函数是在ddraw.h中定义的,它的原型如下:

HRESULT WINAPI DirectDrawCreateEx(
GUID FAR *lpGUID, //指向DirectDraw接口的GUID的指针,NULL表示采用默认(当前)
LPVOID *lplpDD, //用来接受初始化的DirectDraw对象的地址
REFIID iid, //IID_IDirectDraw7,当前版本
IUnknown FAR *pUnkOuter //NULL 保留
);
所有的DirectDraw函数的返回值都是HRESULT类型,它是一个32位的值。
函数调用成功用 "DD_OK"表示,
所有的错误值标志开头都为"DDERR",如:
DDERR_DIRECTDRAWALREADYCREATED
DDERR_OUTOFMEMORY
*/
if (DirectDrawCreateEx(NULL,(LPVOID*)&lpDD, IID_IDirectDraw7, NULL)!= DD_OK)
return FALSE; //创建DirectDraw对象
/*
DirectDrawCreate函数调用成功后,lpDD已经指向了一个DirectDraw对象,
它是整个DirectDraw接口的最高层领导,以后的步骤都是在它的控制之下。
我们用IDirectDraw7::SetCooperativeLevel( )来设置DirectDraw程序对系统的控制级。
它的原型如下:
HRESULT SetCooperativeLevel (HWND hWnd, DWORD dwFlags )
第一个参数是窗口句柄,我们给它hWnd,使DirectDraw对象与主窗口联系上。
第二个参数是控制级标志。这里使用DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN,
表示我们期望DirectDraw以独占和全屏方式工作。

控制级描述了DirectDraw是怎样与显示设备及系统作用的。
DirectDraw控制级一般被用来决定应用程序是运行于全屏模式(必须与独占模式同时使用),
还是运行于窗口模式。但DirectDraw的控制级还可设置如下两项:
(1)允许按Ctrl+Alt+Del重新启动(仅用于独占模式,为DDSCL_ALLOWREBOOT)。
(2)不允许对DirectDraw应用程序最小化或还原 (DDSCL_NOWINDOWCHANGES)。

普通的控制级(DDSCL_NORMAL)表明我们的DirectDraw应用程序将以窗口的形式运行。
在这种控制级下,我们将不能改变显示器分辨率,或进行换页操作(这是一个重要的操作)。
除此之外,我们也不能够调用那些会对显存产生激烈反应的函数,如Lock()。
当应用程序为全屏并且独占的控制级时,我们就可以充分的利用硬件资源了。
此时其它应用程序仍可创建页面、使用DirectDraw或GDI的函数,只是无法改变显示模式。
*/
if (lpDD->SetCooperativeLevel(hWnd,DDSCL_NORMAL)!= DD_OK)
return FALSE; //设置DirectDraw控制级
/*
下一步我们使用IDirectDraw7::SetDisplayMode( )来设置显示模式,其原形为:
HRESULT SetDisplayMode(
DWORD dwWidth,
DWORD dwHeight, //dwWidth and dwHeight用来设置显示模式的宽度和高度。
DWORD dwBPP, //dwBPP用来设置显示模式的颜色位数。
DWORD dwRefreshRate, //dwRefreshRate设置屏幕的刷新率,0为使用默认值。
DWORD dwFlags //dwFlags现在唯一有效的值是DDSDM_STANDARDVGAMODE
);
*/
if (lpDD->SetDisplayMode(1024,768,32,0,DDSDM_STANDARDVGAMODE)!= DD_OK)
return FALSE; //设置显示模式
/*
HRESULT CreateClipper(
DWORD dwFlags, //现在不用,必须设为0
LPDIRECTDRAWCLIPPER FAR *lplpDDClipper,//指向剪裁器对象的指针
IUnknown FAR *pUnkOuter // //现在不用,必须设为NULL
);
成功的时候返回DD_OK
*/

//创剪裁器(必须在设置完DirectDraw控制级后,创建主页面之前进行)
hRet=lpDD->CreateClipper(NULL,&lpClip,NULL);
if (hRet != DD_OK) {
return FALSE;
}
lpClip->SetHWnd(0,hWnd);

/*
创建一个页面之前,首先需要填充一个DDSURFACEDESC2结构,
它是DirectDraw Surface Description的缩写,意思是DirectDraw的页面描述。
它的结构非常庞大,这里只能作一个最简单的介绍。
要注意的是在填充此结构前一定要将其清空!
*/

//开始创建主页面,先清空页面描述
ZeroMemory(&ddsd, sizeof(ddsd));

//填充页面描述
ddsd.dwSize = sizeof(ddsd);//给dwSize页面描述的大小
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE;//主页面
/*
CreateSurface( )函数的第一个参数是被填充了页面信息的DDSURFACEDESC2结构的地址,
此处为&ddsd;
第二个参数是接收主页面指针的地址,此处为&lpDDSPrimary;
第三个参数现在必须为NULL,为该函数所保留。
如果函数调用成功,lpDDSPrimary将成为一个合法的主页面对象。
由于在前面已经设置了该程序的工作模式为独占和全屏,
所以,此时主页面所代表的实际上是我们的整个显示屏幕。
在主页面上所绘制的图形将立即反映到我们的显示屏幕上。
*/
if (lpDD->CreateSurface(&ddsd,&lpDDSPrimary, NULL) != DD_OK )
return FALSE; //创建主页面
lpDDSPrimary->SetClipper(lpClip);//设置剪裁
//载入图片
lpBmp=bitmap_surface(PicName);
//画图
DrawImage();
return TRUE;
}


chijingde 2005-08-15
  • 打赏
  • 举报
回复
楼上说的是通过暴雪提供的接口和SDK实现的,否则不可能让游戏的控制台调用
现在WOW也提供了SDK和接口,现在有好多这种嵌入到游戏的第三方插件
在网上可以搜到这类网站



to alphax:我也没研究过这个,不明白……

DX的初始化过程一般是这样的,贴段代码给你你一看就知道了
以DDraw为例,重点看InitDDraw这个函数,其他的基本上是win32下创建窗体那一套,对你来说小菜一碟
zousoft 2005-08-15
  • 打赏
  • 举报
回复
我最感到好奇的是,暗黑里的外挂,加载后他们会整合到暗黑游戏里,游戏会打出一行“xxx has been installed”,而且还可以接收暗黑聊天里的文字,作为自己的命令。比如在聊天框里输入".stop" 外挂就会停止运行,而且这行字还不会发送出去。。。感觉挺牛的,不知道怎么实现的。
g961681 2005-08-15
  • 打赏
  • 举报
回复
进来学习的!
hthunter 2005-08-15
  • 打赏
  • 举报
回复
金山游侠?呵呵
alphax 2005-08-15
  • 打赏
  • 举报
回复
别笑话我了,我从来没弄过,

你来了就好
我第一个问题是这样的:
就是我正在玩游戏,然后我按下我定义的hotkey,然后捕获程序不离开游戏画面在一个角落显示一个小窗口,这个窗口接不接收按键都无所谓,如果我可以截获所有的按键和鼠标的话,这样行不行?

我听说好像DX写的程序用钩子是无法钩住鼠标和按键的,是不是这样,有没有其他解决办法
我没弄过DX,不知道他和Windows有什么区别,你给我讲讲课阿

第二个问题,有点像alt-tab切换进程,就是切换回游戏,需要什么特殊函数么,还是ShowWindow就可以?DX的画面是Window么?

chijingde 2005-08-15
  • 打赏
  • 举报
回复
写出来给俺看看行不?

让俺也学习学习
chijingde 2005-08-15
  • 打赏
  • 举报
回复
外挂? alphax 怎么也对这个玩意感兴趣了?哈哈

俺也不会,瞎说几句,不知道对不对


1.DX写的游戏,初始化的时候,有个地方是控制是否独占,一般全屏的游戏都是独占的,看看改变它,然后让你的窗体最前端显示行不

2.DX写的游戏,一般都会有页面保护,主页面丢失,游戏一般就会终止,切换回去的时候,重新让他获得主页面就会继续,不知道是不是这个……

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧