Dynamically created TFrame causes Windows user object leak

68 Views Asked by At

In a C++ Builder 6 test project, I try to understand the relation between the TWinControl classes of the VCL and Windows user objects, because I'm hunting a leak of user objects in my original application where I use some levels of nested frames, created periodically at runtime, that causes my application to crash after some days.

In the test project I observe a strange behaviour. When I add a dynamically created TFrame object to a panel, the count of user objects increases by 2. If I remove a frame by deletion, the user object count is decreased by 1. If I add it again, the increment is 1. If I add more than 1 frame, the increment is 2 after exceeding the last maximum value of frames. This is the code to reproduce this:

MainForm.cpp

#include <vcl.h>
#pragma hdrstop

#include "MainFrm.h"

#pragma resource "*.dfm"
TMainForm *MainForm;

int UserObjectCount() {
    return GetGuiResources(GetCurrentProcess(), 1);
}

__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
{
}

void __fastcall TMainForm::AddButtonClick(TObject *Sender)
{
    String msg = "add: "+IntToStr(UserObjectCount())+",";
    (new TFrame(static_cast<TComponent*>(NULL)))->Parent = FramesPanel;
    trace(msg+IntToStr(UserObjectCount()));
}

void __fastcall TMainForm::RemoveButtonClick(TObject *Sender)
{
    if (!FramesPanel->ControlCount) return;
    String msg = "rem: "+IntToStr(UserObjectCount())+",";
    FramesPanel->Controls[0]->Free();
    trace(msg+IntToStr(UserObjectCount()));
}

void TMainForm::trace(const String& msg)
{
    TraceMemo->Lines->Add(msg);
}

It looks like a kind of caching. See the (grouped) excerpt of the trace (format action: before,after):

add: 28,30
rem: 30,29

add: 29,30
add: 30,32
rem: 32,31
rem: 31,30

add: 30,31
add: 31,32
add: 32,34
rem: 34,33
rem: 33,32
rem: 32,31

Another observation: If I use TPanel instead of TFrame, the behaviour is is trivial.

As to understand whether this is a Windows feature, I built another test application with Lazarus (Google didn't help). Here the user object count behaviour is unsurprising: increment and decrement compensate each other.

What is the explanation of this caching-like behaviour? How to get back to the initial count of user objects?

I'm sorry for pushing you back into the old times of BCB6.

0

There are 0 best solutions below