24小时热门版块排行榜    

查看: 165  |  回复: 1
当前主题已经存档。

zsglly

木虫 (著名写手)

[交流] 在DirectX下弹出对话框

金山公司出品的游戏修改器——《金山游侠》,以其独特的“DirectX下智能弹出”的功能在众多的游戏修改器中独树一帜,赢得了众多玩家的喜爱。

“DirectX下智能弹出”在抓图、游戏修改器、游戏调试等方面都非常有用。那么,它的原理是什么?我们能在自己的软件中实现它吗?我经过一番努力,终于揭开了“DirectX下智能弹出”的神秘面纱。

1.   预备知识
在开始前,有必要介绍一点关于Hook与Windows的基础知识。

众所周知,Windows是一个消息驱动的32位操作系统。在Windows中,所有正在运的进程都有一个独立的2GB的虚拟地址空间,进程之间相互不可见。Windows的绝大多数API与消息是不能跨越进程的。

“Hook”在Windows中主要是用来截取消息的,形象说,就是用来“钩” 消息的。Hook实际上是一个处理消息的程序段,每当特定的消息发出,在没有到达目的窗口前,Hook函数就先捕获该消息,即Hook函数先得到处理消息的控制权。而且如果你把Hook实现在DLL文件中,那么Hook函数将会自动被系统映射到会处理那个特定消息的窗口所在的进程虚拟地址空间中。例如,你可以用Hook来捕获系统中所有的键盘输入消息(WM_KEYDOWN)来实现对电脑使用者的输入进行记录(关于Windows进程管理与Hook 的详细用法,请参阅MSDN与相关资料)。

2.   原理
微软的 DirectX 为Windows下的游戏带来了华丽的声光效果。但是由于DirectX采用直接访问布姆椒ㄌ岣叨嗝教逵胗蜗烦绦虻乃俣龋虼说贾铝巳嗣俏笠晕贒irectX(确切地说是DirectDraw)下不能显示普通的Windows对话框。

       但是DirectX是支持GDI的,也就是说游戏可以用常规的方法在DirectX下显示对话框(在微软 DirectX 8 SDK 中有名为“FullScreenDialog”的例子)。现在我们的问题是:如上所述,调用API建立与显示对话框必须要在该进程的内部,而我们的程序是在游戏进程的外部,这样,那些CreateDialog() 与DialogBox() 只会引起“非法操作”或不起任何作用。

       但是,有了上面所讲的Hook情况就不同了。既然Hook可以映射到别的进程内部,那么只要将显示对话框的函数以及对话框资源包括在Hook DLL 中不就可以调用DialogBox() 了吗?完全正确!我们用 SetWindowsHookEx() 为系统设置一个键盘消息Hook,系统会自动将这个DLL映射到游戏的进程中。每当有键盘消息,我们只要判断是不是我们所设定的热键,如果是就调用 DialogBox() 显示对话框即可。

       由此可见,Hook为我们解决了系统级热键与插入DLL两大难题,真是一举两得!也从一个方面说明了学习Windows基础知识的重要性,如果你有钻研精神,又有像《Windows核心编程》这样的好书指引,就一定能成为顶尖高手。

3.示例源程序
       限于篇幅,只能摘抄几段关键的代码,程序中有注释,自己研究吧。

// TestPopup.cpp : Defines the entry point for the DLL application.

//

  

#include "stdafx.h"

#include "TestPopup.h"

  

#define SHARD_SEG_NAME "SHARD_DATA"

  

//共享数据段

#pragma data_seg(SHARD_SEG_NAME)

#pragma bss_seg(SHARD_SEG_NAME)

  

static BOOL g_fIsInstalled = FALSE;

static HHOOK g_hKeyHook;

static HINSTANCE g_hInstance;

static HWND g_hWnd;

  

#pragma data_seg()

  

BOOL APIENTRY DllMain( HANDLE hModule,  

                       DWORD  ul_reason_for_call,  

                       LPVOID lpReserved

                     )

{

  

    g_hInstance = (HINSTANCE)hModule;

  

  

    switch (ul_reason_for_call)

    {

        case DLL_PROCESS_ATTACH:

        case DLL_THREAD_ATTACH:

        case DLL_THREAD_DETACH:

        case DLL_PROCESS_DETACH:

            break;

    }

    return TRUE;

}

  

//键盘消息处理程序

LRESULT TESTPOPUP_API CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

{

    //if(((DWORD)lParam & 0x40000000) && (HC_ACTION == nCode));

    WORD wKey = (WORD)wParam;

     

    //键按下

    if((HIWORD(lParam) & KF_UP) == 0 && HC_ACTION == nCode)

    {        

        if(wKey == VK_ADD)//是热键

        {

            //获取前台窗口(游戏窗口)

            HWND hWnd = ::GetForegroundWindow();

            //创建并显示模式对话框

            :ialogBox(g_hInstance, MAKEINTRESOURCE(IDD_MAIN_DIALOG), hWnd, DLGPROC(DialogProc));

        }

    }

  

    LRESULT RetVal = CallNextHookEx(g_hKeyHook, nCode, wParam, lParam );

  

    return  RetVal;

}

  

BOOL TESTPOPUP_API InstallHotKey()

{

    if(g_fIsInstalled)return FALSE;

     

    g_hKeyHook = ::SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc, g_hInstance, 0);//安装 Hook

    g_fIsInstalled = TRUE;

  

    return TRUE;

}

  

BOOL TESTPOPUP_API UninstHotKey()

{

    BOOL bRet;

     

    bRet = ::UnhookWindowsHookEx(g_hKeyHook);

    g_fIsInstalled = FALSE;

    g_hKeyHook = NULL;

  

    return bRet;

}

  

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

    switch (uMsg)

    {

        case WM_INITDIALOG:

            return TRUE;

  

        case WM_COMMAND:

            switch( LOWORD(wParam) )

            {

                case IDCANCEL:

                case IDOK:

                    EndDialog( hwndDlg, TRUE );

                    return TRUE;

            }

            break;
        case WM_MOVE:

            break;

          case WM_DESTROY:

            g_hWnd = NULL;

            break;
    }
    return FALSE;

  }


//TestPopupDemoDlg.C

void CTestPopupDemoDlg::OnEnableHotkey()  

{

    // TODO: Add your control notification handler code here

    UpdateData();

  

    if(m_fHotkeyEnabled)

    {

        ::InstallHotKey();

    }

    else

    {
        ::UninstHotKey();

    }

    UpdateData(FALSE);

  }

   

本程序在Microsoft Visual C++、Win97下调试通过。

[ Last edited by 幻影无痕 on 2006-11-27 at 10:23 ]
回复此楼
做人要厚道啊!厚道啊!
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

娃哈哈212

新虫 (初入文坛)

0.5

好 顶
2楼2005-12-29 19:23:24
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 zsglly 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[公派出国] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +3 4FFAWE8HcgUD 2026-08-29 4/200 2026-08-30 20:21 by hZiFeudZyoGR
[硕博家园] 售SCI一区T0P文章,我:8.O.55.1.O.5.4,科目全,可+急 +3 4FFAWE8HcgUD 2026-08-29 3/150 2026-08-30 20:10 by hZiFeudZyoGR
[公派出国] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +4 G6APbkg8SA6w 2026-08-29 5/250 2026-08-30 18:51 by hZiFeudZyoGR
[论文投稿] 售SCI一区文章,我:8.O.551.O.5.4,科目全,可伽急 +5 gy1nBQXYQJqL 2026-08-29 5/250 2026-08-30 18:29 by hZiFeudZyoGR
[考博] 售SCI-T0P文章,我:8O.5.5.1.O.54,科目齐全,可+急 +4 gy1nBQXYQJqL 2026-08-29 6/300 2026-08-30 18:20 by hZiFeudZyoGR
[公派出国] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +6 gy1nBQXYQJqL 2026-08-29 9/450 2026-08-30 17:56 by hZiFeudZyoGR
[公派出国] 售SCI文章,我:8O.5.5.1O.54,科目全,可十急 +7 ASdOkHsho7FD 2026-08-28 9/450 2026-08-30 17:34 by hZiFeudZyoGR
[博后之家] 售SCI文章,我:8O.5.5.1O.54,科目全,可十急 +5 gy1nBQXYQJqL 2026-08-29 8/400 2026-08-30 12:03 by l0VvVHGBGRLv
[找工作] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +4 gy1nBQXYQJqL 2026-08-29 8/400 2026-08-30 12:03 by l0VvVHGBGRLv
[论文投稿] 售一区SCI文章T0P,我:8O.551.O54,科目全,可十急 +5 gy1nBQXYQJqL 2026-08-29 7/350 2026-08-30 11:51 by l0VvVHGBGRLv
[基金申请] 麻烦专家们看看评委们的意见(F口面上) +6 gdd2018 2026-08-28 11/550 2026-08-30 08:58 by 超级无敌华子
[基金申请] 我就是申请一个面上项目而已,这评审意见是按照杰青的条件评的吧? +6 gouxfjh 2026-08-28 11/550 2026-08-30 07:57 by gouxfjh
[硕博家园] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +6 ASdOkHsho7FD 2026-08-28 11/550 2026-08-30 06:00 by ZPa0EcMwuECS
[教师之家] 导师吐槽:我怎么摊上了这么个极品研究生! +9 苏东坡二世 2026-08-23 9/450 2026-08-29 14:41 by hustersqt
[基金申请] 基金不中,共勉 +11 eulota 2026-08-26 11/550 2026-08-28 14:22 by 火星超人xi
[基金申请] 基金系统什么内容也没有 30+4 winsaint 2026-08-27 9/450 2026-08-28 11:06 by maolC
[基金申请] 怎么查啊 +6 huang1991js 2026-08-26 6/300 2026-08-28 08:42 by winsaint
[基金申请] 哪位高人中了,把查询到的截图贴出来让我看看,让我长长见识 +5 yuleib84 2026-08-26 6/300 2026-08-28 00:02 by yudaoqian88
[基金申请] 面上合作单位盖章 +5 ssyjh 2026-08-27 5/250 2026-08-27 20:50 by gdfollow
[基金申请] 国际合作可查了,中了面上 (EPI+1)(金币+50) +18 Ldrop2023 2026-08-26 18/900 2026-08-26 11:15 by cmrandy
信息提示
请填处理意见