如果我单击对话框中的项目(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 内单击时它会触发。但是当我点击滚动条时它不会触发。code
class 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); code
public:code
CMyListBox(void); code
virtual ~CMyListBox(void); code
;在 .cpp 文件中:code
BEGIN_MESSAGE_MAP(CMyListBox, CListBox) code
ON_WM_LBUTTONDOWN() code
ON_WM_LBUTTONUP() code
END_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(),但如果单击背景或静态文本,它会触发的主要内容,如果未能解决你的问题,请参考以下文章