如何将WM_KEYDOWN消息传递给CWinFormsView内的WinForms控件?

时间:2011-05-17 13:56:06

标签: winforms onkeydown

我在MDI应用程序的CWinFormsView V 内部有一个WinForms控件(假设 C )。 C 会覆盖 OnKeyDown 方法。我在 C 中也覆盖了 OnMouseUp ,我在那里调用 Focus()方法,所以当我点击 C 键盘消息直接转到它,一切正常。

但是,当我切换到 V 时,我希望能够使用键盘控制 C ,而无需在视图内部单击。我怎样才能做到这一点?我是否需要在 V 中捕获WM_KEYDOWN消息并将其手动传递给托管控件(换句话说, C )? C 实际上是 V 的子窗口,不应该以某种方式自动工作吗?

2 个答案:

答案 0 :(得分:0)

如果我按照你的问题,最简单的方法是让V向前推进到C。

看看Form.KeyPreview - 对于V--当V或其中一个孩子有焦点时,V会看到所有按键。然后,您可以将其转发给C.

答案 1 :(得分:0)

我实际上在 V 视图中使用以下代码解决了问题:

BOOL CMyView::PreTranslateMessage(MSG* pMsg)
{
    if( pMsg->message == WM_KEYDOWN || pMsg->message == WM_MOUSEWHEEL )
    {
        ::SendMessage( (HWND) m_myControl->Handle.ToInt32(), pMsg->message, pMsg->wParam, pMsg->lParam );
    }

    return CWinFormsView::PreTranslateMessage(pMsg);
}

我还删除了在鼠标单击时将焦点设置为 C 的代码。这样它就永远不会聚焦,但是从 PreTranslateMessage 接收父视图的消息(我需要WM_KEYDOWN和WM_MOUSEWHEEL)。不设置焦点是重要的,否则我将失去使用Ctrl + Tab在MDI视图之间切换的能力(如果 C 被聚焦)。所以现在我可以自由切换它们,然后当 V 变为活动时我可以使用键来控制 C 但我仍然可以使用Ctrl + Tab切换到另一个视图而不用必须使用鼠标。