Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Report Control
  New Posts New Posts RSS Feed - Possible exception after RemoveRecordEx calling
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Possible exception after RemoveRecordEx calling

 Post Reply Post Reply
Author
Message
DiZSl View Drop Down
Groupie
Groupie


Joined: 08 August 2020
Status: Offline
Points: 11
Post Options Post Options   Thanks (0) Thanks(0)   Quote DiZSl Quote  Post ReplyReply Direct Link To This Post Topic: Possible exception after RemoveRecordEx calling
    Posted: 29 November 2024 at 1:40am
After calling RemoveRecordEx, it is essential to call UpdateWindows for the ReportControl. If this is not done and a user quickly clicks on the deleted record before the window is redrawn (updated), the function HitTest in CXTPReportControl::OnButton will return the deleted CXTPReportRow from the m_pScreenRows array, which is only updated during redrawing. However, the redraw has not yet occurred only invalidating, resulting in m_pScreenRows being out of sync with the main tree.

Additionally, when calling CXTPReportControl::OnButton, this removed CXTPReportRow will be passed to _SetSelectedRow, which will cause an index for a non-existent record to appear in the m_pSelectedRows array. As a result, m_pSelectedRows.GetCount will return 1, while m_pSelectedRows.GetAt(0) will return nullptr.

My solution (remove row from m_pScreenRows):
void CXTPReportRows::RemoveAt(int nIndex)
{
    auto row = m_arrRows.GetAt(nIndex);
    if (row != nullptr)
    {
        auto rows = GetScreenRows();
        if (rows != nullptr)
        {
            auto size = rows->GetCount();
            for (int i = 0; i < size; i++)
            {
                if (rows->GetAt(i) == row)
                {
                    row->InternalRelease();
                    rows->RemoveAt(i);
                    break;
                }
            }
        }

        row->InternalRelease();
    }
    m_arrRows.RemoveAt(nIndex);
}

Back to Top
agontarenko View Drop Down
Admin Group
Admin Group


Joined: 25 March 2016
Status: Offline
Points: 299
Post Options Post Options   Thanks (0) Thanks(0)   Quote agontarenko Quote  Post ReplyReply Direct Link To This Post Posted: 17 December 2024 at 4:47am
Hello,

Thanks for you solution.
How I can to reproduce this bug with our sample?

Regards,
Artem Gonarenko
Back to Top
DiZSl View Drop Down
Groupie
Groupie


Joined: 08 August 2020
Status: Offline
Points: 11
Post Options Post Options   Thanks (0) Thanks(0)   Quote DiZSl Quote  Post ReplyReply Direct Link To This Post Posted: Yesterday at 3:22am

I've modified your example by adding a "Button1" button. It deletes the last record and emulates clicking on that deleted record. After that GetCount method returns 1.

Back to Top
agontarenko View Drop Down
Admin Group
Admin Group


Joined: 25 March 2016
Status: Offline
Points: 299
Post Options Post Options   Thanks (0) Thanks(0)   Quote agontarenko Quote  Post ReplyReply Direct Link To This Post Posted: 21 hours 49 minutes ago at 8:14am
Hello,

I've change function with next code

void CXTPGridRows::RemoveAt(int nIndex)
{
    CXTPGridScreenRows* pScreenRows = GetScreenRows();
    if (pScreenRows)
    {
        for (int i = 0; i < pScreenRows->GetCount(); i++)
        {
            if (pScreenRows->GetAt(i) == m_arrRows.GetAt(nIndex))
            {
                pScreenRows->GetAt(i)->InternalRelease();
                pScreenRows->RemoveAt(i);
                break;
            }
        }
    }

    m_arrRows.GetAt(nIndex)->InternalRelease();
    m_arrRows.RemoveAt(nIndex);
}

Note in last versions CXTPReport was renamed to CXTPGrid.
The fix will be available in the next beta or final release.

Regards,
Artem Gontarenko
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.328 seconds.