3

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.

demonplus
  • 5,613
  • 12
  • 49
  • 68
djeidot
  • 4,542
  • 4
  • 42
  • 45
  • Please provide some code. What are all of the style flags (base and extended) on the CListCtr?. Can you show the code that fills the list? – Aidan Ryan Apr 19 '09 at 02:54
  • Tip: If you really want this answered, sacrifice some of your reputation and attach a bounty to it. Then people will make efforts and try to reproduce the error etc. http://stackoverflow.com/questions/483019/how-does-the-bounty-system-work-in-stackoverflow – sharkin Apr 20 '09 at 12:02
  • Why do you especially need CView+CListCtrl instead of CListView? – Valentin Galea Apr 24 '09 at 11:53
  • Because I need to use a CListCtrl-derived class and not a CListCtrl/CListView. This class is also used in another forms and I don't want to duplicate it. – djeidot Apr 27 '09 at 09:00
  • Thanks for clarifying the question. I've deleted my answer, as it doesn't solve your problem. – ChrisN Apr 27 '09 at 12:54

2 Answers2

1

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
  • 170
  • 1
  • 2
  • 6
1

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
  • 4,542
  • 4
  • 42
  • 45