Winapi Windows键盘加速器和子窗口
我已经使用C和Windows API创建了一个Windows GUI程序,我希望该程序使用键盘加速器。我已经设置了一些加速器,它们工作正常,但当焦点转到程序主窗口的子窗口(如列表视图控件或状态栏控件)时,键盘加速器似乎被转换为子窗口而不是主窗口的WM_命令消息。因此,当焦点在子控件上时,我在主窗口的WndProc中对适当的WM_命令消息的处理被忽略Winapi Windows键盘加速器和子窗口,winapi,keyboard,wm-command,Winapi,Keyboard,Wm Command,我已经使用C和Windows API创建了一个Windows GUI程序,我希望该程序使用键盘加速器。我已经设置了一些加速器,它们工作正常,但当焦点转到程序主窗口的子窗口(如列表视图控件或状态栏控件)时,键盘加速器似乎被转换为子窗口而不是主窗口的WM_命令消息。因此,当焦点在子控件上时,我在主窗口的WndProc中对适当的WM_命令消息的处理被忽略 我该如何解决这个问题?我找到了答案。主窗口的子窗口必须子类化,以便可以截获键盘加速器生成的WM_命令消息并将其传递给父窗口 这涉及将控件的窗口过程更
我该如何解决这个问题?我找到了答案。主窗口的子窗口必须子类化,以便可以截获键盘加速器生成的WM_命令消息并将其传递给父窗口 这涉及将控件的窗口过程更改为其他过程。备用过程通过将消息发送到父窗口来处理应该截获的消息。指向原始窗口过程的指针也必须存储在某个位置,以便控件能够正常工作 可以使用GWLP_WNDPROC更改窗口过程 下面是一个简单的示例,说明如何通过在控件的用户数据值(GWLP_USERDATA)中存储指向原始窗口过程的指针来执行此操作: 更改窗口过程并将原始过程存储在GWLP_USERDATA中的代码:
SetWindowLongPtr( hWnd, GWLP_USERDATA, ( LONG_PTR )SetWindowLongPtr( hWnd, GWLP_WNDPROC, ( LONG_PTR )WndProc ) );
截取窗口程序:
static LRESULT CALLBACK WndProc( const HWND hWnd, const UINT message, const WPARAM wParam, const LPARAM lParam )
{
switch( message )
{
case WM_COMMAND:
SendMessage( GetParent( hWnd ), message, wParam, lParam );
return 0;
default:
//Assume that GWLP_USERDATA has been set to the original window procedure.
return CallWindowProc( ( WNDPROC )GetWindowLongPtr( hWnd, GWLP_USERDATA ), hWnd, message, wParam, lParam );
}
}
另一种方法是避免对子窗口使用TranslateAccelerator,示例代码:
if (mainWidget() && msg.hwnd == mainWidget()->hwnd()) {
if (TranslateAccelerator(msg.hwnd, hMainAccelTable, &msg)) {
continue;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
如果消息不是mainWidget的,我们不会使用mainWidget的加速器表为其翻译加速器