我在MDI 应用程序的 CWinFormsView V中有一个 WinForms 控件(比如说C )。C重写OnKeyDown方法。我在C中也覆盖了OnMouseUp并在那里调用Focus()方法,因此当我在C内部单击时,键盘消息直接转到它并且一切正常。
但是,当我切换到V时,我希望能够使用键盘控制C而无需在视图内单击。我怎样才能做到这一点?我是否需要在V中捕获 WM_KEYDOWN 消息并将它们手动传递给托管控件(换句话说,C)?C实际上是V的子窗口,它不应该以某种方式自动工作吗?
如果我遵循您的问题,最简单的方法是让 V 将印刷机转发给 C。
看看Form.KeyPreview
- 对于 V - 当它或它的一个孩子有焦点时,它会让 V 看到所有的按键。然后,您可以将其转发给 C。
我实际上用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 (如果C是焦点)在 MDI 视图之间切换的能力。所以现在我可以在它们之间自由切换,然后当V激活时,我可以使用按键来控制C,但我仍然可以使用 Ctrl+Tab 切换到另一个视图,而无需使用鼠标。