我是MFC的新手(来自C#和Java)并搞清楚了。
考虑一个带有三个文本框的对话框。我将CEdit子类化为CMyEdit,并且三个文本框连接到对话框类中的CMyEdit变量。
我希望当用鼠标左键单击三个文本框中的任何一个时,允许对话框类“知道”。我找到了如何将ON_WM_LBUTTONDOWN处理程序添加到我的CMyEdit类的示例。效果很好,但处理程序只在CMyEdit类中。假设每当单击其中一个文本框时,我希望该对话框禁用其他两个文本框。如何通知对话框左键单击?
这是一个完全做作和简化的例子。我实际上没有一个应用程序,我担心文本框中的左键单击。但我认为我无法弄清楚如何做到这一事实表明了对如何处理MFC中的UI事件的根本误解。
来自C#的世界,一切都为我完成,我可以直接访问我想要的任何事件(获得焦点,鼠标双击,无论如何)我很困惑为什么某些事件是特殊的,提供方便的访问。在CEdit的情况下,我不明白为什么聚焦,杀死焦点,改变,以及其他几个“直接”可用于我没有问题,但其他事件,如鼠标点击,不是。
但回到我的实际问题:在上述场景中,如何通知鼠标左键单击文本框的对话框?文本框是否需要引发事件或向对话框发送消息(或其他内容)?
答案 0 :(得分:2)
将WM_LBUTTONUP处理程序添加到消息映射
即
BEGIN_MESSAGE_MAP(CYourDialog, CDialog)
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
最简单的方法是在窗口中添加一个事件处理程序。这最容易通过资源编辑器完成。转到属性页面,然后转到消息部分。然后为WM_LBUTTONUP添加一个函数。
最后你可以按如下方式填写这个功能。
void CYourDialog::OnLButtonUp(UINT nFlags, CPoint point)
{
// Grab the 3 (or more) edit control
CEdit* pEdit1 = (CEdit*)GetDlgItem( ID_YOUR_EDIT_CONTROL1 );
CEdit* pEdit2 = (CEdit*)GetDlgItem( ID_YOUR_EDIT_CONTROL2 );
CEdit* pEdit3 = (CEdit*)GetDlgItem( ID_YOUR_EDIT_CONTROL3 );
// Grab the edit control window rects in screen coords.
CRect edit1Rect;
CRect edit2Rect;
CRect edit3Rect;
pEdit1->GetWindowRect( &edit1Rect );
pEdit2->GetWindowRect( &edit2Rect );
pEdit3->GetWindowRect( &edit3Rect );
// Convert to client coordinates relative to their parent (ie this) window.
ScreenToClient( edit1Rect );
ScreenToClient( edit2Rect );
ScreenToClient( edit3Rect );
// Test if the point passed in to this function is in the control's rectangle.
const BOOL bEnable1 = edit1Rect.PtInRect( point );
const BOOL bEnable2 = edit2Rect.PtInRect( point );
const BOOL bEnable3 = edit3Rect.PtInRect( point );
// Enable the window that was clicked on and disable the others.
pEdit1->EnableWindow( bEnable1 );
pEdit2->EnableWindow( bEnable2 );
pEdit3->EnableWindow( bEnable3 );
// Set keyboard focus to the relevant control
if ( bEnable1 )
{
pEdit1->SetFocus();
}
else if ( bEnable1 )
{
pEdit2->SetFocus();
}
else if ( bEnable1 )
{
pEdit3->SetFocus();
}
CDialog::OnLButtonUp(nFlags, point);
}
这基本上会进行测试,如果命中测试位于编辑窗口中,它将启用它,禁用其他测试并给予键盘焦点。