Windows编程 DirectInput 鼠标和键盘的输入

版本:VS2015 语言:C++

 

书的第八章是一些数学的知识,以及一个图形库的创建。数学知识是有必要看一看的,我这里就不做多的介绍了,图形库的话反正你现在的win7+系统上也运行不了,看看就好。因为虽然这本书(《Windows游戏编程大师技巧》)非常的经典,但是代码都是比较老的,很多都已经过时了不能运行,所以我们要明确我们的目的,学好基础知识,编写一下程序练练手,熟悉熟悉Direct的流程以及原理,至于正真的想要运用的话,凭着这些知识学习最新的dx,或者直接上引擎,研究引擎中的代码。

 

好了,说了这么多,其实这本书就是为了入门。

 

今天讲的是第九章的内容,主要实现使用键盘和鼠标控制。

 

首先是基础的代码:

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)	//判断当前的按键是否被按下
#define DDRAW_INIT_STRUCT(ddsd) { memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); }
#define _RGB32BIT(a, r, g, b) ((b) + (g << 8) + (r << 16) + (a << 24))

HWND main_window_handle = NULL;	//当前窗口
LPDIRECTDRAW7 lpdd = NULL;	//Direct7对象,下称d7

LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;	//主显示表面指针
LPDIRECTDRAWSURFACE7 lpddsback = NULL;	//后备显示表面
DDSURFACEDESC2 ddsd;	//主显示表面的描述

int SCREEN_WIDTH = 640;	//显示宽度
int SCREEN_HEIGHT = 480;	//显示高度
int SCREEN_BPP = 32;	//色深,现在的机子只能设置为32位,书上可能还是8位的

int CharPosX = 200;	//当前显示人物的x坐标
int CharPosY = 200;	//当前任务显示的y坐标

// 弹出消息
void popMessage(LPWSTR str)
{
	MessageBox(main_window_handle, str, TEXT("提示"), MB_OK);
}

// 32位像素上色
void Plot_Pixel_Fast32_2(int x, int y, int red, int green, int blue, int alpha, UINT* video_buffer, int lpitch)
{
	video_buffer[x + y * (lpitch >> 2)] = (UINT)(_RGB32BIT(alpha, red, green, blue));	//使用宏直接写,有点区别的是lpitch需要除以4,因为lpitch算的是横向的字节数,而我们把主界面的内存弄成UINT型,是32位、4个字节的,上一节中是我理解的不够深刻
}


// 游戏初始化
int Game_Init(void* params = NULL)
{
	// 基础设置
	if (FAILED(DirectDrawCreateEx(NULL, (void**)&lpdd, IID_IDirectDraw7, NULL)))	//获取d7对象
		return 0;
	if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,
		DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT
		)))	//跟windows协作等级设置为全屏,这是最常用的参数
		return 0;

	if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))	//设置显示模式,如果设置为8位会直接出错
		return 0;

	// 开始创建显示主界面
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;	//表明ddsCaps是个有效成员,并且拥有后备的缓冲
	ddsd.dwBackBufferCount = 2;	//表明有一个缓冲
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | //表明该界面是主界面
							DDSCAPS_COMPLEX | //表明拥有缓冲链
							DDSCAPS_FLIP;	//表明是反正结构的一部分,上面的参数相当于是有缓冲,而这个参数表明可以切换缓冲

	if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))	//根据界面描述创建主界面
	{
		popMessage(TEXT("主表面创建出错"));
		return 0;
	}

	// 开始创建后备界面
	ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;	//表明该界面是后备界面
	if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))	//通过主界面创建出备用表面
	{
		popMessage(TEXT("创建备用表面出错了"));
		return 0;
	}

	return 1;
}

// 游戏结束
int Game_Shutdown(void* params = NULL)
{
	 释放初始化时创建的对象

	if (NULL != lpddsprimary)
	{
		lpddsprimary->Release();
		lpddsprimary = NULL;
	}

	if (NULL != lpdd)	//d7对象不为空的情况下释放
	{
		lpdd->Release();
		lpdd = NULL;
	}

	return 1;
}

// 游戏主循环
int Game_Main(void* params = NULL)
{
	// 判断是否要退出
	if (KEYDOWN(VK_ESCAPE))
		PostMessage(main_window_handle, WM_CLOSE, 0, 0);

	// 初始化主界面描述
	DDRAW_INIT_STRUCT(ddsd);

	if (FAILED(lpddsback->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL)))	//有备用表面时用备用表面加锁
	{
		popMessage(TEXT("LOCK 出错了"));
	}

	// 白色的背景
	UINT *video_buffer = (UINT*)ddsd.lpSurface;
	for (int x = 0; x < 640; ++x)
		for (int y = 0; y < 480; ++y)
			Plot_Pixel_Fast32_2(x, y, 255, 255, 255, 128, video_buffer, ddsd.lPitch);

	//画人物
	//UCHAR *video_buffer = (UCHAR*)ddsd.lpSurface;
	for (int x = 0+CharPosX; x < 64+CharPosX; ++x)
		for (int y = 0 + CharPosY; y < 64 + CharPosY; ++y)
		{
			if (x<0 || x>SCREEN_WIDTH - 1 || y<0 || y>SCREEN_HEIGHT-1)	//超出屏幕边缘的时候不画
				continue;
			Plot_Pixel_Fast32_2(x, y, 0, 255, 0, 128, video_buffer, ddsd.lPitch);
		}

	if (FAILED(lpddsback->Unlock(NULL)))	//解锁
	{
		popMessage(TEXT("UNLOCK 出错了"));
	}

	while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));	//切换界面,这边的while不是很懂,应该每次只会调用一次

	return 1;
}

// 消息处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,
	UINT msg,
	WPARAM wParam,
	LPARAM IParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		DefWindowProc(hwnd, msg, wParam, IParam);	//自动处理其他的消息
		break;
	}
	return (1);
}

// 主函数,程序入口
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	// 创建窗口类
	WNDCLASSEX wndclass;
	wndclass.cbSize = sizeof(WNDCLASSEX);
	wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;	//窗口的样式:改变宽度刷新、改变高度刷新、分配设备描述表、双击信息
	wndclass.lpfnWndProc = WindowProc;	//回调函数
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	//任务栏上的图标
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);	//光标的读取
	wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);	//窗口背景
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = TEXT("MyManyTimesWindow");	//窗口的名字
	wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);	//应用上的图标
	if (!RegisterClassEx(&wndclass))
		return 0;

	// 创建窗口,上面的窗口类是一个模版,可以根据上面的模版创建多个窗口,但请注意第二个参数
	HWND hwnd = CreateWindowEx(NULL,//WS_EX_TOPMOST,	//窗口特性,注释里设置为永远在最上方显示
		TEXT("MyManyTimesWindow"),	//窗口名称,一定要和窗口类的lpszClassName对应
		TEXT("我与DDraw已经很多次了"),	//标题
		WS_POPUP | WS_VISIBLE,	//无边框样式配合下面的尺寸实现全屏显示
		0, 0,	//左上角坐标
		SCREEN_WIDTH, SCREEN_HEIGHT,
		NULL,	//父窗口句柄,如果是桌面则为NULL
		NULL,	//菜单窗口句柄
		hInstance,	//应用程序实例
		NULL	//高级特性
		);
	if (!hwnd)	//创建失败返回
		return 0;

	main_window_handle = hwnd;

	ShowWindow(hwnd, nCmdShow);	//显示窗口
	UpdateWindow(hwnd);	//刷新窗口

	MSG msg;	//消息缓存

	srand(GetTickCount());	//随机一个种子

	if (0 == Game_Init())	//游戏初始化
		return 0;

	// 进入主循环
	while (true)
	{
		DWORD start_time = GetTickCount();	//获取当前时间

		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))	//有消息事件,注意最后一个参数,如果设置为PM_NOREMOVE的话不会销毁消息队列中的消息
		{
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);	//转译消息
			DispatchMessage(&msg);	//将消息发送给WindowProc函数处理

		}
		else	//没有消息
		{
			//游戏主循环
			Game_Main();

			// 延时代码,锁定30帧
			while ((GetTickCount() - start_time) < 33);

		}
	}

	Game_Shutdown();	//游戏结束

	return msg.wParam;
}


注意导入库文件。嘛,都是以前的知识,复制粘贴过来就行了,效果:


显示了一个绿色的方型,这就是我们要操控的勇士了。来吧,接下来要达到的效果就是使用wasd,控制左右移动,首先我们加上速度的全局变量(放在角色位置变量的下放):

int CharSpdX = 0;	//当前显示人物x方向的速度
int CharSpdY = 0;	//当前显示人物y方向的速度

然后导入文件input.lib和input8.lib,并包含dinput.h头文件。

 

在文件的全局处加上宏和变量:

#define DIKEYDOWN(data, n) (data[n] & 0x80)
HINSTANCE h_instance = NULL;	//当前应用程序的句柄,玩家自己在main函数中设置一下
LPDIRECTINPUT8 lpdi;	//输入对象
LPDIRECTINPUTDEVICE8W lpdikey = NULL;	//键盘设备
UCHAR keyboard_state[256];	//键盘当前的状态

初始化函数中添加获取输入对象和输入设备等的代码,错误处理去掉了,玩家自己添加一下:

// 开始创建输入对象
FAILED(DirectInput8Create(h_instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&lpdi, NULL));
FAILED(lpdi->CreateDevice(GUID_SysKeyboard, &lpdikey, NULL));	//创建键盘设备FAILED(lpdikey->SetCooperativeLevel(main_window_handle, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE));	//设置协作等级,键盘和鼠标设置为这里的可以后台接受和非独占,而游戏手柄则要设置为独占
FAILED(lpdikey->SetDataFormat(&c_dfDIKeyboard)));	//设置键盘的数据格式FAILED(lpdikey->Acquire());	//获取键盘

然后在游戏Shutdown销毁各个对象:

if (lpdikey)	//释放键盘相关对象
	lpdikey->Unacquire();
if (lpdikey)
	lpdikey->Release();
if (lpdi)
	lpdi->Release();

最后是游戏主循环,哈哈,激动人心的时候到了:

// 获取键盘状态
if (lpdikey->GetDeviceState(sizeof(UCHAR[256]), (LPVOID)keyboard_state))
{
	popMessage(TEXT("获取键盘状态出错了"));
}

// 处理按键
if (DIKEYDOWN(keyboard_state, DIK_W))
	CharSpdY = -3;
else if (DIKEYDOWN(keyboard_state, DIK_S))
	CharSpdY = 3;
else
	CharSpdY = 0;

if (DIKEYDOWN(keyboard_state, DIK_D))
	CharSpdX = 3;
else if (DIKEYDOWN(keyboard_state, DIK_A))
	CharSpdX = -3;
else
	CharSpdX = 0;

// 调整人物的位置
CharPosX += CharSpdX;
CharPosY += CharSpdY;

这段代码放在刷新白色背景的上面,然后可以试试效果了。我们的勇者是不是可以上下左右移动了?嗯,太棒了!

 

下面是鼠标信息获取的方法。

 

嗯,首先要说明一下,DirectX中的鼠标跟Windows里的鼠标其实没有什么关系,Windows鼠标就是你白色的指针,它就是在屏幕中的某个位置,而dx中鼠标设备的意思是真实设备操控时所产生的信息。不是很理解的话,我会在程序中说到这个问题。

 

上代码(初始化和释放就不说了,跟键盘的方法差不多,换成mouse相关的就OK了):

//全局变量
LPDIRECTINPUTDEVICE8W lpdimouse = NULL;	//鼠标设备
DIMOUSESTATE2 mouse_state;	//鼠标的状态
int MousePosX = 0;	//dx计算出来的鼠标位置
int MousePosY = 0;

// 这里是游戏主循环里的内容,请放在获取键盘状态的下面
// 处理鼠标
if (FAILED(lpdimouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mouse_state)))
{
	popMessage(TEXT("获取鼠标状态出错了"));
}
bool isMouseProccess = false;
MousePosX += mouse_state.lX;	//计算当前鼠标的位置,获得的参数是当前鼠标位置与上一帧位置的差值
MousePosY += mouse_state.lY;
SetCursorPos(MousePosX, MousePosY);	//设置Windows中鼠标的位置,如果不设置的话,可能会出现计算出来的位置与当前显示位置不匹配的情况,一定要记得Windows鼠标的位置和dx中鼠标的位置是隔离的	
if (DIKEYDOWN(mouse_state.rgbButtons, 0))	//当鼠标按下的时候,人物瞬移到对应位置
{
	isMouseProccess = true;
	CharPosX = MousePosX - 32;
	CharPosY = MousePosY - 32;
}

好了,现在按下鼠标,角色就跟这鼠标移动了,效果是不是很棒啊,哈哈。

 

至于手柄,现在手上也没有手柄,所以暂时就算了,这类其他的设备也就是比鼠标键盘麻烦了点,思路还是一样的。

 

下一节会讲声音相关的内容,而讲完声音,dx的内容貌似就是已经完了,如果有好玩的话写一点后面章节的知识,一般般的话就算了,下一节就是最后一节了。



  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目 录 游戏编程指南... 1 目 录... 1 导 读... 1 第一章 表述游戏的语言... 1 1.1 VC.net概述... 1 1.2 入门知识... 4 1.2.1 数与数据类型... 4 1.2.2 变量与常量... 4 1.2.3 Namespace. 5 1.2.4 操作符与表达式... 6 1.3 预编译指令... 7 1.4 结构,联合和枚举... 8 1.4.1 结构... 8 1.4.2 联合... 9 1.4.3 枚举... 10 1.5 控制语句... 10 1.5.1 判断和跳转语句... 10 1.5.2 选择语句... 11 1.5.3 循环语句... 13 1.6 函数... 13 1.7 指针、数组与字符串... 17 1.7.1 指针... 17 1.7.2 数组... 19 1.7.3 字符串... 22 1.7.4 小结... 23 1.8 多文件程序的结构... 23 1.9 常用函数... 25 第二章 如何说得更地道... 29 2.1 定义和使用类... 29 2.2 类的构造函数... 32 2.3 类的静态成员... 34 2.4 运算符重载... 35 2.5 类的继承... 38 2.6 虚函数和抽象类... 41 2.7 模板... 42 2.8 优化程序... 45 2.9 调试程序... 47 第三章 容纳游戏的空间... 49 3.1 基本Windows程序... 49 3.2 WinMain函数... 53 3.2.1 简介... 53 3.2.2 注册窗口类... 53 3.2.3 创建窗口... 55 3.2.4 显示和更新窗口... 56 3.2.5 消息循环... 57 3.3 消息处理函数... 58 3.4 常用Windows函数... 59 3.4.1 显示对话框... 59 3.4.2 定时器... 59 3.4.3 得到时间... 60 3.4.4 播放声音... 60 第四章 描绘游戏的画笔... 61 4.1 初始化DirectDraw.. 61 4.1.1 简介... 61 4.1.2 DirectDraw对象... 62 4.1.3 设置控制级和显示模式... 63 4.1.4 创建页面... 64 4.2 后台缓存和换页... 66 4.3 调入图像... 67 4.4 页面的丢失与恢复... 67 4.5 透明色... 68 4.6 图像传送... 68 4.7 程序实例... 72 4.8 图像缩放... 72 4.9 释放DirectDraw对象... 72 第五章 丰富画面的技巧... 74 5.1 填涂颜色... 74 5.2 输出文字... 75 5.3 GDI作图... 75 5.4 程序实例... 76 5.5 锁定页面... 76 5.6 程序提速... 78 5.7 特殊效果... 82 5.7.1 减暗和加亮... 82 5.7.2 淡入淡出... 83 5.7.3 半透明... 83 5.7.4 光照... 84 5.7.5 动态光照... 85 5.7.6 光照系统... 88 5.7.7 天气效果... 88 第六章 加速游戏的魔法... 89 6.1 内嵌汇编简介... 89 6.2 基本指令... 90 6.3 算术指令... 91 6.4 逻辑与移位指令... 93 6.5 比较、测试、转移与循环指令... 93 6.6 MMX指令集之基本指令... 96 6.7 MMX指令集之算术与比较指令... 98 6.8 MMX指令集之逻辑与移位指令... 99 6.9 MMX指令集之格式调整指令... 100 第七章 我没有想好名字... 102 7.1 读取键盘数据... 102 7.2 读取鼠标数据... 103 7.3 恢复和关闭DirectInput 104 7.3.1 恢复DirectInput设备... 104 7.3.2 关闭DirectInput 104 7.4 初始化和关闭DirectX Audio. 104 7.4.1 初始化DirectX Audio. 104 7.4.2 关闭DirectX Audio. 105 7.5 播放MIDI和WAV音乐... 105 7.5.1 调入MIDI和WAV文件... 105 7.5.2 播放MIDI和WAV文件... 106 7.5.3 停止播放... 107 7.6 在3D空间中播放音乐... 107 7.7 播放MP3音乐... 109 7.7.1 调入MP3文件... 109 7.7.2 播放MP3文件... 109 7.7.3 停止播放和释放对象... 110 第八章 支撑游戏的基石... 111 8.1 链表... 111 8.2 哈希表... 111 8.3 快速排序... 112 8.4 深度优先搜索... 113 8.5 广度优先搜索... 117 8.6 启发式搜索... 120 8.7 动态规划... 126 8.8 神经网络... 128 8.9 遗传规划... 129 第九章 向三维世界迈进... 131 9.1 概述... 131 9.2 基本知识... 133 9.2.1 初始化DXGraphics. 133 9.2.2 关闭DXGraphics. 135 9.2.3 恢复DXGraphics设备... 135 9.3 设置场景... 135 9.3.1 设置渲染状态... 135 9.3.2 设置矩阵... 136 9.4 创建场景... 137 9.4.1 调入3D场景... 138 9.4.2 调入2D图像... 139 9.5 刷新场景... 140 9.6 渲染场景... 141 9.6.1 渲染3D场景... 141 9.6.2 渲染2D图像... 141 9.7 改变场景... 141 9.8 显示文字... 142 9.9 程序实例... 143 第十章 我没有想好名字... 144 10.1 灯光... 144 10.2 半透明... 145 10.3 纹理混合... 146 10.4 雾... 148 10.5 凹凸贴图与环境贴图... 149 10.6 粒子系统... 149 10.7 骨骼动画... 149 10.8 镜子... 151 10.9 影子... 151 第十一章 我没有想好名字... 152 11.1 基本概念... 152 11.2 程序流程... 152 11.2.1 服务器端... 152 11.2.2 客户端... 153 11.3 程序实例... 153 11.4 错误处理... 158 11.5 显示IP地址... 158 11.6 更有效地传送数据... 159 第十二章 创造我们的世界... 161 12.1 程序流程... 161 12.2 程序结构... 162 12.3 基本方法... 163 12.4 SLG编程要点... 163 12.4.1 电脑AI 163 12.5 RPG & ARPG编程要点... 163 12.5.1 迷宫的生成... 163 12.5.2 脚本技术... 163 12.6 RTS编程要点... 163 12.6.1 寻路... 163 12.6.2 电脑AI 163 12.7 FPS编程要点... 164 12.7.1 移动... 164 12.7.2 碰撞检测... 164 12.8 游戏中的物理学... 165 附 录... 166 附录一 Windows常见消息列表... 166 附录二 虚拟键列表... 171 Windows消息中的虚拟键... 171 DirectInput中的虚拟键... 172 附录三 DirectX函数返回值列表... 174 DirectDraw部分... 174 Direct3D部分... 181 附录四 Winsock函数返回值列表... 183 附录五 游戏编程常用网址... 187 附录六 中英文名词对照... 188 附录七 常见问题及解决办法... 189 1. 程序编译时出现"Warning". 189 2. "Cannot Execute Program". 189 3. "Unresolved External Symbol". 189 4. 运行时出错... 189 5. 大家还有什么问题,可以告诉我... 189
游戏编程指南 1 目 录 1 导 读 1 第一章 表述游戏的语言 1 1.1 VC.net概述 1 1.2 入门知识 4 1.2.1 数与数据类型 4 1.2.2 变量与常量 4 1.2.3 Namespace 5 1.2.4 操作符与表达式 6 1.3 预编译指令 7 1.4 结构,联合和枚举 8 1.4.1 结构 8 1.4.2 联合 9 1.4.3 枚举 10 1.5 控制语句 10 1.5.1 判断和跳转语句 10 1.5.2 选择语句 11 1.5.3 循环语句 13 1.6 函数 13 1.7 指针、数组与字符串 17 1.7.1 指针 17 1.7.2 数组 19 1.7.3 字符串 21 1.7.4 小结 22 1.8 多文件程序的结构 22 1.9 常用函数 24 第二章 如何说得更地道 28 2.1 定义和使用类 28 2.2 类的构造函数 31 2.3 类的静态成员 32 2.4 运算符重载 33 2.5 类的继承 36 2.6 虚函数和抽象类 39 2.7 模板 40 2.8 优化程序 43 2.9 调试程序 44 第三章 容纳游戏的空间 46 3.1 基本Windows程序 46 3.2 WinMain函数 50 3.2.1 简介 50 3.2.2 注册窗口类 50 3.2.3 创建窗口 52 3.2.4 显示和更新窗口 53 3.2.5 消息循环 54 3.3 消息处理函数 55 3.4 常用Windows函数 56 3.4.1 显示对话框 56 3.4.2 定时器 56 3.4.3 得到时间 57 3.4.4 播放声音 57 第四章 描绘游戏的画笔 58 4.1 初始化DirectDraw 58 4.1.1 简介 58 4.1.2 DirectDraw对象 59 4.1.3 设置控制级和显示模式 60 4.1.4 创建页面 61 4.2 后台缓存和换页 63 4.3 调入图像 64 4.4 页面的丢失与恢复 64 4.5 透明色 65 4.6 图像传送 65 4.7 程序实例 69 4.8 图像缩放 69 4.9 释放DirectDraw对象 69 第五章 丰富画面的技巧 71 5.1 填涂颜色 71 5.2 输出文字 72 5.3 GDI作图 72 5.4 程序实例 73 5.5 锁定页面 73 5.6 程序提速 75 5.7 特殊效果 79 5.7.1 减暗和加亮 79 5.7.2 淡入淡出 80 5.7.3 半透明 80 5.7.4 光照 81 5.7.5 动态光照 82 第六章 加速游戏的魔法 86 6.1 内嵌汇编简介 86 6.2 基本指令 87 6.3 算术指令 88 6.4 逻辑与移位指令 90 6.5 比较、测试、转移与循环指令 90 6.6 MMX指令集之基本指令 93 6.7 MMX指令集之算术与比较指令 95 6.8 MMX指令集之逻辑与移位指令 96 6.9 MMX指令集之格式调整指令 97 第七章 我没有想好名字 99 7.1 读取键盘数据 99 7.2 读取鼠标数据 100 7.3 恢复和关闭DirectInput 101 7.3.1 恢复DirectInput设备 101 7.3.2 关闭DirectInput 101 7.4 初始化和关闭DirectX Audio 101 7.4.1 初始化DirectX Audio 101 7.4.2 关闭DirectX Audio 102 7.5 播放MIDI和WAV音乐 102 7.5.1 调入MIDI和WAV文件 102 7.5.2 播放MIDI和WAV文件 103 7.5.3 停止播放 104 7.6 在3D空间中播放音乐 104 7.7 播放MP3音乐 106 7.7.1 调入MP3文件 106 7.7.2 播放MP3文件 106 7.7.3 停止播放和释放对象 107 第八章 支撑游戏的基石 108 8.1 链表 108 8.2 哈希表 108 8.3 快速排序 109 8.4 深度优先搜索 110 8.5 广度优先搜索 114 8.6 启发式搜索 117 8.7 动态规划 123 8.8 神经网络 125 8.9 遗传规划 126 第九章 向三维世界迈进 128 9.1 概述 128 9.2 基本知识 130 9.2.1 初始化DXGraphics 130 9.2.2 关闭DXGraphics 132 9.2.3 恢复DXGraphics设备 132 9.3 设置场景 132 9.3.1 设置渲染状态 132 9.3.2 设置矩阵 133 9.4 创建场景 134 9.4.1 调入3D场景 135 9.4.2 调入2D图像 136 9.5 刷新场景 137 9.6 渲染场景 138 9.6.1 渲染3D场景 138 9.6.2 渲染2D图像 138 9.7 改变场景 138 9.8 显示文字 139 9.9 程序实例 140 第十章 我没有想好名字 141 10.1 灯光 141 10.2 半透明 142 10.3 纹理混合 143 10.4 雾 145 10.5 凹凸贴图与环境贴图 146 10.6 粒子系统 146 10.7 骨骼动画 146 10.8 镜子 146 10.9 影子 146 第十一章 我没有想好名字 148 11.1 基本概念 148 11.2 程序流程 148 11.2.1 服务器端 148 11.2.2 客户端 149 11.3 程序实例 149 11.4 错误处理 154 11.5 显示IP地址 154 11.6 Multicast技术 155 11.7 更有效地传送数据 156 第十二章 创造我们的世界 157 12.1 程序流程 157 12.2 程序结构 158 12.3 基本方法 159 12.4 SLG编程要点 159 12.4.1 电脑AI 159 12.5 RPG & ARPG编程要点 159 12.5.1 迷宫的生成 159 12.5.2 脚本技术 159 12.6 RTS编程要点 159 12.6.1 寻路 159 12.6.2 电脑AI 159 12.7 FPS编程要点 160 12.7.1 移动 160 12.7.2 碰撞检测 160 附 录 162 附录一 Windows常见消息列表 162 附录二 虚拟键列表 167 Windows消息中的虚拟键 167 DirectInput中的虚拟键 168 附录三 DirectX函数返回值列表 170 DirectDraw部分 170 Direct3D部分 177 附录四 Winsock函数返回值列表 179 附录五 游戏编程常用网址 183 附录六 中英文名词对照 184 附录七 常见问题及解决办法 185 1. 程序编译时出现"Warning" 185 2. "Cannot Execute Program" 185 3. "Unresolved External Symbol" 185 4. 运行时出错 185
上传限制,共分四卷压缩。请务必下载完所有压缩包。 目录 第一篇 软件设计基础篇 第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:使用MFC实现模态对话框 9 2.1.2 实例:使用Win32 API实现模态对话框 10 2.2 非模态对话框 12 2.2.1 实例:使用MFC实现非模态对话框 12 2.2.2 实例:使用Win32 API实现非模态对话框 13 2.3 属性对话框 14 2.3.1 实例:多页面切换程序 14 2.3.2 实例:向导对话框 16 2.4 对话框设计技巧 17 2.4.1 控件对齐与排列 17 2.4.2 设置控件逻辑顺序 18 2.5 通用对话框 19 2.5.1 实例:通用“打开”和“另存为”对话框 19 2.5.2 实例:通用“字体”对话框 22 2.5.3 实例:通用“颜色”对话框 23 第3章 基本控件 26 3.1 按钮控件 26 3.1.1 按钮CButton类 26 3.1.2 实例:按钮控件的使用方法 28 3.2 编辑框 30 3.2.1 编辑框CEdit类 30 3.2.2 实例:编辑框的使用方法 32 3.3 列表框 33 3.3.1 列表框CListBox类 33 3.3.2 实例:列表框的使用方法 35 3.4 组合框 36 3.4.1 组合框CComboxBox类 37 3.4.2 实例:组合框的使用方法 39 3.5 进度条 41 3.5.1 进度条CProgressCtrl类 41 3.5.2 实例:进度条的使用方法 42 3.6 列表控件 44 3.6.1 列表控件CListCtrl类 44 3.6.2 实例:列表控件的使用方法 45 第4章 文档与视图 47 4.1 文档—视图结构 47 4.1.1 单文档与多文档 47 4.1.2 文档与视图体系 48 4.2 实例:单文档应用程序与文档串行化 52 第5章 GDI绘图技术 57 5.1 图形设备接口GDI 57 5.1.1 设备上下文 57 5.1.2 GDI对象 58 5.1.3 GDI绘图 58 5.2 画笔 58 5.2.1 画笔CPen类 58 5.2.2 实例:使用GDI对象CPen绘图示例 59 5.3 画刷 60 5.3.1 画刷CBrush类 60 5.3.2 实例:使用GDI对象CBrush绘图示例 61 5.4 位图 63 5.4.1 位图CBitmap 63 5.4.2 实例:使用GDI对象CBitmap示例 64 第6章 键盘鼠标消息 67 6.1 键盘消息 67 6.1.1 键盘消息的类型 67 6.1.2 实例:响应键盘消息示例 68 6.1.3 模拟键盘消息 70 6.1.4 实例:模拟键盘消息示例 71 6.2 鼠标消息 72 6.2.1 鼠标消息的类型 72 6.2.2 实例:处理鼠标消息 73 6.2.3 实例:模拟鼠标消息 74 第二篇 软件设计综合应用篇 第7章 网络通信基础 80 7.1 网络模型 80 7.1.1 OSI参考模型 80 7.1.2 TCP/IP参考模型 81 7.2 基础协议 82 7.2.1 IP协议 82 7.2.2 TCP协议 83 7.2.3 UDP协议 84 7.2.4 ICMP协议 85 7.3 套接字编程 85 7.3.1 函数介绍 85 7.3.2 实例:Ping程序 88 7.3.3 实例:网络嗅探器 92 7.4 服务器与客户端模型 96 7.4.1 实例:TCP服务端和客户端程序 96 7.4.2 实例:UDP服务器和客户端程序 100 7.5 实例:使用分层服务提供者LSP截取网络数据包 103 7.5.1 服务提供者接口(SPI) 103 7.5.2 设计实例 103 7.5.3 枚举协议目录 106 7.5.4 LSP的安装与卸载 108 7.5.5 分层服务提供者(LSP) 113 第8章 密码学算法 118 8.1 数据加密标准(DES) 118 8.1.1 算法描述 118 8.1.2 初始置换与逆初始置换 119 8.1.3 生成子密钥 120 8.1.4 f函数的执行流程 121 8.1.5 解密过程 122 8.1.6 实例:DES算法加密解密演示 123 8.2 国际数据加密算法(IDEA) 131 8.2.1 算法描述 131 8.2.2 生成子密钥 133 8.2.3 实例:IDEA算法加密解密演示 134 8.3 Blowfish算法 139 8.3.1 算法描述 139 8.3.2 生成子密钥和S盒 141 8.3.3 实例:Blowfish算法加密解密演示 141 8.4 公钥加密算法(RSA) 146 8.4.1 算法描述 146 8.4.2 实例:RSA加密解密演示软件 147 第9章 多媒体技术 151 9.1 多媒体控件 151 9.1.1 实例:使用Animation控件播放AVI文件 151 9.1.2 实例:使用Windows Media Player控件播放多媒体文件 152 9.1.3 实例:使用Real Player控件播放多媒体文件 153 9.2 屏幕截图 154 9.2.1 位图 154 9.2.2 实例:屏幕截图 155 9.3 屏幕录像 157 9.3.1 实现原理 157 9.3.2 实例:屏幕录像 158 第10章 数据库技术 161 10.1 设置ODBC数据源 161 10.1.1 ODBC数据源 161 10.1.2 使用ODBC管理器设置Access数据源 162 10.2 MFC ODBC数据库编程 163 10.2.1 MFC ODBC概述 163 10.2.2 实例:使用MFC ODBC访问数据库 164 10.3 MFC DAO数据库编程 169 10.3.1 MFC DAO概述 169 10.3.2 实例:使用MFC DAO访问 数据库 169 第11章 综合实例开发 174 11.1 实例:Huffman编码软件 174 11.1.1 Huffman算法原理 174 11.1.2 具体实现 175 11.2 实例:八数码游戏 178 11.2.1 八数码游戏算法介绍 178 11.2.2 具体实现 179 11.3 实例:游戏寻路算法A* 183 11.3.1 A*算法原理 183 11.3.2 二叉堆在A*中的应用 184 11.3.3 具体实现 186 11.4 实例:“连连看”游戏辅助工具 190 11.4.1 “连连看”算法原理 190 11.4.2 具体实现 191 11.5 实例:“对对碰”游戏辅助工具 196 11.5.1 “对对碰”算法原理 196 11.5.2 具体实现 197 11.6 实例:拼音输入法 199 11.6.1 设计实例 200 11.6.2 拼音字典存储结构—Trie树 200 11.6.3 单字联想 205 11.7 实例:Windows二级文件系统 209 11.7.1 设计实例 209 11.7.2 具体实现 211 11.8 实例:手柄测试器 214 11.8.1 DirectInput手柄输入 214 11.8.2 设计实例 216 第三篇 Windows系统程序设计篇 第12章 进程与线程 222 12.1 进程 222 12.1.1 原理介绍 223 12.1.2 创建进程 223 12.1.3 实例:创建进程 226 12.2 线程 227 12.2.1 原理介绍 227 12.2.2 创建线程 229 12.2.3 实例:创建线程 229 12.3 枚举进程/线程信息 231 12.3.1 实例:使用PSAPI示例 231 12.3.2 实例:使用ToolHelpAPI示例 233 12.3.3 实例:使用Native API示例 235 第13章 内存管理 239 13.1 虚拟内存 239 13.1.1 进程虚拟地址空间 239 13.1.2 实例:查看虚拟内存状态 240 131.3 实例:演示虚拟内存的“保留—提交”特性 243 13.1.4 实例:游戏内存修改器 245 13.2 内存映射文件 249 13.2.1 内存映射文件的原理 249 13.2.2 实例:文件分割器 250 第14章 进程间通信 254 14.1 消息传递机制 254 14.1.1 消息传递 254 14.1.2 实例:使用WM_COPYDATA消息传递数据 254 14.2 共享内存 256 14.2.1 共享内存的原理 256 14.2.2 实例:使用共享内存示例 257 14.3 管道和邮槽 259 14.3.1 管道和邮槽通信原理 259 14.3.2 实例:使用匿名管道重定向程序输出 261 14.3.3 实例:命名管道示例 263 14.3.4 实例:邮槽通信示例 266 14.4 剪贴板 267 14.4.1 剪贴板通信机制 267 14.4.2 实例:使用剪贴板实现进程间通信示例 269 第15章 线程同步 275 15.1 原子访问 275 15.1.1 多线程访问共享数据问题 275 15.1.2 互锁系列函数 276 15.2 关键代码段 277 15.2.1 基本原理 277 15.2.2 实例:多线程环境下的数据共享 278 15.3 内核对象与等待函数 280 15.3.1 内核对象 280 15.3.2 等待函数 281 15.4 事件内核对象 283 15.4.1 基本原理 283 15.4.2 实例:使用事件内核对象示例 284 15.5 等待定时器内核对象 285 15.5.1 基本原理 285 15.5.2 实例:使用等待定时器的APC机制 287 15.6 信标内核对象 288 15.6.1 基本原理 288 15.6.2 实例:使用信标内核对象示例 289 15.7 互斥内核对象 291 15.7.1 基本原理 292 15.7.2 实例:使用互斥内核对象示例 292 第16章 动态链接库 295 16.1 DLL基础 295 16.1.1 DLL的隐式链接 295 16.1.2 DLL的显示加载 296 16.2 编写动态链接库 297 16.2.1 入口函数DllMain 297 16.2.2 实例:编写DLL实现导出变量、函数、类 298 16.3 线程本地存储器(TLS) 301 16.3.1 静态TLS和动态TLS 301 16.3.2 实例:使用静态TLS示例 303 16.3.3 实例:使用动态TLS示例 304 第17章 结构化异常处理 306 17.1 SEH的概念、特性 306 17.2 SEH的基本使用方法 307 17.2.1 结束异常程序 307 17.2.2 异常处理程序 310 17.2.3 顶层异常处理 313 17.3 VC++编译器级SEH的具体实现 313 17.3.1 SEH相关数据结构的介绍 314 17.3.2 异常处理链结构图 315 17.3.3 实例:单嵌套异常块演示程序 316 17.3.4 实例:多嵌套异常块演示程序 318 17.3.5 VC++编译器级异常帧结构 320 17.3.6 VC中的顶层异常处理 320 17.3.7 VC搜索异常处理程序流程 322 第18章 可执行文件格式 324 18.1 PE文件格式 324 18.1.1 PE文件头 324 18.1.2 可选文件头 325 18.1.3 区块表 327 18.1.4 输入表 328 18.1.5 输出表 329 18.1.6 资源表 330 18.1.7 重定位表 332 18.1.8 绑定输入表 332 18.2 综合应用 333 18.2.1 实例: PE文件资源查看器 333 18.2.2 实例: 为应用程序添加Nag窗口 337 第19章 模块注入与函数挂接技术 341 19.1 模块注入 341 19.1.1 添加导入表项 342 19.1.2 远程线程技术 344 19.1.3 实例:使用远程线程实现模块注入 345 19.1.4 异步过程调用(APC) 346 19.1.5 实例:使用APC实现模块注入 347 19.2 挂接API 349 19.2.1 重定向API 350 19.2.2 实例:重定向API MessageBoxA示例 350 19.2.3 古老的API HOOK 353 19.2.4 实例:HOOK API示例 354 19.2.5 Detours Hook 356 19.2.6 实例:使用detour库实现挂接API示例 357 19.3 钩子 359 19.3.1 钩子的基本原理 359 19.3.2 钩子类型 360 19.3.3 实例:全局鼠标钩子示例 366 19.3.4 实例:全局键盘钩子示例 369 19.3.5 实例:使用局部CBT钩子示例 370 19.3.6 实例:使用低级键盘钩子示例 371 19.4 反注入技术 372 19.4.1 实例:使用调试钩子屏蔽全局钩子 372 19.4.2 实例:检测注入模块 374 19.4.3 实例:使用DLL_THREAD_ATTACH阻止远程线程 377 19.4.4 实例:使用挂钩LoadLibraryExW屏蔽全局钩子 379 附录 光盘源码实例 381
上传限制,共分四卷压缩。请务必下载完所有压缩包。 目录 第一篇 软件设计基础篇 第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:使用MFC实现模态对话框 9 2.1.2 实例:使用Win32 API实现模态对话框 10 2.2 非模态对话框 12 2.2.1 实例:使用MFC实现非模态对话框 12 2.2.2 实例:使用Win32 API实现非模态对话框 13 2.3 属性对话框 14 2.3.1 实例:多页面切换程序 14 2.3.2 实例:向导对话框 16 2.4 对话框设计技巧 17 2.4.1 控件对齐与排列 17 2.4.2 设置控件逻辑顺序 18 2.5 通用对话框 19 2.5.1 实例:通用“打开”和“另存为”对话框 19 2.5.2 实例:通用“字体”对话框 22 2.5.3 实例:通用“颜色”对话框 23 第3章 基本控件 26 3.1 按钮控件 26 3.1.1 按钮CButton类 26 3.1.2 实例:按钮控件的使用方法 28 3.2 编辑框 30 3.2.1 编辑框CEdit类 30 3.2.2 实例:编辑框的使用方法 32 3.3 列表框 33 3.3.1 列表框CListBox类 33 3.3.2 实例:列表框的使用方法 35 3.4 组合框 36 3.4.1 组合框CComboxBox类 37 3.4.2 实例:组合框的使用方法 39 3.5 进度条 41 3.5.1 进度条CProgressCtrl类 41 3.5.2 实例:进度条的使用方法 42 3.6 列表控件 44 3.6.1 列表控件CListCtrl类 44 3.6.2 实例:列表控件的使用方法 45 第4章 文档与视图 47 4.1 文档—视图结构 47 4.1.1 单文档与多文档 47 4.1.2 文档与视图体系 48 4.2 实例:单文档应用程序与文档串行化 52 第5章 GDI绘图技术 57 5.1 图形设备接口GDI 57 5.1.1 设备上下文 57 5.1.2 GDI对象 58 5.1.3 GDI绘图 58 5.2 画笔 58 5.2.1 画笔CPen类 58 5.2.2 实例:使用GDI对象CPen绘图示例 59 5.3 画刷 60 5.3.1 画刷CBrush类 60 5.3.2 实例:使用GDI对象CBrush绘图示例 61 5.4 位图 63 5.4.1 位图CBitmap 63 5.4.2 实例:使用GDI对象CBitmap示例 64 第6章 键盘鼠标消息 67 6.1 键盘消息 67 6.1.1 键盘消息的类型 67 6.1.2 实例:响应键盘消息示例 68 6.1.3 模拟键盘消息 70 6.1.4 实例:模拟键盘消息示例 71 6.2 鼠标消息 72 6.2.1 鼠标消息的类型 72 6.2.2 实例:处理鼠标消息 73 6.2.3 实例:模拟鼠标消息 74 第二篇 软件设计综合应用篇 第7章 网络通信基础 80 7.1 网络模型 80 7.1.1 OSI参考模型 80 7.1.2 TCP/IP参考模型 81 7.2 基础协议 82 7.2.1 IP协议 82 7.2.2 TCP协议 83 7.2.3 UDP协议 84 7.2.4 ICMP协议 85 7.3 套接字编程 85 7.3.1 函数介绍 85 7.3.2 实例:Ping程序 88 7.3.3 实例:网络嗅探器 92 7.4 服务器与客户端模型 96 7.4.1 实例:TCP服务端和客户端程序 96 7.4.2 实例:UDP服务器和客户端程序 100 7.5 实例:使用分层服务提供者LSP截取网络数据包 103 7.5.1 服务提供者接口(SPI) 103 7.5.2 设计实例 103 7.5.3 枚举协议目录 106 7.5.4 LSP的安装与卸载 108 7.5.5 分层服务提供者(LSP) 113 第8章 密码学算法 118 8.1 数据加密标准(DES) 118 8.1.1 算法描述 118 8.1.2 初始置换与逆初始置换 119 8.1.3 生成子密钥 120 8.1.4 f函数的执行流程 121 8.1.5 解密过程 122 8.1.6 实例:DES算法加密解密演示 123 8.2 国际数据加密算法(IDEA) 131 8.2.1 算法描述 131 8.2.2 生成子密钥 133 8.2.3 实例:IDEA算法加密解密演示 134 8.3 Blowfish算法 139 8.3.1 算法描述 139 8.3.2 生成子密钥和S盒 141 8.3.3 实例:Blowfish算法加密解密演示 141 8.4 公钥加密算法(RSA) 146 8.4.1 算法描述 146 8.4.2 实例:RSA加密解密演示软件 147 第9章 多媒体技术 151 9.1 多媒体控件 151 9.1.1 实例:使用Animation控件播放AVI文件 151 9.1.2 实例:使用Windows Media Player控件播放多媒体文件 152 9.1.3 实例:使用Real Player控件播放多媒体文件 153 9.2 屏幕截图 154 9.2.1 位图 154 9.2.2 实例:屏幕截图 155 9.3 屏幕录像 157 9.3.1 实现原理 157 9.3.2 实例:屏幕录像 158 第10章 数据库技术 161 10.1 设置ODBC数据源 161 10.1.1 ODBC数据源 161 10.1.2 使用ODBC管理器设置Access数据源 162 10.2 MFC ODBC数据库编程 163 10.2.1 MFC ODBC概述 163 10.2.2 实例:使用MFC ODBC访问数据库 164 10.3 MFC DAO数据库编程 169 10.3.1 MFC DAO概述 169 10.3.2 实例:使用MFC DAO访问 数据库 169 第11章 综合实例开发 174 11.1 实例:Huffman编码软件 174 11.1.1 Huffman算法原理 174 11.1.2 具体实现 175 11.2 实例:八数码游戏 178 11.2.1 八数码游戏算法介绍 178 11.2.2 具体实现 179 11.3 实例:游戏寻路算法A* 183 11.3.1 A*算法原理 183 11.3.2 二叉堆在A*中的应用 184 11.3.3 具体实现 186 11.4 实例:“连连看”游戏辅助工具 190 11.4.1 “连连看”算法原理 190 11.4.2 具体实现 191 11.5 实例:“对对碰”游戏辅助工具 196 11.5.1 “对对碰”算法原理 196 11.5.2 具体实现 197 11.6 实例:拼音输入法 199 11.6.1 设计实例 200 11.6.2 拼音字典存储结构—Trie树 200 11.6.3 单字联想 205 11.7 实例:Windows二级文件系统 209 11.7.1 设计实例 209 11.7.2 具体实现 211 11.8 实例:手柄测试器 214 11.8.1 DirectInput手柄输入 214 11.8.2 设计实例 216 第三篇 Windows系统程序设计篇 第12章 进程与线程 222 12.1 进程 222 12.1.1 原理介绍 223 12.1.2 创建进程 223 12.1.3 实例:创建进程 226 12.2 线程 227 12.2.1 原理介绍 227 12.2.2 创建线程 229 12.2.3 实例:创建线程 229 12.3 枚举进程/线程信息 231 12.3.1 实例:使用PSAPI示例 231 12.3.2 实例:使用ToolHelpAPI示例 233 12.3.3 实例:使用Native API示例 235 第13章 内存管理 239 13.1 虚拟内存 239 13.1.1 进程虚拟地址空间 239 13.1.2 实例:查看虚拟内存状态 240 131.3 实例:演示虚拟内存的“保留—提交”特性 243 13.1.4 实例:游戏内存修改器 245 13.2 内存映射文件 249 13.2.1 内存映射文件的原理 249 13.2.2 实例:文件分割器 250 第14章 进程间通信 254 14.1 消息传递机制 254 14.1.1 消息传递 254 14.1.2 实例:使用WM_COPYDATA消息传递数据 254 14.2 共享内存 256 14.2.1 共享内存的原理 256 14.2.2 实例:使用共享内存示例 257 14.3 管道和邮槽 259 14.3.1 管道和邮槽通信原理 259 14.3.2 实例:使用匿名管道重定向程序输出 261 14.3.3 实例:命名管道示例 263 14.3.4 实例:邮槽通信示例 266 14.4 剪贴板 267 14.4.1 剪贴板通信机制 267 14.4.2 实例:使用剪贴板实现进程间通信示例 269 第15章 线程同步 275 15.1 原子访问 275 15.1.1 多线程访问共享数据问题 275 15.1.2 互锁系列函数 276 15.2 关键代码段 277 15.2.1 基本原理 277 15.2.2 实例:多线程环境下的数据共享 278 15.3 内核对象与等待函数 280 15.3.1 内核对象 280 15.3.2 等待函数 281 15.4 事件内核对象 283 15.4.1 基本原理 283 15.4.2 实例:使用事件内核对象示例 284 15.5 等待定时器内核对象 285 15.5.1 基本原理 285 15.5.2 实例:使用等待定时器的APC机制 287 15.6 信标内核对象 288 15.6.1 基本原理 288 15.6.2 实例:使用信标内核对象示例 289 15.7 互斥内核对象 291 15.7.1 基本原理 292 15.7.2 实例:使用互斥内核对象示例 292 第16章 动态链接库 295 16.1 DLL基础 295 16.1.1 DLL的隐式链接 295 16.1.2 DLL的显示加载 296 16.2 编写动态链接库 297 16.2.1 入口函数DllMain 297 16.2.2 实例:编写DLL实现导出变量、函数、类 298 16.3 线程本地存储器(TLS) 301 16.3.1 静态TLS和动态TLS 301 16.3.2 实例:使用静态TLS示例 303 16.3.3 实例:使用动态TLS示例 304 第17章 结构化异常处理 306 17.1 SEH的概念、特性 306 17.2 SEH的基本使用方法 307 17.2.1 结束异常程序 307 17.2.2 异常处理程序 310 17.2.3 顶层异常处理 313 17.3 VC++编译器级SEH的具体实现 313 17.3.1 SEH相关数据结构的介绍 314 17.3.2 异常处理链结构图 315 17.3.3 实例:单嵌套异常块演示程序 316 17.3.4 实例:多嵌套异常块演示程序 318 17.3.5 VC++编译器级异常帧结构 320 17.3.6 VC中的顶层异常处理 320 17.3.7 VC搜索异常处理程序流程 322 第18章 可执行文件格式 324 18.1 PE文件格式 324 18.1.1 PE文件头 324 18.1.2 可选文件头 325 18.1.3 区块表 327 18.1.4 输入表 328 18.1.5 输出表 329 18.1.6 资源表 330 18.1.7 重定位表 332 18.1.8 绑定输入表 332 18.2 综合应用 333 18.2.1 实例: PE文件资源查看器 333 18.2.2 实例: 为应用程序添加Nag窗口 337 第19章 模块注入与函数挂接技术 341 19.1 模块注入 341 19.1.1 添加导入表项 342 19.1.2 远程线程技术 344 19.1.3 实例:使用远程线程实现模块注入 345 19.1.4 异步过程调用(APC) 346 19.1.5 实例:使用APC实现模块注入 347 19.2 挂接API 349 19.2.1 重定向API 350 19.2.2 实例:重定向API MessageBoxA示例 350 19.2.3 古老的API HOOK 353 19.2.4 实例:HOOK API示例 354 19.2.5 Detours Hook 356 19.2.6 实例:使用detour库实现挂接API示例 357 19.3 钩子 359 19.3.1 钩子的基本原理 359 19.3.2 钩子类型 360 19.3.3 实例:全局鼠标钩子示例 366 19.3.4 实例:全局键盘钩子示例 369 19.3.5 实例:使用局部CBT钩子示例 370 19.3.6 实例:使用低级键盘钩子示例 371 19.4 反注入技术 372 19.4.1 实例:使用调试钩子屏蔽全局钩子 372 19.4.2 实例:检测注入模块 374 19.4.3 实例:使用DLL_THREAD_ATTACH阻止远程线程 377 19.4.4 实例:使用挂钩LoadLibraryExW屏蔽全局钩子 379 附录 光盘源码实例 381

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值