CView 类中的标签编辑(EditLabel)忽略鼠标点击

Posted

技术标签:

【中文标题】CView 类中的标签编辑(EditLabel)忽略鼠标点击【英文标题】:Label editing (EditLabel) in CView class ignores mouse clicks 【发布时间】:2014-07-23 16:33:21 【问题描述】:

我有一个使用 CView 类的应用程序,其中 CListCtrl 作为其主要控件。当我使用 EditLabel 函数时,它的“工作原理”是标签编辑开始,现有字符被突出显示,我可以使用键盘箭头键来移动和更改文本。但是我无法识别鼠标。因此,如果最终用户想要单击现有文本中的某处并对其进行修改,则无法识别该单击。只有箭头键、home、end 等可用于导航编辑单元格。

此应用程序还使用 CListCtrl 的多个对话框,并且就地编辑允许使用鼠标就好了。

因此,应用程序或框架中似乎有一些东西正在捕获 CEdit 控件中的鼠标单击。

此应用程序有很多事件处理程序,但在编辑模式下不会调用 OnClick 事件。调用 PretranslateMessage 处理程序,但不处理 WM_LBUTTONDOWN 消息。我可以给它设个陷阱,但还是不知道该把消息发到哪里去。

鼠标点击事件的去向有什么我遗漏的吗?

【问题讨论】:

如果这里要责备 MFC,我会感到非常惊讶。 IMO 更有可能是另一个应用程序(或您自己的应用程序)实际上导致了问题。 使用 Spy++ 确定鼠标点击不被接受的原因。 我确实使用了 Spy++,并且可以看到鼠标单击事件,但看不出与同一控件的其他用途有任何区别(只是不在 CView 中)。我将尝试了解有关 Spy++ 的更多信息,以查看是否可以看到消息“去向”的位置。我不知道如何在我的应用中追踪它。 【参考方案1】:

我遇到了与嵌入在 CFormView 派生类中的编辑控件类似的问题。

虽然启用并相应地亮起,但控件的行为就像它们被禁用或启用但被阻止使用的“力场”覆盖。无法使用鼠标选择它。它似乎不是与 MFC 文献一致的状态。

我主要通过子类化 MFC CEdit 控件并添加以下消息映射条目 - ON_WM_LBUTTONDOWN() - 及其处理程序来解决该问题:

void CMyEdit::OnLButtonDown(UINT nFlags, CPoint point)

    auto bEnabled = IsWindowEnabled();
    BOOL bReadOnly = GetStyle() & ES_READONLY;
    //ShowCursor(TRUE);
    //ShowCaret();// Does nothing

    // New logic to circumvent "force field" that prevents editing the control's contents
    // Identify the position that the mouse was clicked on
    auto ptMousePos = (CPoint)GetMessagePos();
    ScreenToClient(&ptMousePos);
    auto nChar = CharFromPos(ptMousePos);

    CEdit::OnLButtonDown(nFlags, point);
    if (bEnabled)
    
        auto pWnd = SetFocus();// Grab the focus
        TRACE(_T("Got focus \n"));

        // Explicitly select the character
        int nStartChar, nEndChar;// troubleshooting
        GetSel(nStartChar, nEndChar);// troubleshooting
        SetSel(nChar, nChar);// Automatically handles nChar overflow
    

处理程序完成了我们所需的大部分功能,但有细微的差别。例如,您不能在编辑控件中拖动选择文本。

【讨论】:

感谢您的回复。但是我不知道如何获取我的 CEdit 的通知,该通知是当我在其上启动 ::EditLabel 时由 CListCtrl 动态创建的。我在 ::OnBeginLabelEdit 中验证了我可以更改选择和内容,但无法让它识别鼠标点击。我假设您的 CEdit 标签是您表单上的控件? 没错。我们的 CEdit 控件位于 CFormView 派生类上。您之前提到您能够在 PreTranslateMsg 中捕获鼠标单击消息。执行此操作时,如果您可以访问编辑控件,则可以排除故障并对其进行操作,使其按您想要的方式运行。但是,如果使用 CListCtrl,这将是一项艰巨的任务。

以上是关于CView 类中的标签编辑(EditLabel)忽略鼠标点击的主要内容,如果未能解决你的问题,请参考以下文章

CPP:作为另一个类中的私有成员类

如何使用 CListCtrl 就地编辑列?

Python Qt GUI设计:QLabel标签类(基础篇—11)

Cocoa NSTextField - 绑定和设置属性

Protobuf-net / NetCore2:反序列化忽略带注释的私有字段

非编辑类中的 InvalidClassException