为什么 SetWindowsHookEx 采用 HINSTANCE 参数?

为什么 SetWindowsHookEx 采用 HINSTANCE 参数?

作者:BlogUpdater |  时间:2023-09-26 |  浏览:454 |  评论已关闭 条评论

有开发者问了这样一个问题:既然 SetWindowsHookEx 的第一个参数总是会被转换为一个文件名,那为什么它的传参类型是 HINSTANCE 呢?这岂不是多此一举?

原因是这样的:在 16 位 Windows 系统上,它不是这样工作的。16 位 Windows 上根本就没有 “钩子注入” 的概念。
所有 16 位 Windows 应用程序都是运行在同一个地址空间,所以就没有必要将代码注入到其他程序中。所以,就没有必要将实例句柄转换为一个文件名来注入代码。
实际的工作原理是这样的:实例句柄将会被用来增加引用计数,从而钩子函数就不会被意外释放掉。当钩子被卸载的时候,模块的引用计数会自动减一。

即使到了 32 位 Windows,窗口管理器需要实例句柄才能将函数指针转换回 RVA,以便在将模块加载到另一个进程时可以找到函数。

如果你传递了带有模块路径的 LPCWSTR,则窗口管理器无论如何都必须执行 GetModuleHandle 来恢复实例句柄。

由于大多数程序的实例句柄都随时可用,因此这是更自然的选择。(更不用说它将保持与 16 位 Windows 的源代码兼容性,这是试图让人们有兴趣将他们的代码移植到 Win32 时的一个重要标准。)

总结
做 Windows 世界的良好公民,不要随意使用钩子。
除非迫不得已。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Why does SetWindowsHookEx take an HINSTANCE parameter?》

最近我写了个东西

正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。

标签:

评论已关闭。