如何在子类控件中使用加速器表?

时间:2017-07-08 23:49:14

标签: c++ windows winapi keyboard-shortcuts

我是一个控件的子类,此时我想为它添加一些键盘快捷键。在资源的accelerator table中定义了大约十几个。

我知道我可以从主应用中使用这些加速器,方法是从主循环中调用TranslateAccelerator然后TranslateMessageDispatchMessage

但我可以检查WndProc内部的子类控件是否按下了加速键序列吗?

编辑:换句话说,做这样的事情会不会

LRESULT CSubclassedWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    // TODO: Add your specialized code here and/or call the base class

    if(message == WM_KEYDOWN ||
        message == WM_CHAR ||
        message == WM_SYSKEYDOWN ||
        message == WM_SYSCHAR)
    {
        if(hAccel)
        {
            CRect rcThis;
            this->GetWindowRect(&rcThis);
            this->ScreenToClient(&rcThis);
            POINT pnt = {(rcThis.right + rcThis.left) / 2, (rcThis.bottom + rcThis.top) / 2};

            MSG msg = {this->GetSafeHwnd(), message, wParam, lParam, ::GetTickCount(), pnt};
            if(::TranslateAccelerator(this->GetSafeHwnd(), hAccel, &msg))
            {
                //Accelerator was recognized and sent as WM_COMMAND message to the same window
                return 0;
            }
        }
    }

    switch(message)
    {
    case WM_COMMAND:
        {
            //Special accelerator commands
            if(HIWORD(wParam) == 1 &&
                lParam == 0)
            {
                //See which command was it
                switch(LOWORD(wParam))
                {
                case ID_MY_ACCELERATOR_ID1:
                    {
                        //Do work...
                    }
                    return 0;

                case ID_MY_ACCELERATOR_ID2:
                    {
                        //Do work...
                    }
                    return 0;
                }
            }
        }
        break;

    case WM_ERASEBKGND:
        //process it
        return TRUE;
    case WM_PAINT:
        //process it
        return TRUE;
    case WM_KEYDOWN:
        //process it
        break;

    //etc.
    }

    return CWnd::WindowProc(message, wParam, lParam);
}

1 个答案:

答案 0 :(得分:2)

我相信标准Windows控件只使用WM_KEYDOWN / CHAR和GetKeyState,但我不明白为什么你不能使用TranslateAccelerator

TranslateAccelerator在某些方面更好,因为它知道如何处理 Alt.Gr 但如果捕获了鼠标(IIRC)它也会忽略该键,因此它取决于您的需求

TranslateAccelerator之后调用顶级窗口上的GetMessage当然是最佳选择,因为它会检查窗口菜单以查看该命令是否已被禁用...