为啥我的 ListView 中没有调用 WM_CHAR

Posted

技术标签:

【中文标题】为啥我的 ListView 中没有调用 WM_CHAR【英文标题】:Why WM_CHAR is not called in my ListView为什么我的 ListView 中没有调用 WM_CHAR 【发布时间】:2017-08-16 02:03:20 【问题描述】:

有一个WTL::CListViewCtrl,它显示在一个窗口中。当它获得焦点并按下任何键时,会调用 WM_KEYDOWN / UP,但会调用 WM_CHAR。

class CPopupList : public CWindowImpl<CPopupList, WTL::CListViewCtrl>

public:
    DECLARE_WND_SUPERCLASS(NULL, WTL::CListViewCtrl::GetWndClassName())

BEGIN_MSG_MAP(CPopupList)
    MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
    MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
    MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
    MESSAGE_HANDLER(WM_CHAR, OnChar)
    REFLECTED_NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED, OnListItemChanged)
    DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()

LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/);
LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL&  /*bHandled*/);
LRESULT OnChar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/);
LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL&     afx_msg LRESULT OnListItemChanged(WPARAM wParam, LPNMHDR hdr, BOOL&);
...

CPopupList::OnKeyDownCPopupList::OnKeyUp 都被调用,但 CPopupList::OnChar 不被调用。

OnGetDlgCode 代码是return DLGC_WANTALLKEYS | DLGC_WANTCHARS;

我发现,如果我将 WM_KEYDOWN 发布到父窗口,则会在父窗口中调用 WM_CHAR:

LRESULT CPopupList::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)

    ::PostMessage(m_hWndParentCtrl, uMsg, wParam, lParam); -> this will call WM_KEYDOWN + WM_CHAR in parent

我想在 ListView 中捕捉 WM_CHAR。我该怎么做,我错过了什么?

【问题讨论】:

您可以使用虚函数 PreTranslateMessage(MSG* pMsg) 捕获几乎所有消息。 【参考方案1】:

ListView 不允许键入文本。因此,它不需要产生 WM_CHAR。此特定消息通常是使用TranslateMessage API 从击键转换而来的。您的父窗口显然会调用它。

【讨论】:

很可惜,因为我需要处理打字(我会跳到给定的位置,就像一个列表框左右)。我目前所做的,作为一种解决方法,在WM_KEYDOWN 中,我通过ToUnicode 手动将键转换为char,然后选择匹配的行。不确定是否有更好的主意。我不想在父级中捕获 WM_CHAR 然后发送回 ListView。 我想你可以覆盖ListViewWndProc 并在那里拨打TranslateMessage 所以你的意思是,在WndProc 中,如果WM_KEYDOWN 到达,我只需调用TranslateMessage,它会发送一个WM_CHAR ? 嗯。可能不在WndProc 中,而是在发送消息之前(不知道在MFC 代码中发生了什么)。您应该始终致电TranslateMessage。 win32developer.com/tutorial/windows/windows_tutorial_2.shtm 是的,可能然后深入研究WTL(不是MFCListView 消息调度程序核心代码,我可以做到……但现在看起来太多了,所以我想我更喜欢第一条评论中描述的“解决方法”。

以上是关于为啥我的 ListView 中没有调用 WM_CHAR的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ListView onScroll() 被多次调用,每次都使用相同的参数量?

为啥我的 ListView 使我的应用程序崩溃而不是列出我的条目?

Listview 没有被填充,getView() 没有被调用

为啥我的依赖属性绑定没有按预期工作?

为啥只有 ListView.builder() 中的内容不滚动?

为啥 ListFragment 在没有 ListView 标签的情况下工作?