Forum
Please
Log In
to post a new message or reply to an existing one. If you are not registered, please
register.
NOTE: Some forums may be read-only if you are not currently subscribed to
our technical support services.
Subject |
Author |
Date |
|
Bart Kampers
|
Feb 4, 2008 - 4:30 AM
|
Hello,
I found that CExtTreeGridWnd::ItemFocusSet crashes when I remove all children from a tree, then re-populate it and set the focus to the first child.
The code below only works the first time I invoke it. The second time it chrashes except when the user does not change the focus manualy.
ItemRemove(ItemGetRoot(), false, false);
Populate(); // Populates the CExtTreeGridWnd and ensures that the root has one child
HTREEITEM focused = ItemGetFirstChild(ItemGetRoot()); ItemFocusSet(focused, NAME_COLUMN, false);
Does someone have some clue?
Kind regards.
|
|
Technical Support
|
Feb 6, 2008 - 11:16 AM
|
Could you e-mail us this project to the support mail box at this web site?
|
|
Bart Kampers
|
Feb 6, 2008 - 1:20 AM
|
I remove rows by "ItemRemove(ItemGetRoot(), false, false)" just before populating the tree (see first posting).
I made a small project that illustrates this problem. Here is the cpp file where the tree is (re)built. I can send you the project in a zip file if you tell me where to send it to.
Thanks in advance.
// test_profuis_treegridDlg.cpp : implementation file //
#include "stdafx.h" #include "test_profuis_treegrid.h" #include "test_profuis_treegridDlg.h"
#ifdef _DEBUG #define new DEBUG_NEW #endif
// Ctest_profuis_treegridDlg dialog
void CTestGrid::Init() { SiwModifyStyle( __ESIS_STH_PIXEL | __ESIS_STV_ITEM | __EGBS_SFM_FULL_ROWS | __EGBS_RESIZING_CELLS_OUTER_H | __EGBS_RESIZING_CELLS_INNER_H | __EGBS_DYNAMIC_RESIZING_H | __EGBS_MULTI_AREA_SELECTION | __EGBS_NO_HIDE_SELECTION | __EGBS_GRIDLINES | __EGBS_LBEXT_SELECTION, 0, false); HoverEventsSet(true, true); OuterRowCountTopSet(1, false); ColumnAdd(1, false); CRect rect; GetClientRect(rect); CExtGridCellHeader * headerCell = STATIC_DOWNCAST(CExtGridCellHeader, GridCellGetOuterAtTop(0, 0, RUNTIME_CLASS(CExtGridCellHeader))); headerCell->ExtentSet(rect.Width()); headerCell->TextSet(_T("Name")); Fill(10); }
void CTestGrid::Fill(int pNrRows) { for (int i = 0; i < pNrRows; i++) { HTREEITEM item = ItemInsert(ItemGetRoot()); CExtGridCellString* cell = (CExtGridCellString*) ItemGetCell(item, 0, 0, RUNTIME_CLASS(CExtGridCellString)); cell->TextSet(_T("Press ’Broken’ to trigger the bug")); cell->ModifyStyle(__EGCS_NO_INPLACE_CONTROL); { HTREEITEM childItem = ItemInsert(item); CExtGridCellString* cell = (CExtGridCellString*) ItemGetCell(childItem, 0, 0, RUNTIME_CLASS(CExtGridCellString)); cell->TextSet(_T("Press ’Fixed’ to run the *fixed* code")); cell->ModifyStyle(__EGCS_NO_INPLACE_CONTROL);
if (i == pNrRows-1) mFocusItem = childItem; } } }
void CTestGrid::Refill(bool pBroken) { // remove all ItemRemove(ItemGetRoot(), false, true);
// make 10 rows Fill(10);
// and set the focus to the last row ItemEnsureExpanded(mFocusItem, true); ItemEnsureVisibleBranch(mFocusItem, true); ItemFocusSet(mFocusItem, 0, true); CPoint p = FocusGet(); // p unequal (-1, -1), which is OK.
ItemRemove(ItemGetRoot(), false, true); // At this point, the grid should be entirely empty and the focus should automatically be lost. p = FocusGet(); // p should be (-1, -1) as the focused item no longer exists.
if (!pBroken) { // FIX: remove focus CPoint previousFocus = FocusSet(CPoint(-1,-1)); }
// fill with less rows then before Fill(4);
HTREEITEM focused = ItemGetFirstChild(ItemGetRoot()); // This will assert in prof-uis 2.81: ItemFocusSet(focused, 0, true); // will try to do something with the old, broken focused item. }
/////////////////////////////////////////////////////////////////////////////////////////////
Ctest_profuis_treegridDlg::Ctest_profuis_treegridDlg(CWnd* pParent /*=NULL*/) : CDialog(Ctest_profuis_treegridDlg::IDD, pParent) {
}
void Ctest_profuis_treegridDlg::DoDataExchange(CDataExchange* pDX) { __super::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(Ctest_profuis_treegridDlg, CDialog) ON_BN_CLICKED(IDC_BUTTON_BROKEN, &Ctest_profuis_treegridDlg::OnBnClickedButtonBroken) ON_BN_CLICKED(IDC_BUTTON_FIXED, &Ctest_profuis_treegridDlg::OnBnClickedButtonFixed) END_MESSAGE_MAP()
// Ctest_profuis_treegridDlg message handlers
BOOL Ctest_profuis_treegridDlg::OnInitDialog() { __super::OnInitDialog();
CRect rect; GetDlgItem(IDC_GRID_PLACEHOLDER)->GetWindowRect(rect); ScreenToClient(rect);
mGrid.Create(this, rect, 1234); mGrid.Init(); mGrid.Invalidate();
return TRUE; // return TRUE unless you set the focus to a control }
void Ctest_profuis_treegridDlg::OnBnClickedButtonBroken() { mGrid.Refill(true); }
void Ctest_profuis_treegridDlg::OnBnClickedButtonFixed() { mGrid.Refill(false); }
|
|
Technical Support
|
Feb 5, 2008 - 12:00 PM
|
We cannot see anything that would remove tree rows in your code snippets. These code snippets are only initializing grid cells. Please try to use ASSERT_VALID for returned cell pointers after each invocation of the ItemGetCell() method. Please also ensure your code removes tree rows using the CExtTreeGridWnd::ItemRemove() method. To remove all items, you should remove all child items of the root item.
|
|
Bart Kampers
|
Feb 5, 2008 - 3:45 AM
|
This is the code that initializes the TreeGrid. It is execute only once.
SiwModifyStyle( __ESIS_STH_PIXEL | __ESIS_STV_ITEM | __EGBS_RESIZING_CELLS_OUTER_H | __EGBS_RESIZING_CELLS_INNER_H | __EGBS_DYNAMIC_RESIZING_H | __EGBS_SFM_FULL_ROWS | __EGBS_NO_HIDE_SELECTION | __EGBS_GRIDLINES, 0, false); OuterRowCountTopSet(1, false); ColumnAdd(NUMBER_OF_TUPLE_COLUMNS, false); for (LONG column = 0; column < NUMBER_OF_TUPLE_COLUMNS; column++) { CExtGridCellHeader * headerCell = STATIC_DOWNCAST(CExtGridCellHeader, GridCellGetOuterAtTop(column, 0, RUNTIME_CLASS(CExtGridCellHeader))); headerCell->ExtentSet(COLUMN_WIDTH); switch (column) { case TUPLE_NAME_COLUMN : headerCell->TextSet(_T("Tuple")); break; case TUPLE_VALUE_COLUMN : headerCell->TextSet(_T("Value")); break; } }
Here are methods which Poputalte() calls to insert cells:
to fill the first column HTREEITEM CTupleTreeGrid::ObjectItemInsert(HTREEITEM pParentItem, const CBlockDataObject* pBlockDataObject, uint32 pIndex, size_t pSize) { HTREEITEM childItem = NULL; if ((pParentItem != NULL) && (pBlockDataObject != NULL)) { childItem = ItemInsert(pParentItem); CExtGridCellString* cell = (CExtGridCellString*) ItemGetCell(childItem, TUPLE_NAME_COLUMN, 0, RUNTIME_CLASS(CExtGridCellString)); const std::string* nameStdString = pBlockDataObject->GetNameId(); CString nameCString; COLORREF color; if (nameStdString != NULL) { nameCString.Format(_T("%s"), CA2T(nameStdString->c_str())); color = DEFAULT_TEXT_COLORREF; } else { nameCString = "?"; color = UNKNOWN_NAME_TEXT_COLORREF; } if (pSize > 0) { CString indexCString; indexCString.Format(_T("[%d/%d]"), pIndex, pSize); nameCString += indexCString; } cell->TextSet(nameCString); cell->TextColorSet(CExtGridCell::__ECS_NORMAL, color); cell->ModifyStyle(__EGCS_NO_INPLACE_CONTROL); cell->LParamSet((LPARAM) pBlockDataObject); } return childItem; }
To fill the second column:
CString dataCString; dataCString.Format(_T("%s"), CA2T(dataStdString.c_str())); CExtGridCellString* cell = (CExtGridCellString*) mTree->ItemGetCell(childItem, TUPLE_VALUE_COLUMN, 0, RUNTIME_CLASS(CExtGridCellString)); cell->TextSet(dataCString); cell->ModifyStyle(__EGCS_NO_INPLACE_CONTROL);
|
|
Technical Support
|
Feb 4, 2008 - 10:12 AM
|
Could you show the code that removes and re-initializes the tree in your project? We need to know the exact way that would allow us to re-produce this crash.
|
|