0

There is a WTL::CListViewCtrl, which is displayed in a Window. When it has the focus, and any key is pressed, the WM_KEYDOWN / UP is called, but the 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&);
...
}

Both CPopupList::OnKeyDown and CPopupList::OnKeyUp are called, but CPopupList::OnChar is not.

The OnGetDlgCode code is return DLGC_WANTALLKEYS | DLGC_WANTCHARS;

What I found, if I post the WM_KEYDOWN to the Parent window, WM_CHAR is being called in the Parent:

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
}

I would like to catch the WM_CHAR here in the ListView. How can I do that, what am I missing?

Zoli
  • 841
  • 8
  • 31

1 Answers1

2

ListView does not allow typing text. Hence, it does not need to produce WM_CHAR. This particular message is typically translated from keystrokes using the TranslateMessage API. Your parent window obviously makes a call to it.

l33t
  • 18,692
  • 16
  • 103
  • 180
  • That is pity, as I need to handle typing (I will jump to the given position, just like a listbox or so). What I do currently, as a workaround, in `WM_KEYDOWN`, I manually translate the key to char by `ToUnicode`, and select that row which matches. Not sure if any better idea to do so. I don't want to catch WM_CHAR in parent and then send back to ListView. – Zoli Mar 23 '17 at 15:50
  • I suppose you could override the `WndProc` of the `ListView` and make the call to `TranslateMessage` there. – l33t Mar 24 '17 at 07:56
  • So you mean, in `WndProc`, if `WM_KEYDOWN` arrives, I just make a call to `TranslateMessage` , which will send a WM_CHAR ? – Zoli Mar 24 '17 at 16:52
  • Hmm. Maybe not in `WndProc`, but instead before the message is dispatched (don't know where in MFC code that happens). You should *always* make a call to `TranslateMessage`. http://www.win32developer.com/tutorial/windows/windows_tutorial_2.shtm – l33t Mar 26 '17 at 07:21
  • Yes, probably then digging into the `WTL` (it's not `MFC`) `ListView` message dispatcher core code, I could do it ... but that looks too much for this now, so I think I prefer my "workaround" described in the first comment. – Zoli Mar 27 '17 at 10:22