如果我单击对话框中的项目(ListBox、CheckBox 等),则不会触发 OnLButtonDown(),但如果单击背景或静态文本,它会触发

Posted

技术标签:

【中文标题】如果我单击对话框中的项目(ListBox、CheckBox 等),则不会触发 OnLButtonDown(),但如果单击背景或静态文本,它会触发【英文标题】:OnLButtonDown() is not fired if I click an item in my dialog (ListBox, CheckBox etc) but it fires ok if I click background or Static Text 【发布时间】:2012-07-26 22:31:40 【问题描述】:

如果我单击对话框窗口中的任意位置,例如“背景”或静态文本,则会触发函数 OnLButtonDown()。但是,如果我单击 ListBox/EditBox/Combo/Calendar/Checkbox 等,则不会被触发。 我认为这是因为它们附加了控制变量,而静态文本没有。但是在我的对话框中添加一个新的列表框并进行测试,我发现它也没有触发,所以现在我很困惑......

我用类向导添加了 OnLButtonDown(),它出现在:

BEGIN_MESSAGE_MAP(CMFCTesting2Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
// other handlers, etc
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

我的功能:

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

    AfxMessageBox(CString("BUTTON DOWN"));
    CDialogEx::OnLButtonDown(nFlags, point);

我尝试在 AfxMessageBox... 之前调用 CDialogEx:: ... 但结果相同。

CListBox 项的 Notify 选项设置为 True,正如我在其他帖子中看到的一些建议。

我怀疑 WM 通知消息被 ListBox 以某种方式捕获,而不是“转发”到我的 CMFCTesting2Dlg,但我知道这应该在 ListBox 上将 Notify 选项设置为 True 时发生,不是吗? (嗯,很明显,不是……)

抱歉,我是新来在 MFC 中处理 WM。

顺便说一句,我使用 Visual Studio 2010 Ultimate,这是一个 Visual C++ - MFC- MFC 应用程序 - 基于对话框的项目。

如果单击列表框/组合/等,我如何捕获此鼠标按下事件?

在 LONG STORY 中,我实际上是在尝试解决这个问题: 我有两个列表框(比如说),我想同步滚动它们,当用户滚动其中一个时,其他的必须滚动相同(或在下一刻更新)。我想用鼠标按下来跟踪每个列表框的位置(使用 GetTopIndex),然后在鼠标向上时,再次使用 GetTopIndex 并与以前的进行比较。如果进行了更改,则滚动列表框,然后使用 SetTopIndex 更新所有列表框。对用户不友好但对我来说更简单的解决方案是单击一个执行此验证/更新的按钮,但它一点也不优雅,它只能将它们设置在同一级别,但无法确定哪个是上次滚动。列表框的这种自动滚动应该只是为了显示,列表框中的选择并不重要。我尝试在列表框的添加事件处理程序中使用消息类型,但是如果拖动滚动条,只有在单击列表框中的项目时,才不会触发针对我的问题显示的任何内容,即 KillFocus 和 SetFocus。 ..我在其他消息类型上也没有成功,来自添加事件处理程序。

【问题讨论】:

【参考方案1】:

一旦一个窗口处理了一条消息,它就会停止发送到它下面的其他窗口。静态窗口不处理鼠标按下,因此它进入对话框。其他控件都以某种方式处理它(至少设置焦点),因此它永远不会进入对话框。

您可以在每个控件中覆盖 OnLButtonDown 处理程序,以在它们完成基类中的默认处理后执行其他操作。您还可以在对话框的 PreTranslateMessage 方法中看到消息。

【讨论】:

感谢您的回复。我设法派生 CListBox 并覆盖 OnLButtonDown,当我在 ListBox 内单击时它会触发。但是当我点击滚动条时它不会触发。 codeclass CMyListBox : 公共 CListBox code code DECLARE_MESSAGE_MAP() code afx_msg void OnLButtonDown( UINT nFlags, CPoint pt ); code afx_msg void OnLButtonUp(UINT nFlags, CPoint pt); codepublic:codeCMyListBox(void); code virtual ~CMyListBox(void); code;在 .cpp 文件中:codeBEGIN_MESSAGE_MAP(CMyListBox, CListBox) code ON_WM_LBUTTONDOWN() code ON_WM_LBUTTONUP() codeEND_MESSAGE_MAP() 我成功地将 ON_WM_VSCROLL() 添加到 .【参考方案2】:

就让列表控件同步滚动而言,最好的办法是通过继承 CListCtrl 或 PreTranslateMessage 来拦截 WM_VSCROLL,然后在另一个列表上调用 SetScrollInfo。如果列表中的项目数相同,则应该相当简单。

【讨论】:

谢谢,我会试试这个,它看起来更适合我的需要。虽然不知道从何说起。子类化 CListCtrl?我正在使用 CListBox。正如我在上面的帖子中所说,我对它进行了子类化,类 CMyListBox :公共 CListBox 等,(对不起那个乱码,我试图格式化它......)。我可以在 CMyListBox 类中使用这条消息 WM_VSCROLL,就像我覆盖 OnLButtonDown 一样?列表中的项目数相同。 点击垂直滚动时触发的 afx_msg OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 成功。问题是它仅在我用鼠标拖动滚动条时有效,它不适用于鼠标滚轮或箭头/向上翻页。目前对于我的项目来说还可以,尽管我很好奇如何在所有情况下都做到这一点。此时,当我使用鼠标滚轮时,它会通过列表框移动但不会同步它们,因此,我的函数没有被调用,因为没有使用 WM_VSCROLL。其他方式来实现这一点? 这是一个很好的观点。一种可能的方法是处理 LBN_SELCHANGE 通知并检查顶部索引是否有更改。这应该抓住箭头键和向上/向下翻页。对于***,处理 WM_MOUSEWHEEL 应该允许您转发这些消息。

以上是关于如果我单击对话框中的项目(ListBox、CheckBox 等),则不会触发 OnLButtonDown(),但如果单击背景或静态文本,它会触发的主要内容,如果未能解决你的问题,请参考以下文章

仅允许在 ListBox 中右键单击来选择项目

在matlab的GUI中的listbox如何添加选项

Python - 如何删除选定ListBox项目周围的边框?

使用警报对话框android的颜色ListView项目

如何在选中复选框时选择列表框中的所有项目?

复制并删除所选的列表框项目