三、Windows键盘快捷键—键盘代码转换
现在我们将讨论底下这三行程序代码,在本书中,截至目前为止建立的所有Windows程序中都使用过它们。这些程序代码是标准的消息循环:
while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; }
下面把上头那段程序代码加以修改,以便使用加速键:
while (GetMessage (&msg, NULL, 0, 0)) { if (!TranslateAccelerator (hwnd, hAccel, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } }
TranslateAccelerator函数确认存放在msg消息结构中的消息是否为键盘消息。如果是,该函数将找寻句柄为hAccel的快捷键表。如果找到了一个符合的,则呼叫句柄为hwnd的窗口消息处理程序。如果快捷键ID与系统菜单的菜单项一致,则消息就是WM_SYSCOMMAND;否则,消息为WM_COMMAND。
当TranslateAccelerator传回时,如果消息已经被转换(并且已经被发送给窗口消息处理程序),那么传回值为非零;否则,传回值为0。如果TranslateAccelerator传回一个非零值,则不呼叫TranslateMessage和DispatchMessage,而是经过循环回到GetMessage呼叫中。
TranslateMessage中的参数hwnd看起来有点累赘,因为消息循环中的其它三个函数都没有要求这个参数。此外,消息结构本身(结构变量msg)有一个叫做hwnd的成员,它是窗口句柄。
该函数有些不同的原因在于:msg结构的字段由GetMessage呼叫填入。当GetMessage的第二个参数为NULL时,函数会找寻应用程序所有窗口的消息。当GetMessage传回时,msg结构的hwnd是将要获得消息之窗口的窗口句柄。然而,当TranslateAccelerator把键盘消息转换为WM_COMMAND或WM_SYSCOMMAND消息时,它使用函数的第一个参数指定的窗口句柄hwnd来代替窗口代号msg.hwnd。Windows就是这样把所有快捷键消息发送给同一窗口消息处理程序的,即使另一个应用窗口目前拥有输入焦点。当系统模态对话框或者消息框拥有输入焦点时,TranslateAccelerator不会转换键盘消息,因为这些窗口的消息是不经过程序的消息循环的。
在某些情况下,当您程序的另一个窗口(比如一个非系统模态对话框)拥有输入焦点时,您也许不想转换快捷键。您将在 下一章中看到如何处理这种情况。