这是你的类 - 你知道你把它放在哪里。
如果您不共享它,则只需选择一个低于 0xBFFF 的 ID 即可。
如果您的类属于可以由多个应用程序共享的 DLL...或者可以简单地由您无法控制的代码共享,因此无法为...分类 ID,请使用 GlobalAddAtom()获取 ID(记得在 unregister the hotkey 之后拨打 GlobalDeleteAtom())。
说明
可能值得花一点时间思考为什么有两个不同的 ID 范围,以及为什么 API 文档建议使用 GlobalAddAtom() 来获取共享 DLL 的后一个范围内的 ID。让我们从RegisterHotKey()的参数的文档开始:
id
[在]指定热键的标识符。如果 hWnd 参数为 NULL,则热键与当前线程相关联,而不是与特定窗口相关联。如果已存在具有相同 hWnd 和 id 参数的热键,请参阅备注了解所采取的操作。
据此,我们可以推测热键由两个潜在的信息对之一唯一标识:线程或窗口句柄,以及任意 16 位数字。如果您指定一个窗口句柄 (HWND),那么the message 将发送到该窗口;否则,它被发送到线程。
所以...如果您只为给定窗口注册 一个 热键,则 ID 并不重要1;没有其他人可以为该窗口注册热键,其他窗口的热键事件将发布到这些窗口。同样,如果您只为给定线程注册一个无窗口热键,您将只会收到该热键的消息。 如果您控制了应用程序的所有代码,则可以为热键选择所需的任何 ID,使用您想要分配的任何技术;没有其他人会踩到它们,因为您拥有所有可以能够踩到它们的代码!
但是,如果您正在编写一个可以被其他代码调用的通用例程怎么办?你不能可靠地选择一个常量 ID,因为调用者可能已经在使用该 ID,如果他们也使用相同的窗口或线程,你最终会重新定义他们的热键。或者如果(如您的情况)您不知道在运行时之前将注册多少个热键?
您需要一种方法来确保您在运行时选择的 ID 不会被其他人使用。这就是 GlobalAddAtom() 发挥作用的地方:您传递一个字符串,然后它为您提供了一个保证与该字符串相对应的 ID,而不会与其他字符串相对应;这对于系统来说实际上是唯一的,除非其他人传递了相同的字符串——你可能会想出一个唯一的字符串;只需使用您的公司名称或社会安全号码,以及为您需要的每个新原子增加的前缀。或者,如果您真的很偏执,请使用 GUID。
真相背后的真相
除此之外,让我试着澄清一点困惑:Windows 实际上并不关心调用 RegisterHotKey() 的代码是否在 DLL 中。它不能。考虑以下例程:
void RegisterSuperHappyFunHotKey(HWND hWnd, int id,
unsigned int fsModifiers, unsigned int vk)
{
RegisterHotKey(hWnd, id, fsModifiers, vk);
}
此例程什么都不做,只是将其参数转发给 WinAPI 函数,这些函数都不能识别调用模块。如果它存在于 DLL 中,则其行为与编译到应用程序本身中的行为相同。 Windows 没有可靠的方法来判断调用的来源,并且热键本身与窗口和线程(或单独的线程)相关联,其中任何一个都可以由 DLL 中的代码控制。现在当然,您可以有自己的应用程序或库特定要求:如果您的 DLL 创建一个窗口并为其设置一个热键,那么您需要在销毁窗口时取消注册该热键。 .. 但这是您自己的问题,您可以按照自己的意愿处理。
MSDN 指定这两个 ID 范围有一个很好的理由:鼓励 DLL 作者避免踩踏应用程序作者使用的 ID。如果您是应用程序的作者,那么世界就是您的牡蛎 - 您(在很大程度上)控制在您的应用程序进程中加载和执行哪些代码,因此可以决定哪些代码您使用的 ID无论您认为合适:从 0 开始并为每个新热键递增是完全可以接受的。但是,一旦您冒险进入 ID 的上限范围,您将不得不像使用 DLL 一样使用GlobalAddAtom() - 否则您将面临与第三方代码以这种方式生成的 ID 冲突的风险动态链接库。这是...social contract 之类的。
总结:
“共享 DLL”位在这里是一个红鲱鱼;如果您知道应用程序注册的所有热键的 ID,则只需选择一个低于 0xBFFF 的数字并使用它。如果你不能,因为你的代码将被多个调用者使用(就像你的......),然后使用GlobalAddAtom() 获取一个 ID 并使用它。
推荐
出于这些原因,我建议您这样做在您正在设计的课程中使用GlobalAddAtom(),只是因为这听起来好像您现在不知道您是否'将把它构建到您自己设计的应用程序中(您可以控制正在使用的 ID)或由其他应用程序加载的 DLL(您不)。不用担心 - 只要您遵守为 DLL 调用者规定的规则,您假装 成为 DLL 并没有违反合同。
1好的,所以有几个系统定义的热键 ID 需要注意...