如何在父窗体中处理 CEdit 鼠标单击?

2022-01-12 00:00:00 mfc

我是 MFC 的新手(来自 C# 和 Java)并且正在搞清楚.

I'm new to MFC (coming from C# and Java) and figuring things out.

考虑一个包含三个文本框的对话框.我将 CEdit 子类化为 CMyEdit,三个文本框都连接到对话框类中的 CMyEdit 变量.

Consider a dialog with three text boxes. I have subclassed CEdit to CMyEdit, and the three text boxes are hooked up to CMyEdit variables in the dialog class.

我想让对话框类知道"三个文本框中的任何一个被鼠标左键单击的时间.我找到了如何将 ON_WM_LBUTTONDOWN 处理程序添加到我的 CMyEdit 类的示例.效果很好,但处理程序仅在 CMyEdit 类中.假设每当单击一个文本框时,我希望对话框禁用另外两个.如何让对话框通知左键?

I want to allow the dialog class to "know" when any of the three text boxes has been clicked with the left mouse button. I have found examples of how to add an ON_WM_LBUTTONDOWN handler to my CMyEdit class. Works great, but the handler is in the CMyEdit class only. Suppose that whenever one of the text boxes is clicked, I want the dialog to disable the other two. How can I get the dialog notified of the left-click?

这是一个完全人为的简化示例.我实际上并没有担心在文本框中单击鼠标左键的应用程序.但我认为我无法弄清楚如何做到这一点表明对如何处理 MFC 中的 UI 事件存在根本性的误解.

This is a completely contrived and simplified example. I don'nt actually have an app where I'm worried about left clicks in text boxes. But I think the fact that I can't figure out how to do it indicates a fundamental misunderstanding of how to deal with UI events in MFC.

来自 C# 的世界,一切都为我完成,我可以直接访问我想要的任何事件(获得焦点、鼠标双击等)我很困惑为什么某些事件是特殊的,并且提供方便的访问.在 CEdit 的情况下,我不明白为什么获得焦点、取消焦点、更改以及其他几个直接"对我来说没有问题,但其他事件,如鼠标单击,则不是.

Coming from the world of C#, where everything is done for me and I have direct access to any of the events I want (got focus, mouse double click, whatever) I'm very confused on why certain events are special and provide easy access. In the case of CEdit, I don't understand why got focus, kill focus, change, and several others are "directly" available to me with no problem, but other events, like mouse click, are not.

但回到我的实际问题:在上面描述的场景中,我怎样才能让对话框通知鼠标左键单击文本框?文本框是否需要引发事件或向对话框发送消息(或其他内容)?

But back to my actual question: in the scenario described above, how can I get the dialog notified of the left mouse clicks on the text boxes? Do the text boxes need to raise events or send messages (or something else) to the dialog?

推荐答案

向您的消息映射添加 WM_LBUTTONUP 处理程序

Add a WM_LBUTTONUP handler to your message map

BEGIN_MESSAGE_MAP(CYourDialog, CDialog)
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

最简单的方法是向窗口添加事件处理程序.这最容易通过资源编辑器完成.转到属性页面,然后转到消息部分.然后为 WM_LBUTTONUP 添加一个函数.

It is easiest to do this by adding an event handler to the window. This is most easily done through the resource editor. Go to the properties page then go to the messages section. Then add a function for WM_LBUTTONUP.

最后你可以填写如下函数.

Finally you could fill in the function as follows.

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);
}

本质上,这将命中测试,如果命中测试在编辑窗口中,它将启用它,禁用其他的并为其提供键盘焦点.

This will, essentially, hit test and if the hit test is in an edit window it will enable it, disable the others and give it keyboard focus.

相关文章