为什么在我的ListView中不调用WM_CHAR

为什么在我的ListView中不调用WM_CHAR,listview,mfc,event-handling,wtl,clistctrl,Listview,Mfc,Event Handling,Wtl,Clistctrl,有一个显示在窗口中的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(CPop

有一个显示在窗口中的
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&);
...
}

我想在ListView中捕捉WM_字符。我该怎么做,我缺少什么?

ListView
不允许键入文本。因此,它不需要生成
WM\u CHAR
。此特定消息通常使用API从击键转换而来。您的父窗口显然对其进行了调用。

ListView
不允许键入文本。因此,它不需要生成
WM\u CHAR
。此特定消息通常使用API从击键转换而来。您的父窗口显然对它进行了调用。

这很遗憾,因为我需要处理键入操作(我将跳转到给定的位置,就像列表框一样)。作为一种解决方法,我目前在
WM_KEYDOWN
中通过
ToUnicode
手动将键转换为char,并选择匹配的行。不确定是否有更好的办法。我不想在父视图中捕获WM_CHAR,然后发送回ListView。我想你可以覆盖
ListView
WndProc
,并在那里调用
TranslateMessage
。你的意思是,在
WndProc
中,如果
WM_KEYDOWN
到达,我只需调用
TranslateMessage
,哪个会发送WM_字符?嗯。可能不是在
WndProc
中,而是在发送消息之前(不知道在MFC代码中发生了什么)。您应该始终拨打
TranslateMessage
。是的,可能然后深入挖掘
WTL
(它不是
MFC
ListView
消息调度器核心代码,我可以做到。。。但现在看来这太过分了,所以我想我更喜欢第一条评论中描述的“变通方法”。这很遗憾,因为我需要处理打字(我将跳转到给定的位置,就像一个列表框一样)。作为一种解决方法,我目前在
WM_KEYDOWN
中通过
ToUnicode
手动将键转换为char,并选择匹配的行。不确定是否有更好的办法。我不想在父视图中捕获WM_CHAR,然后发送回ListView。我想你可以覆盖
ListView
WndProc
,并在那里调用
TranslateMessage
。你的意思是,在
WndProc
中,如果
WM_KEYDOWN
到达,我只需调用
TranslateMessage
,哪个会发送WM_字符?嗯。可能不是在
WndProc
中,而是在发送消息之前(不知道在MFC代码中发生了什么)。您应该始终拨打
TranslateMessage
。是的,可能然后深入挖掘
WTL
(它不是
MFC
ListView
消息调度器核心代码,我可以做到。。。但是现在看来这太过分了,所以我想我更喜欢第一条评论中描述的“变通方法”。你可以用虚拟函数PreTranslateMessage(MSG*pMsg)捕捉几乎所有的消息。你可以用虚拟函数PreTranslateMessage(MSG*pMsg)捕捉几乎所有的消息。
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
}