1

I have a problem using MESSAGE_MAP &/or PreTranslateMessage. This may be a design issue but I'm not sure. The main issue is MESSAGE_MAP code not being called & not sure how to do same via PreTranslateMessage. ie as follows:

    //MyCDialogEx : public CDialogEx
    class MyCDialogEx::Init()
    {
        CFlatSplitterWnd m_cSplitter; //http://www.codersource.net/2010/01/29/mfc-splitter-window/
        m_pFrame = new CFlatFrameWnd;
        m_pFrame->Create(strMyClass, L"", WS_CHILD, rect, this);
        m_pFrame->ShowWindow(SW_SHOW);
        m_cSplitter.CreateStatic(m_pFrame, 1, 2);

        m_cSplitter.ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_NOSIZE | SWP_NOACTIVATE);
        m_cSplitter.CreateView(0, 0, RUNTIME_CLASS(CHolderView), CSize(100, 100), &ccc);

        CHolderView* pView = (CHolderView*)m_cSplitter.GetPane(0, 0);
        ASSERT_VALID(pView);
        pView->setWnd(&m_TreeCtrl);
        pView->setOwner(this, IDC_TREECTRL);

        const DWORD dwStyle = LBS_NOTIFY | WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES
         | TVS_LINESATROOT | TVS_CHECKBOXES | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP;
        m_TreeCtrl.Create(dwStyle, CRect(0, 0, 1, 1), pView, IDC_TREECTRL);
    }

    BEGIN_MESSAGE_MAP(MyCDialogEx, CDialogEx)
        ON_NOTIFY_REFLECT(WM_ONMYCLICK, OnClickTreectrl) //this & following not called
        ON_NOTIFY(NM_CLICK, IDC_TREECTRL, OnClickTreectrl)
        ON_NOTIFY(TVN_ITEMCHANGED, IDC_TREECTRL, OnItemchangedTreectrl)
        ON_NOTIFY(TVN_SELCHANGED, IDC_TREECTRL, OnSelchangedTreectrl)
        ON_NOTIFY(TVN_KEYDOWN, IDC_TREECTRL, OnKeydownTreectrl)
    END_MESSAGE_MAP()

    BOOL MyCDialogEx::PreTranslateMessage(MSG* pMsg)
    {
        if (GetFocus() && GetFocus()->GetDlgCtrlID() == IDC_TREECTRL)
        {
            //what/how goes in here to catch NM_CLICK, TVN_ITEMCHANGED etc??

            if (pMsg->message == WM_LBUTTONDOWN)
            {
                switch (LOWORD(pMsg->wParam))
                {
                case NM_CLICK:
                    break;
                }
            }
            if (pMsg->message == WM_KEYDOWN)
                TRACE(L"WM_KEYDOWN\n");

            if (pMsg->message == WM_KEYUP)
                TRACE(L"WM_KEYUP\n");
        }
        return MyCDialogEx::PreTranslateMessage(pMsg);
    }
    void MyCDialogEx::OnClickTreectrl(NMHDR *pNMHDR, LRESULT *pResult) //not called
    {
        TRACE(L"tree click\n");
        *pResult = 0;
    }

MESSAGE_MAP works if I house these in CHolderView class MESSAGE_MAP, but I rather not as it's just a container class & will possibly be used elsewhere in my project.

What I'd really like to do is use MESSAGE_MAP to minimize coding via PreTranslateMessage (& if it's possible to redirect to MESSAGE_MAP, how?). If I must resort to PreTranslateMessage or other, then how do I use this so I can catch the relevant NM_CLICK, TVN_ITEMCHANGED for tree control etc.

Thank you.

EDIT: oh & the following don't help, not relevant or don't sufficiently explain:

Community
  • 1
  • 1
ReturnVoid
  • 1,106
  • 1
  • 11
  • 18

1 Answers1

3

The problem is that the tree view will send all its notifications to the parent window. And the parent windows is the CHolderWindow.

Messages are not routed like WM_COMMAND messages. So handler for WM_COMMAND messages may reside anywhere in the notification path.

But regular window control notifications are always handled in the direct parent of the window. In MFC you can redirect such notfications to the child window control itself. Using ON_..._REFLECT.

A trick can be: Set a pointer to a window to the holder window, that should receive all messages. Than accept all WM_COMMAND and all WM_NOTIFY messages in the holder window and resend them to the new window.

PreTranslateMessage is another thing. The target window always receives a call first. Than all parents will get a chance until somebody in the chain of PreTranslateMessage calls returns TRUE.

xMRi
  • 14,982
  • 3
  • 26
  • 59
  • "A trick can be...." Can you please elaborate? CHolderWindow has a pointer to child window but calling m_pDlgOwner->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam); in it's PreTranslateMessage doesn't call the childs message_map and using reflect in CHolderWindow is not being called :/. ie ON_NOTIFY_REFLECT(NM_CLICK, OnClickCtrl) – ReturnVoid Nov 20 '15 at 19:03
  • I only mean that cou can except WM_COMMAND/WM_NOITY Messages in the holder Windows and resend it to the child. This will never work for PreTranslateMessage and the parent classes will get a Chance to handle PreTranslateMessage if the Messages isn't handled before! So there is no reason for "resending somehting with PreTranslateMessage" – xMRi Nov 22 '15 at 21:20