Tuesday, May 12, 2009

Desable VK_DELETE accelerator key while Editing Tree conrol's Item Label

Problem/Bug :
 User cannot delete characters with Delete key.

Technical Details:
In our application user can delete items in a Tree control. Say this menu COMMAND is ID_FILE_DELETE and its corresponding accelerator key is VK_DELETE. This tree control is created with  TVS_EDITLABELS style.

Behavior:
VK_DELETE accelerator key
method is invoking while editing HTREEITEM in CTreeCtrl.

Solution 1: Add following code in PreTranslateMessage

// Header file CLeftView.h
class CLeftView : public CTreeCtrl
{
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
};
// Header file CLeftView.cpp
BOOL CLeftView::PreTranslateMessage(MSG* pMsg)
{
      // A pointer to the edit control used to edit the item text, if successful;otherwise NULL
      if (__super::GetEditControl())
      {
            ::TranslateMessage(pMsg);
            ::DispatchMessage(pMsg);
            return TRUE;
      }
      return CTreeView::PreTranslateMessage(pMsg);
}

Solution 2: by avoid calling GetEditControl() every time

// Header file CLeftView.h
class CLeftView : public CTreeCtrl
{
public:
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
      DECLARE_MESSAGE_MAP()
      afx_msg void OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
      afx_msg void OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
private:
      bool m_bEditLabel;
};

// Source file CLeftView.cpp
CLeftView::CLeftView()
{
      m_bEditLabel = false;
}
BEGIN_MESSAGE_MAP(CLeftView, CTreeCtrl)
      ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, &CDMTreeCtrl::OnTvnBeginlabeledit)      ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, &CDMTreeCtrl::OnTvnEndlabeledit)
END_MESSAGE_MAP()
void CLeftView::OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult)
{
      LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
      m_bEditLabel = true;
      *pResult = 0;
}
void CLeftView::OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult)
{
      LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
      m_bEditLabel = false;
      // TODO: Add your control notification handler code here
      *pResult = 0;
}
BOOL CLeftView::PreTranslateMessage(MSG* pMsg)
{
      if( m_bEditLabel)
      {
            ::TranslateMessage(pMsg);
            ::DispatchMessage(pMsg);
            return TRUE;
      }
      return CTreeView::PreTranslateMessage(pMsg);
}

Solution 2: I am thinking.

 

No comments: