【蓝因子教育】一个 HOOK 的例子

2025-03-22ASPCMS社区 - fjmyhfvclm

️一、应用场景

封装一个 OCX 控件,该控件的作用是来播放一个视频文件,需要在一个进程中放置四个控件实例。 由于控件是提供给别人用的,因此需要考虑很多东西。

️二、考虑因素

️1、控件的父窗口 resize 时需要控件也随之 resize

子窗体不能知道父窗口的 resize 情况,因为父窗口不会主动把这一情况通知子窗口。 因此需要放一个钩子来主动得知父窗口的 resize 事件,然后告诉控件窗口做出适当的改变。

这里用了一个局部钩子,即线程钩子。 被放置钩子的线程是控件的父窗口所在的线程 (这也是考虑第 3 个因素的原因)

️2、这四个控件是否为同一个父窗口

在该场景中考虑到了多个控件在同一个父窗口的情况:这种情况下,当父窗口 resize 的时候,就需要通知每一个控件 (子窗口)。 又因为多个控件的父窗口可能不是同一个,因此钩子就要被放置到每一个父窗口所在的线程。

️3、执行四个控件 UI 相关代码的线程是否为同一个线程

由于控件的所在场景相对无法控制,因此控件的父窗口的代码有可能是在不同的线程中执行的 (虽然 99.999% 可能性是同一个线程),这就需要在每个不同的线程中放置一个钩子 (这基于一个前提,那就是 放置钩子的线程 == 执行钩子回调函数的线程)。

️综合 3 个因素,可以得出这样一个 对应关系

一个线程 Thread: 被放置钩子的线程 == 控件的父窗口所在的线程 (可能这样说不准确,但权且这样说) == 执行钩子回调函数的线程

一个 Hook: 每放置一个钩子就产生一个 HOOK, 对于同一个线程只放置一次,如果四个控件的父窗口不是同一个线程,那么就要放置多个。还因为要在代码中使用 CallNextHook 将当前线程对应的钩子作为参数传给该函数,因此要保存线程和钩子的对应关系。

一个父窗口句柄: 即相同父窗口的控件的父窗口

若干个子窗口 (控件):同一个父窗口有多个子窗口

全部评论