热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

帮忙下面这个WH_CBT全局钩子为啥不行?

我写了个程序用了WH_CBT全局钩子,但是只能拦截到自己进程的消息,并且当鼠标指针移出我的窗口之外,钩子就失效了。帮忙看看哪里写错了,我实在是瞅不出来了。。。回调函数是放在dll里的Hook.c
我写了个程序用了WH_CBT全局钩子,但是只能拦截到自己进程的消息,并且当鼠标指针移出我的窗口之外,钩子就失效了。
帮忙看看哪里写错了,我实在是瞅不出来了。。。
回调函数是放在dll里的
Hook.cpp内容如下:

#include "Hook.h"

#pragma data_seg("MySeg")
HHOOK g_hCbtHook = NULL;
HWND g_hReceiveWnd = NULL;
#pragma data_seg()
#pragma  comment(linker,"/section:MySeg,RWS")

// 设置接受消息的窗口
void SetReceiveWnd(HWND hWnd)
{
    g_hReceiveWnd=hWnd;
}
// 窗口切换钩子回调
static LRESULT CALLBACK CbtHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    ::SendMessage(g_hReceiveWnd, WM_MY_MESSAGE, (WPARAM)nCode, lParam);
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
// 开关窗口切换钩子
bool HookCbt(bool bHook)
{
    if(bHook)
    {
        g_hCbtHook = ::SetWindowsHookEx(WH_CBT, CbtHookProc, GetModuleHandle(NULL), 0);
        return g_hCbtHook ? true : false;
    }
    else
    {
        g_hCbtHook ? UnhookWindowsHookEx(g_hCbtHook) : NULL;
        g_hCbtHook = NULL;
        return true;
    }
}

Hook.h内容如下:

#pragma once

#include "windows.h"

#define WM_MY_MESSAGE WM_USER + 1

// 设置接受消息的窗口
void SetReceiveWnd(HWND hWnd);
// 窗口切换钩子回调
static LRESULT CALLBACK CbtHookProc(int nCode, WPARAM wParam, LPARAM lParam);
// 开关窗口切换钩子
bool HookCbt(bool bHook);

Hook.def内容如下:

LIBRARY "Hook"

EXPORTS
SetReceiveWnd @2
HookCbt @3

17 个解决方案

#1


if(g_hReceiveWnd)
::SendMessage(g_hReceiveWnd, WM_MY_MESSAGE, (WPARAM)nCode, lParam);
else
MessageBox(NULL, "no recv window", "t", 0);
return CallNextHookEx( g_hCbtHook, nCode, wParam, lParam);

#2


引用 1 楼 oldn_cc_bird 的回复:
if(g_hReceiveWnd)
::SendMessage(g_hReceiveWnd, WM_MY_MESSAGE, (WPARAM)nCode, lParam);
else
MessageBox(NULL, "no recv window", "t", 0);
return CallNextHookEx(g_hCbtHook, nCode, wParam, lParam);

试了下还是不行。
MSDN上说这个参数在2003系统上是忽略的。
我刚才有测试了下。如果我鼠标指针不移出窗口而是用ALT+TABLE切换窗口时,是能收到消息的。
也就是说这个是个全局钩子,只不过在鼠标指针移出窗口的时候,钩子失效了。
但是,我用ALT+TABLE切换到任何一个其他程序都会导致那个程序崩溃.提示内存无法访问

#3


你要hook的是什么消息啊,wh_cbt真的适合你么?

#4


我想写个程序监视另外某个程序的窗口是否处于活动状态。

#5


那用cbt是没错,但是你鼠标移出程序窗口你想收到什么呢?只有当你去激活另一窗口时hook才会被触发啊

#6


CBT钩子拦截的消息包括你的鼠标在某个窗口上移动。
激活窗口只是我要拦截的那种。
问题是怎么就导致程序崩溃呢

#7


CBT钩子拦截的消息包括你的鼠标在某个窗口上移动。 
----------
你在哪查到这个的?

程序会崩溃的话得看你hook里怎么写的了.

#8


代码已经贴出来了。
CBTProc Function
The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command;  before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue. 

#9


同样只这段代码,换成WH_KEYBOARD_LL就可以正常运行
无奈了

#10


感觉上没处理好WM_MY_MESSAGE消息。这么多的消息。。会不会没处理好?

#11


引用 10 楼 ju897d 的回复:
感觉上没处理好WM_MY_MESSAGE消息。这么多的消息。。会不会没处理好?

刚才我把SendMessage那行注释掉也没用。
切换窗口时还是崩溃,而且现在发现好像只能做WH_KEYBOARD_LL WH_MOUSE_LL这两个钩子
刚才试了下WH_CALLWNDPROCRET也不行

#12


before removing a mouse or keyboard event from the system message queue;
-------------------
system message queue not thread's message queue.

#13


反正是我在窗口内移动鼠标时能拦截到消息的。
出了窗口就不行了。

#14


更恶心的是这个全局WH_CBT钩子
那怕回调过程里只有一句
CallNextHookEx
也照样会导致大量其他程序崩溃

#15


引用 8 楼 icedmilk 的回复:
代码已经贴出来了。
 CBTProc Function
 The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command;before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue.

红颜色那句话你理解成了”鼠标移出窗口“??
那是一个消息被从消息队列移出的意思,和移出窗口没有任何关系呀。

#16


引用 15 楼 keepdoingit 的回复:
引用 8 楼 icedmilk 的回复:
代码已经贴出来了。
CBTProc Function
The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command;before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue.

红颜色那句话你理解成了”鼠标移出窗口“??
那是一个消息被从消息队列移出的意思,和移出窗口没有任何关系呀。

帅哥,仔细看看帖子

问题在于这种全局钩子根本无法执行

钩子的回调dll被挂到了每个进程上

当一个进程的消息被拦截后,也就是说那个回调dll要在该进程上执行,然后就导致该进程崩溃

#17


I found the problem.

It's SetWindowsHookEx(WH_CBT, CbtHookProc, GetModuleHandle(NULL), 0);
The third parameter cause the problem.

If I save the handle of the dll in the function DllMain by a shared global variable, the problem is solved.

I also found that the Handle we get from the DllMain and GetModuleHandle is not the same.

推荐阅读
  • JNI技术实践小结转自http:sett ... [详细]
  • 使用RSACryptoServiceProvider进行公钥加密我已经在CodeProject上发表了一篇文章,解释了如何使用RSA提供程序进行加密和解密:RSA私钥加密虽然200 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 这篇文章将为大家详细讲解有关C#开发技巧有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。C#开发技 ... [详细]
  • linux filesystem_如何使用cgdb + qemu调试linux内核模块
    如何使用cgdbqemu调试linux内核模块前言Linux代码庞大而繁杂,光看代码会使人头晕目眩,如果能通过调试工具对其代码执行流程进行调试ÿ ... [详细]
  • 找出字符串中重复字符
    2019独角兽企业重金招聘Python工程师标准packagejavaBasic;importjava.util.HashMap;importjava.util.Map; ... [详细]
  • 元类print(type(abc))print(type(True))print(type(100))print(type([1,2,3]))print(type({na ... [详细]
  • 下面是一个用openssl实现获取https网页内容的demo,整个流程比较简单,主要封装的API如下staticinthttps_init(http ... [详细]
  • #include#include#includeusingnamespacecv;usingname ... [详细]
  • 在ROS系统中,参数读写一般通过xml或者yaml格式的文件,其中yaml用得比较多。这是一种可读性高,轻量级的标记语言,简单好用。对于yaml文件,ros中用的较早版本的yaml- ... [详细]
  • 本文分析HashMap的实现原理。数据结构(散列表)HashMap是一个散列表(也叫哈希表),用来存储键值对( ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
author-avatar
熊熊粉丝6888
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有