【UnhookWindowsHookEx()期间崩溃】

UnhookWindowsHookEx()崩溃

SetWindowLong(…)
来恢复旧的窗口程序程序粉碎。 DLL代码:

#include "pch.h"
#include "pidhwnd.h"
#include "windows.h"
#include "TLHelp32.h"

BOOL IsHook = FALSE;
WNDPROC oldProc = NULL;
HWND gameHwnd =0 ;
HHOOK hMsgHook = NULL;
int hotkey = 0;
int Ctrl = 0, vk3f = 0;//热键参数
WNDPROC g_OldWndProc = NULL;
//钩子回调函数
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
//替换的窗口过程
LRESULT CALLBACK HookWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//自动打怪
void zddga();
///< 枚举窗口参数
typedef struct
{
	HWND hwndWindow; // 窗口句柄
	DWORD dwProcessID; // 进程ID class
	const char* T_teit;      //窗口标题
	const char* T_class;      //进程类名
}EnumWindowsArg;
///< 枚举窗口回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
	EnumWindowsArg* pArg = (EnumWindowsArg*)lParam;
	DWORD dwProcessID = 0;
	// 通过窗口句柄取得进程ID
	::GetWindowThreadProcessId(hwnd, &dwProcessID);
	if (dwProcessID == pArg->dwProcessID)
	{		
		CHAR szBuf_class[MAX_PATH] = {0};
		CHAR wszTitle[MAX_PATH] = { 0 };

		 GetWindowTextA(hwnd, wszTitle, MAX_PATH);

		 GetClassName(
			 hwnd,					// 窗口句柄
			 szBuf_class,		// 接收窗口类名的缓冲区指针
			 MAX_PATH			// 缓冲区字节大小
		 );
		// MessageBox(NULL, szBuf_class, "提示!", 1);
		 if (strcmp(pArg->T_teit,"")==0)
		 {
			 if (memcmp(szBuf_class, pArg->T_class,strlen(pArg->T_class)) == 0)
			 {
				 pArg->hwndWindow = hwnd;
				 return FALSE;
			 }
		 }
		 if (strcmp(pArg->T_class, "") == 0)
		 {
			 if (memcmp(wszTitle, pArg->T_teit, strlen(pArg->T_teit)) == 0)
			 {
				 pArg->hwndWindow = hwnd;
				 return FALSE;
			 }
		 }
		 if (strcmp(pArg->T_class, "") != 0&& strcmp(pArg->T_teit, "") != 0)
		 {
			 if (memcmp(szBuf_class, pArg->T_class,strlen(pArg->T_class)) == 0 && memcmp(wszTitle, pArg->T_teit, strlen(pArg->T_teit)) == 0)
			 {
				 pArg->hwndWindow = hwnd;
				 return FALSE;
			 }
		 }
		// 找到了返回FALSE
		return TRUE;
	}
	// 没找到,继续找,返回TRUE
	return TRUE;
}
///< 通过进程ID获取窗口句柄
HWND GetWindowHwndByPID(DWORD dwProcessID ,const char* T_class,const char* T_teit)
{
	HWND hwndRet = NULL;
	EnumWindowsArg ewa;
	ewa.dwProcessID = dwProcessID;
	ewa.hwndWindow = NULL;
	ewa.T_class = T_class;
	ewa.T_teit = T_teit;
	EnumWindows(EnumWindowsProc, (LPARAM)&ewa);
	if (ewa.hwndWindow)
	{
		hwndRet = ewa.hwndWindow;
	}
	return hwndRet;
}

BOOL setKeyRj(HWND hwnd,int _hotkey,int ctrl_z,int Vkzf)
{
	//设置窗口线程的钩子函数 
	DWORD threadId, processId;
	gameHwnd = hwnd;
	hotkey = _hotkey;
	Ctrl = ctrl_z;
	vk3f = Vkzf;
	threadId = GetWindowThreadProcessId(gameHwnd, &processId);	
	//这里的 hMsgHook 回调函数中需要用到 设置为全局
	hMsgHook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, GetModuleHandle(NULL), threadId);
	return (BOOL)hMsgHook;//WH_CALLWNDPROC
}
BOOL Unhook()
{
	if (!hMsgHook)
	{
		return FALSE;
	}
	if (g_OldWndProc)
	{
		// recovering old wnd proc
		
		SetWindowLong(gameHwnd, GWL_WNDPROC, (LONG)g_OldWndProc);
		g_OldWndProc = NULL;
	}
IsHook = FALSE;
UnregisterHotKey(gameHwnd, hotkey);//注销热键
	BOOL ret= UnhookWindowsHookEx(hMsgHook);
	hMsgHook =NULL;
	return  ret;
}

//钩子回调函数
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	//由于窗口的 GetMessage PeekMessage 在不停的发生 所以回调函数在不停调用 这里设置全局变量 IsHook 验证一下 以免重复设置
	if (!IsHook)
	{
		IsHook = TRUE;
		//这里的 hotkey oldProc设置为全局变量 因为在后边的替换窗口过程需要用到
		//hotkey = GlobalAddAtom("test_F3");
		int result = RegisterHotKey(gameHwnd, hotkey, Ctrl, vk3f);
		g_OldWndProc=(WNDPROC)GetWindowLong(gameHwnd, GWL_WNDPROC);
		oldProc = (WNDPROC)SetWindowLong(gameHwnd, GWL_WNDPROC, (LONG)HookWndProc);
	}

	return CallNextHookEx(hMsgHook, nCode, wParam, lParam);
}

//替换的窗口过程
LRESULT CALLBACK HookWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	//热键处理 hotkey是自己定义的热键标识 这样一来自己定义的热键处理 其他消息 包括其他热键都默认处理
	if (uMsg == WM_HOTKEY && wParam == hotkey)
	{
		//执行 自定义热键的函数
		zddga();
	}
	else
	{
		CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam);
	}

	return 1;
}

int dg01 = 0;
void zddga()
{
if (dg01==0)
{
	MessageBox(NULL, "开始自动打怪!", "提示!", 1);
	dg01 = 1;
}
else
{
	MessageBox(NULL, "停止自动打怪!", "提示!", 1);
	dg01 = 0;
}
}

.h文件

#pragma once
///< 通过进程ID获取窗口句柄
HWND GetWindowHwndByPID(DWORD dwProcessID,const char* T_class, const char* T_teit);//T_class
//注册热键
BOOL setKeyRj(HWND hwnd, int _hotkey, int ctrl_z, int Vkzf);
//卸载热键
BOOL Unhook();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+V代码搬运工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值