views:

903

answers:

2

I'm building a project with MFC Feature Pack. Is this project I have a window which includes a CView, which includes a CListCtrl-derived object. The object includes the LVS_EDITLABELS flag.

Somehow I cannot edit the CListCtrl icon labels by two-time clicking (not double-clicking) on the icon label. After I select the item with a single click, a second click just flashes the item (button down turns text background to white, button up turns it back to blue) and the edit control never appears.

I reduced this problem to the simplest form, and even with a plain CListCtrl object I cannot edit the labels.

I also found that:

  • This problem occurs in VS2008. It doesn't occur in a similar project built in VS2003.

  • I am able to edit the labels if I build a CListView instead of a CView+CListCtrl.

  • I am also able to edit the labels if I build a CFormView and put the CListCtrl inside the resource dialog.

Here's some code in the simplest form: the .h file:

// vwTerminaisTeste.h
//
#pragma once
// vwTerminaisTeste view

    class vwTerminaisTeste : public CView
{
 DECLARE_DYNCREATE(vwTerminaisTeste)

protected:
 vwTerminaisTeste();           // protected constructor used by dynamic creation
 virtual ~vwTerminaisTeste();

 CListCtrl m_lstTerminais;

protected:
 DECLARE_MESSAGE_MAP()
 virtual void OnDraw(CDC* /*pDC*/);
public:
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 afx_msg void OnSize(UINT nType, int cx, int cy);
};

and the .cpp file:

// vwTerminaisTeste.cpp : implementation file
//

#include "stdafx.h"
#include "vwTerminaisTeste.h"

// vwTerminaisTeste

IMPLEMENT_DYNCREATE(vwTerminaisTeste, CView)
vwTerminaisTeste::vwTerminaisTeste()
{
}

vwTerminaisTeste::~vwTerminaisTeste()
{
}

BEGIN_MESSAGE_MAP(vwTerminaisTeste, CView)
 ON_WM_CREATE()
 ON_WM_SIZE()
END_MESSAGE_MAP()

// vwTerminaisTeste message handlers

void vwTerminaisTeste::OnDraw(CDC* /*pDC*/)
{
 CDocument* pDoc = GetDocument();
}

int vwTerminaisTeste::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CView::OnCreate(lpCreateStruct) == -1)
  return -1;

 m_lstTerminais.Create(WS_CHILD | WS_VISIBLE | LVS_EDITLABELS, CRect(0,0,1,1), this, 0);
 m_lstTerminais.InsertItem(0, "Teste", 0);

 return 0;
}

void vwTerminaisTeste::OnSize(UINT nType, int cx, int cy)
{
 CView::OnSize(nType, cx, cy);

 if (IsWindow(m_lstTerminais.GetSafeHwnd()))
  m_lstTerminais.MoveWindow(0, 0, cx, cy);
}

This way I cannot edit labels. To change it to a CListView I simply replaced CView by CListView and m_lstTerminais by GetListCtrl(), and removed the OnCreate and OnSize implementations. That way it worked.

Note: the vwTerminaisTeste is created from a CSplitterWndEx within a CMDIChildWndEx-derived class.

A: 

Well nobody solved this problem but I managed to go around it by changing the CView to a CFormView and building a resource dialog with a ListView control, attaching it to the CListCtrl-derived class.

If anyone still has any suggestions on how could I solve this problem entirely, I'd appreciate them.

djeidot
+1  A: 

This sounds like it may be a focus or command routing issue, although that doesn't explain why it works OK in VS2003. You might try routing the command and/or focus messages from the splitter ctrl to vwTerminaisTeste, and/or from the MDIChild to the splitter. If you haven't already, you may need to derive your own splitter window. The command/focus forwarding would be something like...

BEGIN_MESSAGE_MAP(MySplitter, CSplitterWnd)
  ON_WM_SETFOCUS()
END_MESSAGE_MAP(...)

void MySplitter::OnSetFocus(CWnd* pOldWnd)
{
  // forward focus to the view window
  m_vwTerminaisTeste.SetFocus();
}

BOOL MySplitter::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
  // let the view have first crack at the command
  if (m_vwTerminaisTeste.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    return TRUE;

  // otherwise, do default handling
  return MySplitter::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
mitcheljh