snakefoot/cgridlistctrlex

No public method to delete column trait

Closed this issue · 7 comments

yscgz commented

In the case of dynamic inserting / deleting column, there is no public method to do it.

Pretty sure I'm misunderstanding the question, but why not use use these:

int CGridListCtrlEx::InsertColumnTrait(...);
int CListCtrl::InsertColumn(...);
BOOL CListCtrl::DeleteColumn(...);

They are very public and available.

If you mean hiding and showing existing column, then you have:

BOOL CGridListCtrlEx::ShowColumn(int nCol, bool bShow);

If you want to pull the pants off CGridListCtrlEx and do nasty stuff, then just inherit from it and you have access to these protected babies:

CSimpleArray<CGridColumnTrait*> m_ColumnTraits;
virtual void InsertColumnTrait(int nCol, CGridColumnTrait* pTrait);
virtual void DeleteColumnTrait(int nCol);

But they are not intended for public use, and only for those who know what they are doing.

yscgz commented

Yes, I knew the method BOOL CListCtrl::DeleteColumn(...). I added a column of CGridColumnTraitCombo, and added some items into it. When deleting column, there occurs error. Maybe CGridColumnTraitCombo can't free its buffer automatically. Is there an easy way to do it?

@yscgz Think you have to post an example of what you are doing. Maybe also a callstack of when the error occurs.

yscgz commented

There is an application based on dialog. In OnInitDialog, initialize list control and insert some columns. Then, uses right click pop menu to add columns and delete column. In the method of adding column, the code is like as below.

CString title;
CGridColumnTrait* pTrait = NULL;
int col_num = m_ListCtrl.GetColumnCount();

std::vector<CString> names;

for (uint16 i = 0; i < get_name_count(); i++)
{
	names.push_back(get_name(i));
}

std::vector<CString> o_names;

for (uint8 i = 0; i < get_o_name_count(); i++)
{
	o_names.push_back(get_o_name(i));
}

int col;
for (int j=0; j<3; j++) // insert 3 columns
{
	col = col_num + j - 1;

	if ((col == 2) || (col == 5) || (col == 8) || (col == 11)) // name.
	{
		title.Format(_T("%d Name"), (col + 1) / 3);
		CGridColumnTraitCombo* pComboTrait = new CGridColumnTraitCombo;

		for (uint16 i = 0; i < names.size(); i++)
		{
			pComboTrait->AddItem((DWORD_PTR)i, names[i]);
		}

		DWORD style = pComboTrait->GetStyle();
		style &= ~CBS_DROPDOWN;
		style |= CBS_DROPDOWNLIST;
		pComboTrait->SetStyle(style);
		pTrait = pComboTrait;
	}
	if ((col == 3) || (col == 6) || (col == 9) || (col == 12)) // text
	{
		title.Format(_T("%d text"), (col + 1) / 3);
		pTrait = new CGridColumnTraitEdit;
	}
	if ((col == 4) || (col == 7) || (col == 10) || (col == 13)) // o_names
	{
		title.Format(_T("%d o_names"), (col + 1) / 3);
		CGridColumnTraitCombo* pComboTrait = new CGridColumnTraitCombo;

		for (uint8 i = 0; i < o_names.size(); i++)
		{
			pComboTrait->AddItem((DWORD_PTR)i, o_names[i]);
		}
		DWORD style = pComboTrait->GetStyle();
		style &= ~CBS_DROPDOWN;
		style |= CBS_DROPDOWNLIST;
		pComboTrait->SetStyle(style);
		pTrait = pComboTrait;
	}
	pTrait->GetColumnState().m_Sortable = false;
	m_ListCtrl.InsertColumnTrait(col + 1, title, LVCFMT_LEFT, 100, col, pTrait);
}

In the method of deleting column, the code is like as below.

int col_num = m_ListCtrl.GetColumnCount();

m_ListCtrl.DeleteColumn(col_num-1);
m_ListCtrl.DeleteColumn(col_num-2);
m_ListCtrl.DeleteColumn(col_num-3);

Adding and deleting, then VS2015 reported "Debug Assertion Failed!
at cgridrowtraittext.cpp
Line: 234"
where,

VERIFY(owner.GetCellRect(nRow, owner.GetFocusCell(), LVIR_BOUNDS, rcHighlight));

Any suggestion?

Tried using the demo-project (CGridListCtrlExDlg) and delete all columns when opening the About-box (Using DeleteColumn). Did not get any errors.

Are you a multi-threaded application? (Deleting the columns from a non-gui-thread or updating the clistctrl from a non-gui-thread)

Can you attach an example project?

yscgz commented

I think I found the cause. Before deleting columns, it focus on the cell which would be deleted. If I changed the focus on another cell before deleting columns, there is no error.